Skip to main content
Every error response is JSON in this shape:
{
  "error": {
    "code": "org_not_found",
    "message": "Org \"acme\" does not exist.",
    "request_id": "req_e1e3f521-c291-40d3-9edb-b5875ef5b417",
    "doc_url": "https://docs.goparlay.io/errors#org_not_found",
    "details": { "org_id": "acme" }
  }
}
The 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)

CodeWhat it meansWhat to do
authentication_requiredNo Authorization headerSet Authorization: Bearer <key>
invalid_api_keyKey doesn’t match any active partnerCheck for typos; rotate via dashboard
key_revokedKey was revokedGenerate a new key, update your env var
key_environment_mismatchLive key on sandbox URL or vice versaMatch the key prefix to the base URL
scope_requiredEndpoint needs a scope your key doesn’t haveRequest the scope from your account manager

Validation (400 / 422)

CodeStatusWhat to do
invalid_request400Body doesn’t match the schema. See details for the offending field
missing_field400Required field omitted. See details.field
invalid_enum400Field value not in allowed enum. See details.allowed
invalid_url400URL is malformed
invalid_recording_url422Recording URL not reachable / not a supported codec
recording_too_long422Audio over 60 minutes — split it
recording_too_short422Audio under 10 seconds — likely a bad upload
unsupported_codec422Use MP3, WAV, M4A, or FLAC

Not found (404)

CodeWhat to do
org_not_foundVerify org_id; case-sensitive. Use list_orgs / GET /v1/orgs
rep_not_foundVerify rep_id within the right org_id
analysis_not_foundVerify the UUID. May be soft-deleted — purge can be reversed only manually
playbook_not_foundSoft-deleted or wrong org
webhook_not_foundWebhook archived
prompt_not_foundSoft-deleted or wrong org
draft_not_foundVerify the draft UUID exists in this org
synthesis_not_foundNo synthesis exists yet — call generate_rep_synthesis first

Conflict (409)

CodeWhat to do
idempotency_key_reusedSame idempotency key + different payload. Generate a fresh UUID
analysis_already_processingDon’t re-submit the same recording_url; check status first
analysis_cannot_rescoreRescore not yet supported on this analysis type
draft_already_publishedDraft was already promoted to a playbook
webhook_disabledWebhook is paused — un-pause via update_webhook first

Limits (429)

CodeWhat to do
rate_limitedSleep Retry-After seconds, then retry. The MCP client does this automatically once
quota_exceededPlan / billing action required
sandbox_limit_reachedYou hit a sandbox-only daily cap. Wait or move to live keys
concurrency_limit_reachedToo many in-flight async jobs. Wait for some to complete

Pipeline (502 / 504)

CodeStatusWhat to do
transcription_failed502Deepgram failed. Retry once; check audio quality
analysis_failed502Gemini returned bad output. Retry once; ping support if persistent
upstream_unavailable502Deepgram or Gemini outage. Retry with backoff
upstream_timeout504Job exceeded internal time budget. Retry; check audio length

Compliance (422 / 403)

CodeStatusWhat to do
pii_policy_violation422Recording contains PII you’ve configured to reject. Adjust org policy or scrub the file
retention_policy_violation422Operation blocked by your retention rules
healthcare_without_baa403Healthcare data requires a signed BAA. Contact account manager

Partner state (404 / 403)

CodeWhat it means
partner_not_foundKey resolves to a partner record we can’t find. Contact support
partner_suspendedAccount suspended. Billing or compliance issue — check email

Server (500 / 501)

CodeWhat to do
internal_errorBug on our side. Retry once; if persistent, file a ticket with the request_id
not_implementedEndpoint is reserved for a future release

Retry strategy

The MCP server retries automatically on:
  • Any 5xx
  • rate_limited (with Retry-After header honored, max once)
  • transcription_failed, analysis_failed, upstream_timeout, upstream_unavailable (max once)
It does not retry on auth, validation, conflict, not-found, or quota errors — those need code/config changes, not retries. Custom REST integrations should follow the same pattern.