Errors
Every error response uses one envelope with a stable type (the category to branch on) and, where the platform can be specific, a stable code. The machine-readable catalog is published at https://api.bricqs.co/.well-known/errors.json (envelope version 1); this page mirrors it for humans.
The envelope
{
"error": {
"type": "insufficient_balance", // stable category (always present)
"code": "POINTS_INSUFFICIENT", // stable specific code (when known)
"message": "Participant has 50 points; need 100.",
"param": "amount", // offending field, when applicable
"details": { "available": 50, "requested": 100 },
"request_id": "req_abc123" // quote this to support
}
}Handling rules. Branch on
type first and treat unknown code values as their type (new codes may be added at any time; existing ones are never renamed). Some responses from older code paths carry only a generic status-derived type without a specific code; your handler must not require code. Always log request_id.The 20 types
| type | Meaning | Handling |
|---|---|---|
validation_error | Request body failed schema validation (Pydantic or domain rule). | Fix the payload; do not retry as-is. |
invalid_request | Request was malformed or semantically invalid. | Fix the request; do not retry as-is. |
not_found | The referenced resource does not exist (in this tenant). | Check ids and environment (test vs live). |
already_exists | A resource with the same natural key already exists. | Treat as success for idempotent creates. |
conflict | Request conflicts with current resource state. | Re-read state; retry if the conflict is transient. |
idempotency_conflict | Idempotency key was reused with a different request payload. | Never reuse a key with changed content; mint a new key. |
precondition_failed | A required precondition (state, version) was not met. | Re-read state and re-evaluate. |
unauthenticated | No valid credentials were supplied. | Fix the credential; for participant JWTs, re-mint. |
invalid_api_key | The API key is malformed, unknown, or revoked. | Fix configuration; do not retry. |
forbidden | Authenticated, but not permitted to perform this action. | Usually a missing scope or a participant-pin mismatch; fix, never retry. |
invalid_configuration | Tenant/resource configuration forbids this operation. | Adjust configuration in the dashboard. |
insufficient_balance | Participant lacks the points balance required. | Surface to the user; not retryable. |
inventory_exhausted | No reward codes/inventory remain to fulfil the request. | Surface sold-out UX; not retryable. |
rate_limited | Too many requests. | Respect Retry-After, then backoff with jitter. |
expired | The referenced resource (token, reward, contest) has expired. | Re-mint tokens; otherwise surface expiry. |
disqualified | Participant is disqualified from this contest/action. | Surface to the user. |
plan_limit_exceeded | The tenant's plan limit/quota/feature gate blocks this request. | See /docs/limits; upgrade or reduce usage. |
internal_error | Unexpected server error. | Safe to retry idempotent requests with backoff; log request_id. |
service_unavailable | A dependency is temporarily unavailable. | Retry with backoff. |
timeout | A downstream operation timed out. | Retry with backoff. |
The 40 codes
Auth
AUTH_UNAUTHENTICATED | No valid credentials were supplied for a protected endpoint. |
AUTH_API_KEY_INVALID | API key is invalid or revoked. |
AUTH_FORBIDDEN | Authenticated, but not permitted: missing scope (events:write / gamify:read / gamify:write / admin) or a participant JWT touching another participant. |
Validation (12 codes)
VALIDATION_REQUIRED | Required field missing. |
VALIDATION_INVALID_TYPE | Field has the wrong type. |
VALIDATION_INVALID_VALUE | Field value rejected. |
VALIDATION_INVALID_ENUM | Value not in the allowed set. |
VALIDATION_INVALID_JSON | Body is not valid JSON. |
VALIDATION_MIN_LENGTH / VALIDATION_MAX_LENGTH | String length out of bounds. |
VALIDATION_MIN_VALUE / VALIDATION_MAX_VALUE | Number out of bounds. |
VALIDATION_PATTERN | String failed its regex/format. |
VALIDATION_NOT_MULTIPLE_OF | Number not a multiple of the required step. |
VALIDATION_UNKNOWN_FIELD | Unrecognised field in the payload. |
Idempotency
IDEMPOTENCY_KEY_INVALID | Idempotency-Key is missing, too long, or has invalid characters (allowed: [A-Za-z0-9_-:.], max 255). |
IDEMPOTENCY_KEY_MISMATCH | Idempotency-Key header and body idempotency_key differ. |
Rate limiting (7 codes)
RATE_LIMIT_API_KEY_EXCEEDED | Per-API-key request rate limit exceeded. |
RATE_LIMIT_TENANT_EXCEEDED / RATE_LIMIT_INGEST_TENANT_EXCEEDED | Per-tenant limit exceeded (general / ingestion). |
RATE_LIMIT_IP_EXCEEDED / RATE_LIMIT_INGEST_IP_EXCEEDED | Per-IP limit exceeded (general / ingestion). |
RATE_LIMIT_PARTICIPANT_EXCEEDED | Per-participant event limit exceeded (default 100/min). |
RATE_LIMIT_BURST_EXCEEDED | Short-window burst limit exceeded (100/second on ingestion). |
Plan limits
PLAN_RESOURCE_LIMIT | Plan's maximum count for this resource reached. |
PLAN_FEATURE_DISABLED | Feature not enabled on the tenant's plan. |
PLAN_MAU_EXCEEDED | Monthly active participant limit exceeded. |
PLAN_API_QUOTA_EXCEEDED | Plan's API request quota for the period exhausted. |
Domain
POINTS_INSUFFICIENT | Participant's available points are below the requested spend. |
REWARD_INVENTORY_EXHAUSTED | No unclaimed reward codes remain for this reward. |
TIER_ASSIGN_CONFLICT | Tier assignment lost a race to a concurrent modification; safe to retry. |
TIER_CRITERIA_INVALID | Tier criteria payload malformed for its criteria_type. |
CHALLENGE_OBJECTIVE_TYPE_UNKNOWN | Objective type is not a recognised evaluator. |
CHALLENGE_OBJECTIVE_CRITERIA_INVALID | Objective criteria payload malformed for its objective_type. |
CHALLENGE_SCORING_INVALID | Challenge scoring configuration malformed. |
GATE_UNAVAILABLE | A feature-gate/plan lookup was temporarily unavailable; retry. |
Streaming
STREAM_PARTICIPANT_MISMATCH | The participant token does not match the requested stream. |
STREAM_SCOPE_MISSING | The participant token lacks the required read:state scope. |
System
SYS_UNAVAILABLE | A required backend dependency is temporarily unavailable; retry with backoff. |
SYS_UNHANDLED | Unhandled internal error; safe to retry idempotent calls. Report the request_id. |
