Every non-2xx response uses a unified envelope:
"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.
HTTP Code Meaning 401 api_key.invalid_formatBearer doesn’t start with afo_sk_live_ 401 api_key.not_foundToken is unknown — wrong, leaked & rotated, or for the wrong environment 401 api_key.revokedKey was revoked (revoked_at set) 403 api_key.scope_deniedKey is missing the scope this route requires (details.required tells you which) 403 api_key.org_inactiveThe organization is soft-deleted or is_active=false
HTTP Code Meaning 422 registration.title_requiredtitle is empty / whitespace-only422 registration.filename_requiredfilename is empty422 registration.creators_requiredcreators array is empty422 registration.commitment_invalidServer-side commitment failed validation (rare) 404 registration.upload_session_not_foundjob_id is unknown / expired / already consumed403 registration.upload_session_forbiddenCaller doesn’t own this upload session 413 registration.audio_too_largeAudio exceeds the configured max — details.size_bytes / details.max_bytes 422 registration.audio_emptyUploaded file is 0 bytes 422 registration.dry_run_failedChain dry-run rejected the submission — details.reason 404 registration.prepared_not_foundconfirm called after the prepare TTL expired or already confirmed once403 registration.prepared_forbiddenCaller doesn’t own this prepared job
HTTP Code Meaning 422 api_key.invalid_nameKey name is empty or > 100 chars 422 api_key.scopes_requiredscopes array is empty422 api_key.unknown_scopeAn entry in scopes is not recognised — details.value echoes which 422 api_key.webhook_url_invalidwebhook_url is not a valid http(s) URL — details.reason429 api_key.limit_reachedOrg has reached api_keys.max_keys_per_org (default 10) — details.max
HTTP Code Meaning 400 common.bad_requestGeneric input rejection (e.g. malformed Idempotency-Key) 401 common.unauthorizedNo credential in the request 403 common.forbiddenGeneric deny — typically insufficient credits, or an external_user_ref mismatch on a version update (the work was tagged with a different ref at register time). See details. 404 common.not_foundGeneric not-found — resource named in details.resource 422 common.validation_failedField-level validation failures — details.fields 429 common.quota_exceededFreemium quota reached — details.limit, details.used, details.resets_at 503 common.service_unavailableUpstream temporarily down — retry with backoff