API fundamentals
Error-code reference
Every error response carries a stable error.code. Search or filter the table, then open a code for its causes, fixes, retry guidance and an example response. The envelope itself is described in Error handling.
66 of 66 error codes
| Error code | HTTP status | Meaning | How to fix | Retry? |
|---|---|---|---|---|
invalid_cursor | 400 | The pagination cursor is invalid or does not match these filters. | Send next_cursor exactly as returned, with the same filters. To change filters, start again without a cursor. | No |
invalid_idempotency_key | 400 | The Idempotency-Key header must be 1 to 255 printable ASCII characters with no spaces. | Use a UUID v4 or another URL-safe token of at most 255 characters. | No |
invalid_json | 400 | The request body is not valid JSON. | Serialize the body with a JSON library rather than by string concatenation. | No |
invalid_phone_number | 400 | The phone number is not a valid E.164 number. | Normalize numbers to E.164 before sending them. | No |
validation_error | 400 | One or more fields are invalid. | Read details.errors[].field and details.errors[].issue, correct each field and resend. | No |
api_key_expired | 401 | This API key has expired. | Switch to the replacement key, or ask a workspace admin to create a new key in the console. | No |
api_key_revoked | 401 | This API key has been revoked. | Ask a workspace admin for a new key. | No |
authentication_required | 401 | Send your API key as a Bearer token in the Authorization header. | Send Authorization: Bearer rai_test_... (test mode) or Authorization: Bearer rai_live_... (live mode). | No |
invalid_api_key | 401 | The API key is not valid. | Copy the key again from where you stored it when it was created. Keys are shown only once; if it is lost, create a new key in the console under API & Developers. | No |
legacy_api_key_not_supported | 401 | Legacy API keys cannot be used with the v1 API. Create a scoped key in the console. | Create a scoped key in the console under API & Developers and use it instead. | No |
campaign_budget_reached | 402 | This campaign has reached its budget cap. | Raise or clear budget_cap with PATCH /v1/campaigns/{campaign_id}, then start or resume. | No |
insufficient_balance | 402 | The workspace balance is too low to start this call. Top up to continue. | A workspace admin tops up the balance in the console (Billing), then retry. | No |
spend_limit_reached | 402 | This workspace has reached the monthly spend limit set by its admin. | A workspace admin raises or removes the limit in the console settings. | No |
account_inactive | 403 | This workspace cannot place calls because its account is not active. | A workspace admin can upgrade the plan in the console, or contact support about a suspension. | No |
api_access_not_enabled | 403 | API access is not enabled for this workspace. | Write to support@relationsai.com to request access for the workspace. | No |
insufficient_permissions | 403 | The member who created this API key no longer has permission for this operation. | Ask a workspace admin to create a new key from an account that holds the permission. | No |
insufficient_scope | 403 | This API key does not have the scope this operation requires. | Ask a workspace admin to create a key that includes the scopes in details.required_scopes. | No |
ip_not_allowed | 403 | Requests from this IP address are not allowed for this workspace. | Ask a workspace admin to add the server's egress address to the allowlist in the console security settings. | No |
live_key_not_allowed_in_browser | 403 | Live API keys cannot be used from a browser. Use a test key, or call the API from your server. | Move live calls to your server. | No |
webhooks_not_enabled | 403 | Webhook delivery is not available yet. | Write to support@relationsai.com to ask when webhook delivery will be available. | No |
resource_not_found | 404 | No such resource. | Check the id and the key mode. List the resource to find valid ids. | No |
route_not_found | 404 | No such route. | Compare the path with the API reference. | No |
method_not_allowed | 405 | This route does not support that HTTP method. | Use a method listed in the Allow header. | No |
campaign_dnc_override_enabled | 409 | This campaign is set in the console to also call contacts on the do-not-call list, so it cannot be started or resumed through the API. | Ask a workspace admin to switch the setting off in the console, then start or resume it through the API. | No |
campaign_has_no_recipients | 409 | This campaign has no recipients to call. | Add recipients with POST /v1/campaigns/{campaign_id}/recipients, then start it. | No |
campaign_not_resumable | 409 | This campaign cannot be resumed. Start it again to begin a new run. | To call only the people not reached yet, list the recipients whose status is still pending, create a new campaign with those contacts, and start it. | No |
campaign_operation_in_progress | 409 | This campaign is being started or resumed by another request. Retry shortly. | Wait Retry-After seconds, retrieve the campaign, and act on its new status. | After Retry-After |
campaign_outcome_unknown | 409 | The request was sent but its outcome is not confirmed yet. Check the campaign before trying again. | Wait Retry-After seconds, then retrieve the campaign: a running status means it started. Do not start or resume it again before you have checked. | After Retry-After |
campaign_pause_not_confirmed | 409 | The pause was requested but not confirmed. The campaign may still be dialling. | Retry the pause (with the same Idempotency-Key if you sent one; a repeated pause is harmless), then retrieve the campaign. If it is still running, use stop. | Yes, with backoff |
campaign_recipients_blocked | 409 | Some recipients of this campaign are now blocked by compliance rules, so it was not resumed. | List the campaign's recipients with status=pending (the people not reached yet), create a new campaign with those contacts minus the blocked ones in details.contact_ids, and start it. | No |
campaign_state_conflict | 409 | This action is not allowed in the campaign's current status. | Retrieve the campaign, check status and capabilities, and choose an allowed action. | No |
contact_already_exists | 409 | A contact with this phone number already exists. | Update the existing contact, or use the upsert operation. | No |
contact_limit_reached | 409 | No more contacts can be created right now. | Delete contacts you no longer need, or contact support. | No |
contact_on_dnc_list | 409 | This contact is on the do-not-call list. Remove its do-not-call entry before deleting it. | Keep the contact: it is what keeps the number from being called. Do not retry: the same request is refused every time. | No |
idempotency_key_in_progress | 409 | A request with this Idempotency-Key is still being processed. | Wait for Retry-After seconds and send the identical request again with the same key. | After Retry-After |
idempotency_key_reused | 409 | This Idempotency-Key was already used with a different request. | Use a new key for a new operation. For a retry, send exactly the original request. | No |
idempotency_outcome_unknown | 409 | An earlier request with this Idempotency-Key did not finish, and its outcome is unknown. | List or retrieve the resource (for a call, list calls filtered by to and created_after) to see whether the operation took effect. | No |
webhook_delivery_not_retryable | 409 | This delivery cannot be retried in its current status. | Retrieve the delivery list and retry only failed or retrying deliveries; for attempt_in_progress, wait a few seconds and read the delivery again. | No |
webhook_endpoint_disabled | 409 | This webhook endpoint is disabled. | Enable it with PATCH /v1/webhook-endpoints/{webhook_endpoint_id} and status: enabled. | No |
webhook_endpoint_limit_reached | 409 | This workspace already has the maximum number of webhook endpoints for this mode. | Delete an endpoint you no longer use, or subscribe one endpoint to more event types. | No |
media_link_expired | 410 | This recording link has expired. Retrieve the recording again for a new link. | Call GET /v1/calls/{call_id}/recording again and use the new url promptly. | No |
version_conflict | 412 | The resource changed since you read it. | Retrieve the resource again, re-apply your change to the new version, and resend with the new ETag. | No |
payload_too_large | 413 | The request body is too large. | Split the request into smaller batches. | No |
unsupported_media_type | 415 | Request bodies must be sent as application/json. | Send Content-Type: application/json with a JSON body. | No |
agent_not_ready | 422 | This agent cannot place calls right now. | Call GET /v1/agents/{agent_id}/readiness to see every reason. | No |
call_not_accepted | 422 | The call could not be placed. Nothing was dialled and nothing was charged. | Check the destination number and the agent's outbound number. If it keeps happening, contact support with the request_id. | No |
calling_not_configured | 422 | Calling is not set up for this workspace yet. | Finish calling setup in the console (Numbers), then retry. | No |
campaign_recipients_suppressed | 422 | Every recipient of this campaign is blocked by your compliance settings. Nothing was dialled. | This is a compliance outcome: do not retry; an unchanged start is refused again. | No |
campaign_too_large | 422 | This campaign has too many recipients to start in one run. | Start: split recipients across several campaigns. | No |
consent_required | 422 | This contact has no recorded consent, and consent is required for calls in this workspace. | Do not retry: the same request is refused every time until consent is recorded. | No |
contact_daily_limit_reached | 422 | This number has already been called the maximum number of times allowed in 24 hours. | Do not retry now: the same request is refused until the oldest of those calls is more than 24 hours old. | No |
custom_field_not_found | 422 | This custom field does not exist in the workspace. | Create the field in the console, or correct the key named in details.field. | No |
dnc_listed | 422 | This number is on your do-not-call list, so the call was not placed. | Do not call this number, and do not retry: the same request is refused every time. | No |
outside_calling_hours | 422 | This is outside the permitted calling window for this workspace. Nothing was dialled. | Do not retry now: the same request is refused until the window opens. Send it again inside the window in details (a new request; the refusal was not stored). | No |
phone_number_not_usable | 422 | This phone number cannot place outbound calls for this agent. | Pick a number whose capabilities.outbound is true, or omit phone_number_id to use the agent's outbound number. | No |
phone_number_required | 422 | This agent has more than one outbound number. Choose one with phone_number_id. | Send phone_number_id, or assign the agent to a single outbound number in the console. | No |
recipient_contacts_not_found | 422 | Some contact ids do not name contacts in this workspace. | Create the contacts first (POST /v1/contacts/upsert), then add their ids. | No |
telephony_disconnected | 422 | The telephony connection for this workspace is not working, so the campaign was paused. | Reconnect the telephony account in the console, then start or resume the campaign again. | No |
webhook_url_not_allowed | 422 | This URL cannot receive webhooks. | Use a public HTTPS URL on port 443 that resolves only to public addresses. Authenticate deliveries by verifying the signature instead of putting credentials in the URL. | No |
precondition_required | 428 | This update needs an If-Match header with the ETag of the version you read. | Retrieve the resource, copy its ETag response header into If-Match, and resend. | No |
calling_capacity_reached | 429 | Too many calls are being started right now. Retry after the number of seconds in the Retry-After header. | Wait Retry-After seconds and retry (with the same Idempotency-Key if you sent one). Spread call starts out, or use a campaign for volume. | After Retry-After |
daily_call_limit_reached | 429 | This workspace has reached its daily limit of calls placed through the API. | Wait until Retry-After (the next UTC midnight). | After Retry-After |
rate_limited | 429 | Too many requests. Retry after the number of seconds in the Retry-After header. | Wait Retry-After seconds. Spread requests out and back off exponentially. | After Retry-After |
internal_error | 500 | Something went wrong on our side. | For a read: retry with exponential backoff. | Yes, with backoff |
campaign_recipients_unavailable | 503 | The campaign's recipients could not be read for screening right now, so nothing was dialled. | Wait Retry-After seconds and retry (with the same Idempotency-Key if you sent one). | After Retry-After |
service_unavailable | 503 | The service is temporarily unavailable. Retry after the number of seconds in the Retry-After header. | Wait Retry-After seconds and retry (with the same Idempotency-Key if you sent one). | After Retry-After |