BricqsBricqs
Documentation

Troubleshooting

Problems organized by what you see, not by feature. Every error response carries a request_id; include it when you contact support. Branch your handling on error.type first and error.code when present (see the Error Reference).

Authentication

401 AUTH_UNAUTHENTICATED, or the browser SDK stops working after a few minutes

Likely cause: Participant tokens are short-lived (default 5 minutes, clamped to 1–60). The token expired and nothing re-minted it.

Fix: Provide a getToken callback to the SDK that fetches a fresh token from your server. The SDK caches it and calls your callback again on a 401. Do not try to extend token lifetime past 60 minutes; refresh instead. See Authentication.

401 AUTH_API_KEY_INVALID

Likely cause: The API key is malformed, revoked, or from the wrong environment (test vs live).

Fix: Use a current key that starts with bq_live_ or bq_test_ followed by 32 hex characters. “admin” is a scope, not a key prefix. Keys are server-only.

403 AUTH_FORBIDDEN

Likely cause: The caller is authenticated but lacks the scope, or a participant token is touching another participant’s data. Minting participant tokens requires an admin-scoped key.

Fix: Check the key’s scopes (events:write, gamify:read, gamify:write, admin) and confirm the participant token’s subject matches the participant you are reading or writing.

The browser SDK throws at construction when given an API key

Likely cause: You passed a server key (bq_live_ / bq_test_) to the browser client.

Fix: The browser client only accepts a participant token. Mint tokens on your server with @bricqs/sdk-server and hand the browser only the participant token.

Events & idempotency

Points or rewards granted twice

Likely cause: A request was retried without an idempotency key, so it was processed as two distinct events.

Fix: Send an Idempotency-Key header on every write. A retry with the same key returns the original result with status: "duplicate" and the same event_id, and does not re-grant.

IDEMPOTENCY_KEY_INVALID

Likely cause: The key is missing, too long, or uses disallowed characters. Allowed: [A-Za-z0-9_-:.], max 255.

Fix: Use a stable, URL-safe key per logical action (for example purchase:order_123).

IDEMPOTENCY_KEY_MISMATCH

Likely cause: The Idempotency-Key header and a body idempotency_key disagree.

Fix: Send the key in one place (the header is canonical), or make both identical.

An event succeeded but did not advance a challenge

Likely cause: Event-driven challenges must be global; engagement-scoped challenges do not advance from public API events.

Fix: Make the challenge global, and read it via the by-ids progress path rather than the by-engagement read. See Known Limitations.

Rate limits

429 with a RATE_LIMIT_* code

Likely cause: You crossed a per-IP, per-tenant, per-key, or per-participant limit.

Fix: Respect the Retry-After header first, then back off exponentially with jitter. Read the specific RATE_LIMIT_* code to know which limit you hit. Batching is not a bypass: batched events count individually. See Rate Limits & Quotas.

Live updates

The UI stopped updating live and never recovered

Likely cause: The stream failed terminally (a 403, or retries exhausted). There is no automatic polling fallback.

Fix: Handle the stream’s onError by switching to periodic re-reads of the data hooks. See Live Updates.

403 STREAM_PARTICIPANT_MISMATCH or STREAM_SCOPE_MISSING

Likely cause: The stream token is for a different participant than the path, or it lacks the read:state scope.

Fix: Open the stream with the same participant’s token, and ensure the token carries read:state (the mint default includes it). These are terminal — the stream will not retry them.

Progression reads look a few seconds behind

Likely cause: General leaderboard reads are served from a cache and can be up to ~30s stale.

Fix: This is expected. For a participant’s own live progression, use streaming; do not expect real-time general leaderboards.

Things that will not happen (by design, today)

  • Automatic points expiry does not run yet. Do not rely on it in launch-critical logic.
  • Bricqs sends no participant notifications (email/push/in-app). Webhooks are the trigger; you send the message.
  • There is no participant data export endpoint yet (erasure exists). Assemble access bundles yourself.
  • Webhooks are not ordered and can be redacted on replay. Process idempotently and re-read on replay.

The full list is on Known Limitations & Guarantees.

Next steps