Skip to content
v1 · Pro

API reference

Create and manage dynamic QR codes and short links. Available on the Pro plan.

Base URL https://ctrlshiftqr.com/api/v1 · OpenAPI 3.1 spec

Authentication

Create a key in Settings → API keys (Pro plan) and send it as a bearer token. Keys are shown once; store them securely and never in client-side code. Keys stop working if the account leaves the Pro plan.

curl https://ctrlshiftqr.com/api/v1/qr-codes \
  -H "Authorization: Bearer csqr_your_key"

Errors & rate limits

Errors use HTTP status codes with a JSON body. Field validation errors include details.fieldErrors. Each key may make 60 requests per minute; responses carry X-RateLimit-Limit and X-RateLimit-Remaining, and 429 responses include Retry-After.

{ "error": { "code": "limit_reached", "message": "You've reached the plan limit…" } }

Pagination

List endpoints return { data, nextCursor }. Pass ?cursor=<nextCursor> to get the next page (newest first, up to 100 per page).

get/qr-codes

List QR codes

Query parameterTypeDescription
limitinteger (default 25)
cursorstring`nextCursor` from the previous page.
qstringSearch by name, destination or slug.
curl -X GET https://ctrlshiftqr.com/api/v1/qr-codes \
  -H "Authorization: Bearer csqr_your_key"

Responses: 200, 400, 401, 403, 429

post/qr-codes

Create a QR code

`type` defaults to `URL` (dynamic: the image encodes a CtrlShiftQR redirect, so `destination` can change later). Other types are static and take a `payload`.

curl -X POST https://ctrlshiftqr.com/api/v1/qr-codes \
  -H "Authorization: Bearer csqr_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"Spring menu","destination":"https://example.com/menu","style":{"fgColor":"#111111","dotStyle":"rounded"}}'

Responses: 201, 400, 401, 403, 429

get/qr-codes/{id}

Get a QR code

curl -X GET https://ctrlshiftqr.com/api/v1/qr-codes/ID \
  -H "Authorization: Bearer csqr_your_key"

Responses: 200, 400, 401, 403, 429

patch/qr-codes/{id}

Update a QR code

Changing `destination` never changes a dynamic code's image.

curl -X PATCH https://ctrlshiftqr.com/api/v1/qr-codes/ID \
  -H "Authorization: Bearer csqr_your_key" \
  -H "Content-Type: application/json" \
  -d '{"destination":"https://example.com/summer-menu"}'

Responses: 200, 400, 401, 403, 429

delete/qr-codes/{id}

Delete a QR code

curl -X DELETE https://ctrlshiftqr.com/api/v1/qr-codes/ID \
  -H "Authorization: Bearer csqr_your_key"

Responses: 204, 400, 401, 403, 429

get/qr-codes/{id}/image

Render the QR image

Query parameterTypeDescription
formatpng | svg (default png)
sizeinteger (default 512)
curl -X GET https://ctrlshiftqr.com/api/v1/qr-codes/ID/image \
  -H "Authorization: Bearer csqr_your_key"

Responses: 200, 400, 401, 403, 429

post/links

Create a short link

curl -X POST https://ctrlshiftqr.com/api/v1/links \
  -H "Authorization: Bearer csqr_your_key" \
  -H "Content-Type: application/json" \
  -d '{"destination":"https://example.com/launch","slug":"launch"}'

Responses: 201, 400, 401, 403, 409, 429

get/analytics

Scan analytics

Query parameterTypeDescription
range7d | 30d | 90d | 365d (default 30d)
tzstring (default UTC)IANA time zone for day buckets.
qrstringLimit to one QR code id.
linkstringLimit to one short link id.
curl -X GET https://ctrlshiftqr.com/api/v1/analytics \
  -H "Authorization: Bearer csqr_your_key"

Responses: 200, 400, 401, 403, 429

get/me

Current plan, limits and usage

curl -X GET https://ctrlshiftqr.com/api/v1/me \
  -H "Authorization: Bearer csqr_your_key"

Responses: 200, 400, 401, 403, 429