Help / Error envelope
Every REST / MCP endpoint returns the same envelope on error. error_code is a machine-readable enum agents can branch on for automatic retry / fallback.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{
"detail": "Rate limit exceeded",
"error_code": "RATE_LIMITED",
"category": "transient",
"retry_after_seconds": 12,
"suggested_action": "exponential_backoff"
}category is one of permanent / transient / unauthorized / budget_exceeded. suggested_action is a hint for agents (refresh_token / top_up_credit / exponential_backoff / fix_request_payload).
error_code values and retry semantics| error_code | HTTP | Meaning | Retry semantics |
|---|---|---|---|
VALIDATION_ERROR | 400 / 422 | Failed body / query validation. detail includes field info. | retryable: false (fix needed) |
UNAUTHORIZED | 401 / 403 | Token invalid / expired / scope missing. Run codens-mcp login. | retryable: true (after re-auth) |
CREDIT_INSUFFICIENT | 402 | Out of credits. Top up via Pricing page or Auth Codens dashboard. | retryable: false |
RESOURCE_NOT_FOUND | 404 | The target resource doesn't exist or belongs to another org. | retryable: false |
RATE_LIMITED | 429 | Rate limit exceeded. Respect the Retry-After header / retry_after_seconds. | retryable: true (exp. backoff) |
INTERNAL_ERROR | 500 / 503 | Unexpected server error. Include detail + request ID when contacting support. | retryable: true (short backoff) |
IDEMPOTENCY_CONFLICT | 409 | Same Idempotency-Key re-sent with a different payload. | retryable: false (change key or match payload) |
JWT_EXPIRED / JWT_INVALID / JWT_REPLAYED | 401 | Service-to-service JWT verification failed. Re-issue from Auth Codens. | retryable: true (after re-auth) |
ORG_NOT_LINKED_TO_AUTH / ORG_NOT_FOUND | 403 / 404 | Cross-service organization_id is unknown / not linked. Omit it — credentials resolve automatically. | retryable: false |
SERVICE_DISABLED | 403 | The service is disabled for this organization. | retryable: false |
Cross-service organization_id caveat
Red / Blue / Green / Purple each issue independent organization_id values. Passing an org ID from one service into another produces UNAUTHORIZED / ORG_NOT_FOUND. codens-mcp v0.7.5+ resolves them automatically via /api/v1/auth/me, so explicit values are not required.