Pagination, errors & rate limits

The list envelope

Every list endpoint returns the same envelope:

{
  "object": "list",
  "data": [ /* … */ ],
  "has_more": true,
  "next_cursor": "b3JkZXJfY3Vyc29y"
}

Keyset pagination

Pass limit (1–200, default 50) and follow next_cursor:

curl "https://api.briefqr.com/v1/sessions?limit=100" 
  -H "Authorization: Bearer bqr_live_..."

# next page — pass the previous response's next_cursor
curl "https://api.briefqr.com/v1/sessions?limit=100&cursor=b3JkZXJfY3Vyc29y" 
  -H "Authorization: Bearer bqr_live_..."

When has_more is false, next_cursor is null and you have reached the end. Cursors are opaque — pass them back verbatim; a malformed cursor returns 400 (code: invalid_cursor). The official SDKs auto-follow the cursor for you.

The error envelope

Errors always look like this:

{
  "error": {
    "type": "validation_error",
    "code": "missing_param",
    "message": "ident is required",
    "param": "ident",
    "request_id": "req_0f2c…"
  }
}

type, message, and request_id are always present; code and param appear when applicable. request_id matches the X-Request-Id response header — include it when contacting support.

error.typeHTTPMeaning
bad_request400Malformed request (bad JSON, bad cursor)
authentication_error401Missing / invalid / expired key
insufficient_scope403Key lacks scope, mode, or subscription
not_found404No such resource
conflict409Uniqueness or idempotency conflict
validation_error422A field failed validation
rate_limited429Too many requests
api_error500Something went wrong on our side

Rate limits

Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. When you exceed the limit you get 429 with a Retry-After header (seconds). Back off and retry — the SDKs do this automatically.

Idempotent retries

Safely retry a create by sending an Idempotency-Key header:

curl -X POST https://api.briefqr.com/v1/operators 
  -H "Authorization: Bearer bqr_live_..." 
  -H "Idempotency-Key: 8f14e45f-cea1-4a3e-9c2b-1f0a2b3c4d5e" 
  -H "Content-Type: application/json" 
  -d '{ "ident": "NURSE01" }'

Replaying the same key with an identical body returns the original response (with Idempotent-Replayed: true). Reusing the key with a different body returns 409 (code: idempotency_key_reuse).