Quickstart — your first QR in 60 seconds
Sign up, grab an API key, run one HTTP call. We hand you back a PNG. No SDK install required to test.
Sign up + get an API key
Create a free account at qrstudio.agency/signup. You land in the dashboard. Open the Keys tab, click Create Key, give it a name. Copy the raw key — it's shown ONCE. It looks like smk_xxxxxxxxxx.
Generate your first QR (cURL)
Replace smk_your_key_here with your real key:
curl -X POST https://api.qrstudio.agency/api/v1/generate/ \
-H "X-Api-Key: smk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"data":"https://yourbrand.com","size_inches":4,"format":"png"}' \
--output qr.pngYou get a qr.png file in your current directory. Open it. Scan it. The phone camera shows https://yourbrand.com.
Same thing in Python
import requests
API_KEY = "smk_your_key_here"
res = requests.post(
"https://api.qrstudio.agency/api/v1/generate/",
headers={"X-Api-Key": API_KEY},
json={
"data": "https://yourbrand.com",
"size_inches": 4,
"format": "png",
"color": "black",
"background": "transparent",
},
)
res.raise_for_status()
with open("qr.png", "wb") as f:
f.write(res.content)All the request fields are documented at /docs/api/generate. Notable: format: "svg" for vector, logo_url or logo_file (multipart) for branded QRs, data_type for vCard / Wi-Fi / mailto / SMS / geo / dynamic.
Dynamic QRs — destination editable forever
Static QR codes encode the destination directly. Dynamic QRs encode https://q.qrstudio.agency/q/<id>/ and redirect at scan time. You can update the destination URL after the QR is printed:
# Create a dynamic QR — destination URL editable later
res = requests.post(
"https://api.qrstudio.agency/api/v1/generate/",
headers={"X-Api-Key": API_KEY},
json={
"data_type": "dynamic",
"payload": {"name": "Spring promo", "destination_url": "https://example.com/spring"},
"size_inches": 4,
},
)
short_id = res.headers["X-QR-Dynamic-Id"] # e.g. "abc12345"
public_url = res.headers["X-QR-Dynamic-Url"] # what's encoded in the QR
print(f"Created {short_id}, encoded: {public_url}")
# The QR encodes https://q.qrstudio.agency/q/abc12345/
# Update the destination at any time:
import json
patch = requests.patch(
f"https://api.qrstudio.agency/api/v1/dynamic/{short_id}/",
headers={"Authorization": "Bearer <jwt>"},
json={"destination_url": "https://example.com/SUMMER"},
)Each scan logs IP, user-agent, country (Cloudflare-detected), referer. Check GET /api/v1/dynamic/<id>/analytics/.
Bulk — 100s or 1000s in one call
# Generate 100 QR codes in one call, get back a ZIP + manifest.json
items = [
{"data": f"https://shop.example.com/order/{i}", "size_inches": 2}
for i in range(100)
]
res = requests.post(
"https://api.qrstudio.agency/api/v1/generate/bulk/",
headers={"X-Api-Key": API_KEY},
json={"items": items},
)
with open("qrs.zip", "wb") as f:
f.write(res.content)
# Unzip → 100 PNGs (qr-0001.png … qr-0100.png) + manifest.jsonAll-or-nothing: if one item is invalid, the whole batch returns 422 with per-index errors. The render cache makes re-runs of the same payload free. Plan caps: Starter 50/batch, Pro 1000, Agency 5000.
That's it — what's next?
- Read the full API reference for every parameter.
- Install the
qrstudioPython SDK or@qrstudio/sdknpm package for typed clients with retry. - Generating for a print campaign? Check /use-cases/print-shop for the bulk workflow.
- Hit the free tier ceiling? $7/mo Starter unlocks 500 generations + 10 dynamics + bulk.
Stuck? Email hello@qrstudio.agency — typically < 4h response.
Sign up