QR codes API & MCP
Generate QR images, create editable (dynamic) codes you can repoint anytime, and read scan stats — over a REST API or an MCP server for AI agents. Free, with a key tied to your account.
Generate a QR image
Tweak the controls — the preview updates live, the code stays in sync, and you can run it against the real API.
curl -X POST https://openqr.uk/v1/qr \
-H "Authorization: Bearer oqr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data":"https://openqr.uk","format":"png","size":512,"dark":"#232E3A","light":"#FFFFFF"}' \
--output qr.pngLive preview — exactly what the API returns.
GET/v1/qr
Render a QR image straight from query params. Returns the raw image (image/svg+xml or image/png) — not JSON.
# SVG (default), 512px, your saved theme's colours:
curl "https://openqr.uk/v1/qr?data=https://openqr.uk&format=svg&size=512&margin=4&theme=Brand" \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -o qr.svg
# PNG with explicit colours:
curl "https://openqr.uk/v1/qr?data=https://openqr.uk&format=png&dark=%23232E3A&light=%23FFFFFF" \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -o qr.pngPOST/v1/qr
Same renderer from a JSON body — handy for longer payloads. Returns the raw image.
curl -X POST https://openqr.uk/v1/qr \
-H "Authorization: Bearer oqr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data":"https://openqr.uk","format":"png","size":1024,"margin":4,"dark":"#232E3A","light":"#FFFFFF"}' \
-o qr.pngdataText or URL to encode. Required, max 2000 characters.format"svg" (default) or "png".sizePixel size, 64–2048. Default 512.marginQuiet-zone modules, 0–16. Default 4 (or the theme's margin).dark / lightForeground / background colour as hex (e.g. #232E3A). Override the theme.themeA saved theme id or name — sets the image colours and margin. Explicit dark/light/margin win.Account
GET /v1/me returns the account that owns your key — a cheap way to verify a key works and read back the connected identity (e.g. for a Zapier connection label).
GET/v1/me
Return the account (id, email, name, created_at) that owns the calling key.
curl https://openqr.uk/v1/me -H "Authorization: Bearer oqr_YOUR_API_KEY"
# → { "id": "...", "email": "you@example.com", "name": "You", "created_at": "2026-01-01T00:00:00.000Z" }Authentication
Every request needs your API key as a Bearer token. Create, name and rotate keys in your dashboard.
Authorization: Bearer oqr_YOUR_API_KEYDynamic codes
A dynamic code is a short URL on oqr.to you can repoint forever — the printed QR never changes. Create one, then update its destination or read its scans.
POST/v1/dynamic
Create a dynamic code.
curl -X POST https://openqr.uk/v1/dynamic \
-H "Authorization: Bearer oqr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"destination":"https://example.com","label":"Spring flyer"}'
# → { "id": "...", "slug": "Ab3xKp", "short_url": "https://oqr.to/Ab3xKp", ... }GET/v1/dynamic
List your dynamic codes (newest first, ?limit= up to 500).
curl https://openqr.uk/v1/dynamic \
-H "Authorization: Bearer oqr_YOUR_API_KEY"
# → { "codes": [ { "id": "...", "slug": "Ab3xKp", "short_url": "...", "destination": "...", "label": "...", "status": "active", "created_at": "..." } ] }PATCH/v1/dynamic/{id}
Edit any field the dashboard can — send only what you want to change.
# repoint (printed QR keeps working), rename, set a custom short link, tag, and file it:
curl -X PATCH https://openqr.uk/v1/dynamic/{id} \
-H "Authorization: Bearer oqr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "https://example.com/new",
"label": "Summer promo",
"slug": "summer",
"tags": ["promo", "2026"],
"folder_id": "FOLDER_ID"
}'
# slug → oqr.to/summer (3–48 letters, numbers or hyphens). folder_id: null to un-file.POST/v1/dynamic/bulk
Create up to 200 dynamic codes in one request.
curl -X POST https://openqr.uk/v1/dynamic/bulk \
-H "Authorization: Bearer oqr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"codes":[
{"destination":"https://example.com/a","label":"A"},
{"destination":"https://example.com/b"}
]}'
# → { "created": [ { "id": "...", "slug": "...", "short_url": "...", ... } ] }GET/v1/dynamic/{id}/scans
Scan summary + full analytics (daily series, country/device/referrer; ?days= up to 365).
curl "https://openqr.uk/v1/dynamic/{id}/scans?days=30" \
-H "Authorization: Bearer oqr_YOUR_API_KEY"
# → {
# "scans": { "total": 42, "last7": 9, "topCountry": "GB", "topDevice": "mobile" },
# "analytics": {
# "days_window": 30, "total": 42, "window_total": 31,
# "daily": [ { "day": "2026-06-01", "n": 3 }, ... ],
# "by_country": [ { "value": "GB", "n": 20 }, ... ],
# "by_device": [ { "value": "mobile", "n": 28 }, ... ],
# "by_referrer":[ { "value": "instagram.com", "n": 12 }, ... ]
# }
# }DELETE/v1/dynamic/{id}
Delete a code.
curl -X DELETE https://openqr.uk/v1/dynamic/{id} \
-H "Authorization: Bearer oqr_YOUR_API_KEY"Folders
Organise codes into folders. Move a code with folder_id on PATCH /v1/dynamic/{id}. Deleting a folder un-files its codes — it never deletes them.
GET/v1/folders
List your folders.
curl https://openqr.uk/v1/folders -H "Authorization: Bearer oqr_YOUR_API_KEY"
# → { "folders": [ { "id": "...", "name": "Campaign" } ] }POST/v1/folders
Create a folder.
curl -X POST https://openqr.uk/v1/folders \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Campaign"}' # → { "id": "...", "name": "Campaign" }PATCH/v1/folders/{id}
Rename a folder.
curl -X PATCH https://openqr.uk/v1/folders/{id} \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Q3 Campaign"}'DELETE/v1/folders/{id}
Delete a folder (codes are un-filed).
curl -X DELETE https://openqr.uk/v1/folders/{id} \
-H "Authorization: Bearer oqr_YOUR_API_KEY"Themes
A theme is a saved style (colours, dot/corner shapes, logo, gradient, frame). Save one in the dashboard, then apply it anywhere by passing theme (its id or name) when creating, bulk-creating or editing a code. On /v1/qr a theme sets the image colours/margin; on dynamic codes the full style is stored for every download.
GET/v1/themes
List your saved themes (id, name, style).
curl https://openqr.uk/v1/themes -H "Authorization: Bearer oqr_YOUR_API_KEY"
# → { "themes": [ { "id": "...", "name": "Brand", "style": { ... } } ] }POST/v1/themes
Save a reusable theme.
curl -X POST https://openqr.uk/v1/themes \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Brand","style":{"fgColor":"#07B1B0","bgColor":"#FFFFFF","dotType":"rounded"}}'—apply a theme
Pass theme (id or name) to any create/edit endpoint.
# new code styled with a theme:
curl -X POST https://openqr.uk/v1/dynamic \
-H "Authorization: Bearer oqr_YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"destination":"https://example.com","theme":"Brand"}'
# a QR image in the theme's colours:
curl "https://openqr.uk/v1/qr?data=https://example.com&theme=Brand&format=svg" \
-H "Authorization: Bearer oqr_YOUR_API_KEY"DELETE/v1/themes/{id}
Delete a theme (styled codes keep their look).
curl -X DELETE https://openqr.uk/v1/themes/{id} \
-H "Authorization: Bearer oqr_YOUR_API_KEY"Rate limits
Creating dynamic codes is capped at 20 per hour on a rolling window (this covers POST /v1/dynamic and each code in a POST /v1/dynamic/bulk batch). Reads, edits, deletes and QR-image rendering are not counted. Every create response carries your current budget in headers:
X-RateLimit-LimitMax creations per rolling hour (20).X-RateLimit-RemainingCreations left in the current window.X-RateLimit-ResetUnix seconds (UTC) when a slot frees up.When you exceed the window the API returns 429 Too Many Requests with a Retry-After header (seconds to wait) alongside the same X-RateLimit-* headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1751299200
Retry-After: 1843
{ "error": "Too many codes created recently. Try again later." }Errors
Every error response is JSON with a single error string and the matching HTTP status. Successful calls return 2xx (codes are created with 201); image endpoints return the raw image bytes rather than JSON.
{ "error": "Human-readable description of what went wrong." }400 Bad RequestA field is missing or invalid — e.g. a disallowed or private destination, a bad slug, malformed JSON, or `data` over 2000 characters.401 UnauthorizedMissing, invalid or revoked Bearer key. Create or rotate keys in your dashboard.404 Not FoundThe code, folder or theme doesn't exist, or isn't owned by your key.429 Too Many RequestsDynamic-code creation rate limit hit — see the Rate limits section and Retry-After.500 Internal Server ErrorUnexpected server-side failure. Safe to retry with backoff.MCP server
Read the full MCP guide → — tools, supported clients, use cases and worked examples.
Point any MCP-capable agent (Claude, Cursor, …) at https://openqr.uk/mcp with your key. Anything you can do in the dashboard, an agent can do here. Tools: generate_qr, create_dynamic_qr, update_dynamic_qr (destination, label, slug, tags, folder, theme), get_scans, list_dynamic_qr, delete_dynamic_qr, bulk_create_dynamic_qr, list_folders, create_folder, delete_folder, list_themes, create_theme, delete_theme.
Connect your MCP client
Pick your client below, paste the config, and swap in your oqr_ key from this page (the key bar at the top). Endpoint is https://openqr.uk/mcp — Streamable HTTP, key in the Authorization header.
// claude_desktop_config.json — Settings → Developer → Edit Config.
// Claude Desktop speaks stdio, so bridge to the remote server with mcp-remote.
{
"mcpServers": {
"openqr": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://openqr.uk/mcp",
"--header", "Authorization: Bearer oqr_YOUR_API_KEY"
]
}
}
}
// Restart Claude Desktop, then ask it to "generate a QR code for openqr.uk".Every tool — including generate_qr — needs a key, since codes are tied to your account. Create a free one in seconds at the top of this page.
Keep learning
- OpenAPI 3.1 spec — import the whole API into Postman, Insomnia, Cursor or an AI agent in one step.
- Postman collection — ready-made requests for every endpoint; set your
apiKeyvariable and send. - QR code guides — Wi-Fi, logos, print/vector, dynamic vs static, and more.
- Your dashboard — manage codes, keys, scans.
- Free generator — no signup, no watermark, in your browser.
Free with generous rate limits. Keys are tied to your account so we can keep abuse off the network — the tool itself stays free and no-signup.
Stay on top of the API
Get the changelog and new endpoints in your inbox — occasional, developer-focused, no spam.
Double opt-in — we'll email you to confirm. No spam, unsubscribe anytime. See our privacy policy.