Public API
QR Mosaic API
Generate branded mosaic QR codes from any URL. Bearer-key auth. Plans from free.
Authentication
All requests require an Authorization header with a Bearer token. Generate a key from your dashboard.
Authorization: Bearer qm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
POST /v1/qr
Generate a QR code. Returns image/svg+xml by default, or image/png when options.format is "png".
Request body
{
"url": "https://stripe.com",
"style": "mosaic",
"options": {
"size": 800,
"format": "svg"
}
}
curl
curl https://qr-mosaic.ddev.site/v1/qr \
-X POST \
-H "Authorization: Bearer $QR_MOSAIC_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com"}' \
--output stripe.svg
Node (fetch)
const res = await fetch("https://qr-mosaic.ddev.site/v1/qr", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.QR_MOSAIC_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://stripe.com" }),
});
const svg = await res.text();
Python (requests)
import os, requests
r = requests.post(
"https://qr-mosaic.ddev.site/v1/qr",
headers={"Authorization": f"Bearer {os.environ['QR_MOSAIC_KEY']}"},
json={"url": "https://stripe.com"},
)
r.raise_for_status()
open("stripe.svg", "wb").write(r.content)
PHP (Guzzle)
$client = new \GuzzleHttp\Client();
$res = $client->post('https://qr-mosaic.ddev.site/v1/qr', [
'headers' => ['Authorization' => 'Bearer ' . getenv('QR_MOSAIC_KEY')],
'json' => ['url' => 'https://stripe.com'],
]);
file_put_contents('stripe.svg', $res->getBody());
Response headers
X-Domain: stripe.com
X-Palette-Dominant: #533afd
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 2026-06-01T00:00:00Z
GET /v1/usage
Check your remaining quota for the current month.
curl https://qr-mosaic.ddev.site/v1/usage \
-H "Authorization: Bearer $QR_MOSAIC_KEY"
{
"usage": 13,
"limit": 100,
"remaining": 87,
"reset_at": "2026-06-01T00:00:00Z",
"plan": { "code": "free", "name": "Free" }
}
Error codes
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_authorization | No Bearer header. |
| 401 | invalid_key | Key not recognized. |
| 403 | revoked_key | Key has been revoked. |
| 422 | logo_unavailable | Couldn't fetch a logo for that URL. |
| 429 | quota_exceeded | Monthly limit reached. X-RateLimit-Reset shows when it refills. |
| 503 | render_unavailable | Render service temporarily down. |
OpenAPI spec
Machine-readable description at /v1/openapi.json. Drop it into Postman, Stoplight, or your favourite client generator.