Developers
API reference
REST API v1 — manage QR codes and pull analytics with cue_live_* bearer keys.
The Cue API is a small REST API over JSON. Create a key in Dashboard → API; keys look like cue_live_a1b2c3... and are sent as a bearer token. Every request is made against your API base URL — https://grandiose-alpaca-668.convex.site — which is also shown alongside your keys in the dashboard. API access is included on Business and Enterprise plans.
curl https://grandiose-alpaca-668.convex.site/api/v1/qrcodes \
-H "Authorization: Bearer cue_live_a1b2c3d4e5f6"List QR codes
GET /api/v1/qrcodes returns your 100 most recent codes, newest first. createdAt is a Unix timestamp in milliseconds.
{
"data": [
{
"id": "jd7f2k9qmx04v5gz1nwe8c3ht",
"name": "Spring menu — window sticker",
"kind": "dynamic",
"status": "active",
"shortCode": "x7Kp2q",
"shortUrl": "https://scancue.co/r/x7Kp2q",
"destination": "https://example.com/menu/spring",
"scans": 1284,
"uniqueScans": 1102,
"createdAt": 1746177240000
}
]
}Create a QR code
POST /api/v1/qrcodes creates a dynamic code from a name and a destination URL, and returns a ready-to-encode short URL. Both fields are required, and the URL must be http(s). Codes created by API start with the default style — open them in the designer to restyle; the short URL never changes.
curl -X POST https://grandiose-alpaca-668.convex.site/api/v1/qrcodes \
-H "Authorization: Bearer cue_live_a1b2c3d4e5f6" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer campaign — poster A",
"url": "https://example.com/summer"
}'
{
"data": {
"id": "jd7f2k9qmx04v5gz1nwe8c3ht",
"shortCode": "x7Kp2q",
"shortUrl": "https://scancue.co/r/x7Kp2q"
}
}Update a destination
PATCH /api/v1/qrcodes/:id/destination repoints a dynamic code atomically and returns the new destination version. The change takes effect within seconds; printed codes keep working throughout.
curl -X PATCH https://grandiose-alpaca-668.convex.site/api/v1/qrcodes/jd7f2k9qmx04v5gz1nwe8c3ht/destination \
-H "Authorization: Bearer cue_live_a1b2c3d4e5f6" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/menu/summer" }'
{
"data": {
"id": "jd7f2k9qmx04v5gz1nwe8c3ht",
"destination": "https://example.com/menu/summer",
"version": 2
}
}Analytics
GET /api/v1/analytics returns daily scan aggregates. Scope to one code with ?qrcodeId= (omit it for the whole workspace) and set the window with ?from= and ?to= as YYYY-MM-DD dates — the default is the last 30 days.
{
"data": {
"totalScans": 403,
"uniqueScans": 352,
"days": [
{ "day": "2026-06-01", "total": 214, "uniques": 187 },
{ "day": "2026-06-02", "total": 189, "uniques": 165 }
]
}
}Errors and limits
Errors use conventional status codes with a plain JSON body: { "error": "name and url are required" }. You'll see 400 for invalid input, 401 for a missing or revoked key, 402 when a plan limit blocks the request, 404 for codes outside your workspace, and 429 once you exceed the rate limit of 120 requests per minute per key.