Skip to content

Error Codes

Every non-2xx response uses a unified envelope:

{
"error": {
"code": "registration.dry_run_failed",
"message": "Dry-run failed: insufficient balance to register work",
"details": { "reason": "..." }, // shape depends on `code`
"request_id":"req_8a3f..." // include in support tickets
}
}

Switch on code, never on message (messages may change; codes are stable). Always log request_id so support can correlate to server-side traces.

HTTPCodeMeaning
401api_key.invalid_formatBearer doesn’t start with afo_sk_live_
401api_key.not_foundToken is unknown — wrong, leaked & rotated, or for the wrong environment
401api_key.revokedKey was revoked (revoked_at set)
403api_key.org_mismatchThe key belongs to a different organization than the one in the URL
403api_key.scope_deniedKey is missing the scope this route requires (details.required tells you which)
403api_key.org_inactiveThe organization is soft-deleted or is_active=false
HTTPCodeMeaning
422registration.title_requiredtitle is empty / whitespace-only
422registration.filename_requiredfilename is empty
422registration.creators_requiredcreators array is empty
422registration.commitment_invalidServer-side commitment failed validation (rare)
404registration.upload_session_not_foundjob_id is unknown / expired / already consumed
403registration.upload_session_forbiddenCaller doesn’t own this upload session
413registration.audio_too_largeAudio exceeds the configured max — details.size_bytes / details.max_bytes
422registration.audio_emptyUploaded file is 0 bytes
422registration.dry_run_failedChain dry-run rejected the submission — details.reason
404registration.prepared_not_foundconfirm called after the prepare TTL expired or already confirmed once
403registration.prepared_forbiddenCaller doesn’t own this prepared job
HTTPCodeMeaning
422api_key.invalid_nameKey name is empty or > 100 chars
422api_key.scopes_requiredscopes array is empty
422api_key.unknown_scopeAn entry in scopes is not recognised — details.value echoes which
422api_key.webhook_url_invalidwebhook_url is not a valid http(s) URL — details.reason
429api_key.limit_reachedOrg has reached api_keys.max_keys_per_org (default 10) — details.max
HTTPCodeMeaning
400common.bad_requestGeneric input rejection (e.g. malformed Idempotency-Key)
401common.unauthorizedNo credential in the request
403common.forbiddenGeneric deny — typically insufficient credits, see details
404common.not_foundGeneric not-found — resource named in details.resource
422common.validation_failedField-level validation failures — details.fields
429common.quota_exceededFreemium quota reached — details.limit, details.used, details.resets_at
503common.service_unavailableUpstream temporarily down — retry with backoff