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
namestringHuman-readable label
typestatic | dynamicCode type
content.urlstringDestination 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.