Errors
Cobuntu errors are JSON with a stable envelope and a meaningful HTTP status. Match on the status code, not the message string.
Error envelope
{
"error": "API key missing required scope: WRITE_MEMBERS",
"code": "INSUFFICIENT_SCOPE",
"requestId": "req_8f9a2b3c4d5e6f7g",
"grantedScopes": ["READ_PUBLIC"]
}| Field | Always present? | Notes |
|---|---|---|
error | ✓ | Human-readable message. Useful for logs/operators. Not stable — wording can change between versions. |
code | When set | Machine-readable code. Stable across versions for the same logical failure. Use this for programmatic branching. |
requestId | When set | Trace id. Quote this in support tickets. |
| (extras) | When set | Some errors include extra fields like grantedScopes (403), field (400 validation), retryAfter (429). |
Status code reference
400 Bad Request — request is malformed
The request body / query params didn't pass validation. The code
field tells you which validation failed:
INVALID_INPUT— generic shape issue (missing required field, wrong type)INVALID_EMAIL— email field didn't match RFC patternINVALID_SLUG— URL slug had unsupported charactersINVALID_DATE— date string wasn't ISO 8601INVALID_AMOUNT— money amount was negative or non-integer cents
These are client bugs. Fix the request; retrying won't help.
401 Unauthorized — no key, or invalid key
{ "error": "API key required. Pass it via X-API-Key header." }or
{ "error": "Invalid API key." }Either the X-API-Key header is missing/empty, or the key doesn't exist (typo / revoked / wrong env). See Authentication for the full flow.
403 Forbidden — key valid but lacks permission
Three flavors:
{ "error": "API key missing required scope: WRITE_MEMBERS",
"grantedScopes": ["READ_PUBLIC"] }Key doesn't carry the scope this endpoint requires. Generate a key with the right scope, or use ADMIN.
{ "error": "API key does not have access to this community" }Key belongs to a different community than the URL's :communityTag. Keys are per-community.
{ "error": "Atlas is not enabled for this community" }The endpoint requires a feature flag the community doesn't have. Enable in cobuntu-admin first.
404 Not Found
The resource doesn't exist (deleted, never created, wrong id). The response body has minimal detail by design — we don't leak existence information.
409 Conflict
The state transition you're attempting isn't valid:
member.approvedalready approved → 409 (use idempotency, not retry)- Subscription already cancelled → 409
- Refund exceeds remaining refundable amount → 409
The code field tells you the specific conflict.
422 Unprocessable Entity — semantic validation
The request was syntactically valid (passed 400 checks) but semantically wrong:
- Trying to approve a request that's already rejected
- RSVPing to an event that's full
- Submitting a form that requires fields you didn't include
429 Too Many Requests — rate limited
{ "error": "Rate limit exceeded. Retry after 4 seconds.",
"code": "RATE_LIMITED" }Headers include Retry-After (seconds) and X-RateLimit-Reset
(Unix timestamp when the window resets). Back off and retry.
Default rate limits:
- Publishable keys: 100 req/s
- Secret keys: 50 req/s
- Broadcasts: 5 sends / 24h / community
500 Internal Server Error
We had a bug. The response body has a requestId — quote it in support so we can find the trace. Retries are safe (we're already idempotent at the request level for reads + writes carrying an Idempotency-Key).
502 Bad Gateway / 503 Service Unavailable
An upstream we depend on (Stripe, our database, etc.) is degraded. Retry with exponential backoff: 1s → 2s → 4s → 8s → 16s, cap at ~5 attempts. Past that, surface a user-facing error.
504 Gateway Timeout
A request took longer than our 30s edge timeout. Almost always indicates either a slow query on our side (file a bug with requestId) or your call hit a network blip. Retry.
Idempotency
Write endpoints accept Idempotency-Key: <your-uuid> header. Two
requests with the same key (within 24h) get the same response —
the second is a replay of the first, never a duplicate state
change.
curl -X POST https://api.cobuntu.com/api/v1/communities/my-community/applications/req_123/approve \
-H "X-API-Key: sk_live_..." \
-H "Idempotency-Key: 8f9a2b3c-4d5e-6f7g-8h9i-0j1k2l3m4n5o"Use any UUID v4. Pattern: generate one per logical operation in your code, persist it alongside the operation, retry safely.
Retry strategy summary
| Status | Retry? | Backoff |
|---|---|---|
| 400, 401, 403, 404, 409, 422 | No — client error, fix the request | n/a |
| 429 | Yes, after Retry-After | Use the header value |
| 500 | Yes (with Idempotency-Key on writes) | Exponential: 1s, 2s, 4s, 8s, 16s |
| 502, 503, 504 | Yes (with Idempotency-Key on writes) | Same as 500 |
| Network error (no response) | Yes (with Idempotency-Key on writes) | Same as 500 |