Skip to main content

Error Codes

Every Adjudon API response follows the same envelope shape. Failures return a stable string code you can branch on; the human-readable error field is for humans, the code is for machines. Tested against API version v1.

The error envelope

Failure response
{
"success": false,
"error": "Entry not found",
"code": "NOT_FOUND"
}
Success response
{
"success": true,
"data": { /* resource-shaped */ }
}

The error string may change for clarity; the code is a stable machine identifier safe to branch on.

HTTP status families

StatusMeaningNotes
2xxSuccess201 = trace approved; 202 = trace flagged for review (held, not blocked)
4xxClient errorAuthentication, validation, plan-gate, rate-limit
5xxServer errorSafe to retry with exponential backoff

The trace-ingestion endpoint (POST /api/v1/traces) is the one place where 2xx carries product semantics: 201 approved, 202 held for review, and 403 ADJ_BLOCKED_BY_POLICY when blocked. See Traces API.

Authentication errors (401 / 403)

CodeHTTPCause
NO_TOKEN401Authorization header missing
INVALID_API_KEY_FORMAT401API key does not start with adj_live_ or adj_test_
INVALID_API_KEY401Key not found or revoked
TOKEN_REVOKED401Session blacklisted (sign in again)
SESSION_REVOKED401Explicit logout has invalidated the session
TOKEN_VERIFICATION_FAILED401JWT signature failed
UNAUTHORIZED_NO_USER401JWT valid but user record gone
FORBIDDEN403Authenticated but lacks the role for this operation
UPGRADE_REQUIRED403Feature requires a higher plan tier; response data carries currentPlan, requiredPlans, feature

Validation and resource errors (400 / 404 / 409)

CodeHTTPCause
VALIDATION_ERROR400Request body or query failed schema validation
INVALID_INPUT400A specific field is malformed
INVALID_OPERATION400The operation is well-formed but illegal in the current state
NOT_FOUND404The requested resource does not exist or is owned by another organization
ALREADY_EXISTS409A duplicate would be created (e.g., re-inviting the same email)
EXPIRED410The token, invitation, or transient resource has expired

Rate-limit errors (429)

CodeHTTPCause
RATE_LIMIT_EXCEEDED429Per-key or per-agent rate limit hit; response data carries limit and windowSeconds
curl (429 response body)
HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
"success": false,
"error": "Agent rate limit exceeded (60 requests per minute). Try again later.",
"code": "RATE_LIMIT_EXCEEDED",
"data": { "limit": 60, "windowSeconds": 60 }
}
Python — back off and retry
import time, requests, os
def post_trace(payload, attempt=0):
r = requests.post(
"https://api.adjudon.com/api/v1/traces",
json=payload,
headers={"Authorization": f"Bearer {os.environ['ADJUDON_API_KEY']}"},
)
if r.status_code == 429 and attempt < 5:
time.sleep(2 ** attempt) # 1, 2, 4, 8, 16 seconds
return post_trace(payload, attempt + 1)
r.raise_for_status()
return r.json()

See Rate Limits for limits per plan tier.

Server errors (5xx)

CodeHTTPCause
INTERNAL_ERROR500Generic server fault; safe to retry
CONFIG_ERROR500Server-side misconfiguration; not retryable until operator intervenes
Resource-specific *_FAILED codes500Per-resource handler error (e.g., HASH_CHAIN_VERIFY_FAILED, INCIDENT_CREATE_FAILED); listed on each resource's reference page

5xx responses are safe to retry with exponential backoff. Use the SDK's built-in retry helper or the Python pattern shown above.

Resource-specific codes

Every D1 resource page lists its 4xx / 5xx codes inline (e.g., HASH_CHAIN_VERIFY_FAILED, ADJ_BLOCKED_BY_POLICY, FRIA_TRANSITION_FAILED, INCIDENT_CREATE_FAILED). See Hash Chain, Traces, FRIA, Incidents.

Stability and honesty

  • The code field is a stable contract: new codes may be added; existing codes are not renamed without a 90-day deprecation notice in the Changelog. The error string may change for clarity and is not part of the contract.
  • The envelope today is { success, error, code }. A request_id field for triage correlation is on the Q3 2026 roadmap; until then, the time of failure plus the code is the triage handle.
  • Unknown codes are coerced to INTERNAL_ERROR server-side as a fail-open guard.

See also