Skip to main content

API Reference

QRlumo exposes a REST API for creating and managing QR codes, reading scan analytics, and automating workflows. The API is designed for teams who want to embed QR code management into their own systems — CRMs, ERPs, print pipelines, or marketing automation.

Base URL​

https://api.qrlumo.com/v1

Authentication​

All requests require a Bearer token in the Authorization header. Generate API keys under Workspace → Settings → API Keys.

curl https://api.qrlumo.com/v1/workspaces \
-H "Authorization: Bearer qrl_live_..."

API keys are scoped to a workspace. Keys with read scope can only fetch data; write scope allows mutations.


QR Codes​

Create a QR code​

POST /workspaces/{workspaceId}/qrcodes

Request body

{
"name": "spring_packaging",
"type": "dynamic",
"content": {
"url": "https://brand.com/spring-offer"
},
"projectId": "proj_abc123"
}
FieldTypeRequiredDescription
namestring✓Human-readable label
typestatic | dynamic✓Code type
content.urlstring✓Destination URL
projectIdstringAssign to a project folder

Response

{
"id": "qr_xyz789",
"name": "spring_packaging",
"type": "dynamic",
"shortUrl": "https://qrlu.mo/r/abc",
"content": { "url": "https://brand.com/spring-offer" },
"scans": 0,
"createdAt": "2026-06-10T09:00:00Z"
}

Update destination​

PATCH /workspaces/{workspaceId}/qrcodes/{qrcodeId}
{
"content": {
"url": "https://brand.com/summer-campaign"
}
}

Only dynamic codes support destination updates. Static codes return 400.


List QR codes​

GET /workspaces/{workspaceId}/qrcodes?page=1&limit=50&projectId=proj_abc

Delete a QR code​

DELETE /workspaces/{workspaceId}/qrcodes/{qrcodeId}

Deleting a dynamic code makes its short URL return 404. Deleting a static code has no effect on already-printed patterns (they encode the URL directly).


Scan Analytics​

Get scan stats​

GET /workspaces/{workspaceId}/qrcodes/{qrcodeId}/stats?from=2026-06-01&to=2026-06-30

Response

{
"total": 2847,
"unique": 1923,
"byDay": [
{ "date": "2026-06-01", "scans": 142, "unique": 98 },
...
],
"byCountry": [
{ "country": "CN", "scans": 1204 },
{ "country": "US", "scans": 441 }
],
"byDevice": [
{ "device": "iOS", "scans": 1589 },
{ "device": "Android", "scans": 891 }
]
}

Raw scan events​

GET /workspaces/{workspaceId}/qrcodes/{qrcodeId}/events?cursor=&limit=100

Returns paginated raw scan events. Available on Team and Business plans.


Workspaces​

List workspaces​

GET /workspaces

Get workspace​

GET /workspaces/{workspaceId}

Rate limits​

PlanRequests / minRequests / month
Free10—
Pro60—
Team12020,000
Business300200,000

Exceeding the rate limit returns 429 Too Many Requests.


Error format​

All errors follow a consistent JSON shape:

{
"error": {
"code": "qr_not_found",
"message": "QR code qr_xyz789 does not exist in this workspace.",
"status": 404
}
}

Client libraries​

Official SDKs are in progress. In the meantime, the REST API works with any HTTP client.

// TypeScript — no SDK needed
const res = await fetch(
`https://api.qrlumo.com/v1/workspaces/${workspaceId}/qrcodes`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'my_code',
type: 'dynamic',
content: { url: 'https://example.com' },
}),
}
);
const code = await res.json();

Planned SDK languages: TypeScript/Node.js · Python · Go · PHP

Join the SDK waitlist to be notified when your language is ready.

OpenAPI spec​

The full OpenAPI 3.0 spec is available at:

https://api.qrlumo.com/openapi.json

Use it to generate a typed client in any language with openapi-generator or oapi-codegen.