QRQR Code Agency

QR Code Agency Developer Docs

Build with QR Code Agency. Generate premium static and dynamic QR codes over a paid HTTP API.

The print-once, edit-forever QR platform. Render static and dynamic QR codes, deliver them as PNG or SVG, swap their destination after print, and watch the scans come in. One JSON endpoint, one API key, one bill.

What you can build

How it works

sequenceDiagram
    participant Client
    participant API as api.qrstudio.agency
    participant Cache as Render cache
    participant Engine as Render engine
    participant DB as Postgres

    Client->>API: POST /api/v1/generate/<br/>X-Api-Key: smk_...
    API->>API: Authenticate, resolve plan, check quota
    API->>Cache: Look up by content hash
    alt Cache hit
        Cache-->>API: PNG bytes (~0 ms)
    else Cache miss
        API->>Engine: Render
        Engine-->>API: PNG bytes
        API->>Cache: Store (24 h TTL)
    end
    API->>DB: Atomic quota increment + audit row
    API-->>Client: 200 OK + image bytes<br/>X-QR-Cache, X-QR-Quota-Remaining

For dynamic QRs the same call also creates a DynamicQr row and encodes https://q.qrstudio.agency/q/<short_id>/. Every scan goes through that short URL, gets logged with country and device, and is 302 redirected to the live destination.

A 30-second example

curl -X POST https://api.qrstudio.agency/api/v1/generate/ \
  -H "X-Api-Key: smk_yOuRkEyHeRe" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "https://yourbusiness.com",
    "size_inches": 4,
    "color": "black",
    "background": "white"
  }' \
  --output qr.png
import requests

r = requests.post(
    "https://api.qrstudio.agency/api/v1/generate/",
    headers={"X-Api-Key": "smk_yOuRkEyHeRe"},
    json={
        "data": "https://yourbusiness.com",
        "size_inches": 4,
        "color": "black",
        "background": "white",
    },
    timeout=30,
)
r.raise_for_status()
open("qr.png", "wb").write(r.content)
const r = await fetch("https://api.qrstudio.agency/api/v1/generate/", {
  method: "POST",
  headers: {
    "X-Api-Key": "smk_yOuRkEyHeRe",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    data: "https://yourbusiness.com",
    size_inches: 4,
    color: "black",
    background: "white",
  }),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const blob = await r.blob();
import fs from "node:fs";

const r = await fetch("https://api.qrstudio.agency/api/v1/generate/", {
  method: "POST",
  headers: {
    "X-Api-Key": "smk_yOuRkEyHeRe",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ data: "https://yourbusiness.com", size_inches: 4 }),
});
fs.writeFileSync("qr.png", Buffer.from(await r.arrayBuffer()));
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-Api-Key", "smk_yOuRkEyHeRe");

var payload = new {
    data = "https://yourbusiness.com",
    size_inches = 4,
    color = "black",
};
var resp = await http.PostAsJsonAsync(
    "https://api.qrstudio.agency/api/v1/generate/", payload);
resp.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync("qr.png", await resp.Content.ReadAsByteArrayAsync());
body := strings.NewReader(`{"data":"https://yourbusiness.com","size_inches":4}`)
req, _ := http.NewRequest("POST", "https://api.qrstudio.agency/api/v1/generate/", body)
req.Header.Set("X-Api-Key", "smk_yOuRkEyHeRe")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer resp.Body.Close()
out, _ := os.Create("qr.png")
io.Copy(out, resp.Body)

The response body is the binary image. Stream it to disk, push it to S3, or pipe it straight into an <img> tag.

Pick your path

Production endpoints

ServiceURLPurpose
APIhttps://api.qrstudio.agencyAll /api/v1/* endpoints
Scan redirecthttps://q.qrstudio.agency/q/<short_id>/Public dynamic QR target
Dashboardhttps://qrstudio.agencyWeb UI for keys, billing, analytics
Statushttps://status.qrstudio.agencyLive uptime and incidents
Docshttps://qrstudio.agency/docs/This site

All traffic is HTTPS only. HTTP is allowed on localhost for development.

What is QR Code Agency built on

  • Django 5 + Django REST Framework for the API surface
  • Pillow + qrcode for the render pipeline (rounded modules, gradients, eye styling, frame decorations, logo composition)
  • Postgres for keys, plans, dynamic QRs, scan audit, webhook deliveries
  • Redis for the 24 hour content-addressed render cache (LocMem in dev)
  • Stripe for subscriptions, credit packs, and metered overage billing

You do not need to know any of this to ship. Read the quickstart and the API reference, pick a plan, and start.

Stuck on something?

Email support@qrstudio.agency with your X-QR-Plan header value and the request payload that misbehaved. We answer within one business day on Starter, four hours on Pro, one hour on Agency, and 15 minutes on Enterprise.