code field is stable — write your error-handling logic against code, not message (messages may improve; codes are the contract).
The request_id should be included in any support ticket — we can pull the full server log from it.
Quick remediation table
Auth (401 / 403)
| Code | What it means | What to do |
|---|---|---|
authentication_required | No Authorization header | Set Authorization: Bearer <key> |
invalid_api_key | Key doesn’t match any active partner | Check for typos; rotate via dashboard |
key_revoked | Key was revoked | Generate a new key, update your env var |
key_environment_mismatch | Live key on sandbox URL or vice versa | Match the key prefix to the base URL |
scope_required | Endpoint needs a scope your key doesn’t have | Request the scope from your account manager |
Validation (400 / 422)
| Code | Status | What to do |
|---|---|---|
invalid_request | 400 | Body doesn’t match the schema. See details for the offending field |
missing_field | 400 | Required field omitted. See details.field |
invalid_enum | 400 | Field value not in allowed enum. See details.allowed |
invalid_url | 400 | URL is malformed |
invalid_recording_url | 422 | Recording URL not reachable / not a supported codec |
recording_too_long | 422 | Audio over 60 minutes — split it |
recording_too_short | 422 | Audio under 10 seconds — likely a bad upload |
unsupported_codec | 422 | Use MP3, WAV, M4A, or FLAC |
Not found (404)
| Code | What to do |
|---|---|
org_not_found | Verify org_id; case-sensitive. Use list_orgs / GET /v1/orgs |
rep_not_found | Verify rep_id within the right org_id |
analysis_not_found | Verify the UUID. May be soft-deleted — purge can be reversed only manually |
playbook_not_found | Soft-deleted or wrong org |
webhook_not_found | Webhook archived |
prompt_not_found | Soft-deleted or wrong org |
draft_not_found | Verify the draft UUID exists in this org |
synthesis_not_found | No synthesis exists yet — call generate_rep_synthesis first |
Conflict (409)
| Code | What to do |
|---|---|
idempotency_key_reused | Same idempotency key + different payload. Generate a fresh UUID |
analysis_already_processing | Don’t re-submit the same recording_url; check status first |
analysis_cannot_rescore | Rescore not yet supported on this analysis type |
draft_already_published | Draft was already promoted to a playbook |
webhook_disabled | Webhook is paused — un-pause via update_webhook first |
Limits (429)
| Code | What to do |
|---|---|
rate_limited | Sleep Retry-After seconds, then retry. The MCP client does this automatically once |
quota_exceeded | Plan / billing action required |
sandbox_limit_reached | You hit a sandbox-only daily cap. Wait or move to live keys |
concurrency_limit_reached | Too many in-flight async jobs. Wait for some to complete |
Pipeline (502 / 504)
| Code | Status | What to do |
|---|---|---|
transcription_failed | 502 | Deepgram failed. Retry once; check audio quality |
analysis_failed | 502 | Gemini returned bad output. Retry once; ping support if persistent |
upstream_unavailable | 502 | Deepgram or Gemini outage. Retry with backoff |
upstream_timeout | 504 | Job exceeded internal time budget. Retry; check audio length |
Compliance (422 / 403)
| Code | Status | What to do |
|---|---|---|
pii_policy_violation | 422 | Recording contains PII you’ve configured to reject. Adjust org policy or scrub the file |
retention_policy_violation | 422 | Operation blocked by your retention rules |
healthcare_without_baa | 403 | Healthcare data requires a signed BAA. Contact account manager |
Partner state (404 / 403)
| Code | What it means |
|---|---|
partner_not_found | Key resolves to a partner record we can’t find. Contact support |
partner_suspended | Account suspended. Billing or compliance issue — check email |
Server (500 / 501)
| Code | What to do |
|---|---|
internal_error | Bug on our side. Retry once; if persistent, file a ticket with the request_id |
not_implemented | Endpoint is reserved for a future release |
Retry strategy
The MCP server retries automatically on:- Any 5xx
rate_limited(withRetry-Afterheader honored, max once)transcription_failed,analysis_failed,upstream_timeout,upstream_unavailable(max once)

