API documentation
Generate branded QR codes at scale over a simple REST API. All endpoints are versioned under /api/v1 and return JSON.
All requests require a Bearer token API key in the Authorization header. Create and manage keys in your dashboard under /dashboard/api-keys. Keys are shown once at creation — store them securely.
Authorization: Bearer qrop_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keys are created in your dashboard. API access requires an active API plan — see the pricing page for available plans.
Errors return a JSON body of the form { "error": "..." } with an appropriate HTTP status.
| 401 | Missing or invalid API key. |
| 402 | Credits exhausted or no active subscription. |
| 400 | Malformed request (e.g. batch outside 1–100 items). |
| 422 | Invalid data type, format, resolution, logo, or colours with insufficient contrast to stay scannable. |
| 429 | Rate limit exceeded — see the Retry-After header. |
Generate a single QR code. Consumes 1 credit.
| Field | Type | Description | |
|---|---|---|---|
| data | string | required | Content to encode (URL, text, vCard string, etc.). |
| type | string | required | One of: url, text, vcard, wifi, email, sms, phone, geo. |
| format | string | required | png, svg, or pdf. |
| resolution | number | required | Square size in px, 1–4096. |
| foregroundColor | string | optional | Hex colour, default #000000. |
| backgroundColor | string | optional | Hex colour, default #FFFFFF. |
| finderColor | string | optional | Hex colour for the finder (corner) patterns. |
| logoUrl | string | optional | Fetched server-side, max 2MB, PNG/JPEG only. Forces error correction to H. |
| logoDataUrl | string | optional | Inline base64 image (data:image/png;base64,... or jpeg), max 2MB, PNG/JPEG only — use this to upload a logo directly instead of hosting it at a fetchable URL. Takes precedence over logoUrl if both are sent. |
| errorCorrection | string | optional | L, M, Q, or H. Auto-upgraded to H when a logo is present. |
| moduleShape | string | optional | Shape of the QR modules (dots). |
| finderShape | string | optional | Shape of the finder patterns. |
| imageRoundness | number | optional | Corner roundness applied to an embedded logo. |
Request
{
"data": "https://example.com",
"type": "url",
"format": "png",
"resolution": 1024,
"foregroundColor": "#000000",
"backgroundColor": "#FFFFFF"
}Response 200
{
"id": "gen_a1b2c3",
"image": "data:image/png;base64,iVBORw0KG...",
"format": "png",
"resolution": 1024,
"creditsConsumed": 1
}Generate up to 100 QR codes in one request. Each item consumes 1 credit; credits are reserved for the full batch up front (no partial processing).
| Field | Type | Description | |
|---|---|---|---|
| items | array | required | 1–100 items, each with data and type (see /api/v1/generate). |
| format | string | required | png, svg, or pdf — applies to every item in the batch. |
| resolution | number | required | Square size in px, 1–4096 — applies to every item. |
| logoUrl | string | optional | Fetched once and applied to every item in the batch, max 2MB, PNG/JPEG only. Not supported with svg format. |
| logoDataUrl | string | optional | Inline base64 image, same logo applied to every item. Takes precedence over logoUrl if both are sent. |
The batch logo is per-request, not per-item — use separate batch calls (or /api/v1/generate) if items need different logos.
Request
{
"items": [
{ "data": "https://example.com/1", "type": "url" },
{ "data": "https://example.com/2", "type": "url" }
],
"format": "png",
"resolution": 512,
"logoUrl": "https://example.com/company-logo.png"
}Response 200
{
"results": [
{ "id": "gen_x1_0", "image": "data:image/png;base64,...", "success": true },
{ "id": "gen_x2_1", "image": "data:image/png;base64,...", "success": true }
],
"creditsConsumed": 2,
"failedCount": 0
}A batch with 0 or more than 100 items returns 400.
Return current period usage, remaining allocation, carried credits from previous periods, and your rate limits.
Response 200
{
"plan": "growth",
"currentPeriodStart": "2026-06-01T00:00:00Z",
"currentPeriodEnd": "2026-07-01T00:00:00Z",
"includedCredits": 50000,
"includedCreditsUsed": 12450,
"carriedCredits": 8200,
"overageCredits": 0,
"overageCostUsd": 0,
"rateLimit": { "requestsPerSecond": 25, "requestsPerMinute": 1000 }
}Rotate the calling API key. A new key is returned (shown once); the old key keeps working for a 24-hour grace period before it stops.
Response 200
{
"newKey": "qrop_live_yyyyyyyyyyyyyyyyyyyy",
"oldKeyValidUntil": "2026-06-25T10:00:00Z"
}