Error handling
Expected API errors use a consistent JSON format and one of the documented HTTP
status codes. This includes requests to an unknown path and requests that use
an unsupported method on a known path. Unexpected 500 responses add a
support_id, as described under 500 Internal Server Error.
Error response format
An expected error response follows this structure:
code— a stable, machine-readable class from a small closed set (see Error Codes). Branch on this. New codes are only added with a documented API change.message— a human-readable, English-only message whose phrasing may change. Use it for display and diagnostics.
Use the HTTP status code to determine whether a request succeeded. Any 2xx status
indicates success. Successful response bodies vary by endpoint and do not use a
common success field.
Request validation errors
A request-validation response contains exactly one error. The message embeds
the failing path:
Fix that error and retry the request. If another field is invalid, the next
response identifies it. Validation responses do not include submitted values
or validator-specific fields such as detail, errors, location, or value.
Error codes
For expected errors, the code field is the stable contract for programmatic
error handling. The closed set contains thirteen classes, mapped to these HTTP
status codes:
The set is closed. These thirteen expected-error codes are the complete list.
Branch on code for programmatic handling and fall back to the HTTP status
class for anything you do not special-case; do not pattern-match the message
string. Unexpected 500 responses use internal_error in a separate format.
W3C trace context
The API supports the W3C Trace Context traceparent and tracestate request headers. It validates their W3C shape and ignores malformed values.
A valid incoming context is linked to a new server-owned trace with its own trace identifier.
Every response carries the server-owned traceparent. Log this response header
with your request context, and include it when you report a problem. The same
trace propagates through command processing and webhook delivery.
Transport. The API is machine-to-machine (M2M), server-to-server HTTP/JSON.
Send Content-Type: application/json on requests with a JSON body. Request-body
limits are documented under 413 Payload Too Large.
HTTP status codes
400 Bad Request
The request is malformed or contains invalid parameters. This includes a missing
or malformed Authorization credential; a syntactically valid credential with
an invalid API key returns 401 Unauthorized instead.
401 Unauthorized
The Bearer credential has a valid application identifier, but its API key is
missing or invalid. Missing or malformed Bearer credentials return
400 invalid_authorization_header instead.
403 Forbidden
You are authenticated, but the action is not permitted. A 403 indicates a policy or resource limit on a resource your application owns. A resource owned by another application returns 404 (see 404 Not Found).
404 Not Found
The requested path or resource does not exist. Sessions and rooms owned by another application also return 404.
405 Method Not Allowed
The request path exists, but it does not accept the HTTP method you used.
409 Conflict
The request conflicts with the current state of the resource.
422 Unprocessable Entity
The request was well-formed but could not be processed. A 422 uses
code: invalid_request for either of these conditions:
Both conditions have the same code, so do not use code alone to select the
recovery action. Use the request context: correct a Dial validation failure, or
use a new idempotency key when you changed a request. Do not pattern-match the
human-readable message, because its phrasing may change.
413 Payload Too Large
Two distinct conditions return 413, each with its own code. payload_too_large means the request body is too big; result_set_too_large means the response a list endpoint would return is too big. Branch on the code field to tell them apart.
For payload_too_large: the request body exceeds the per-route size limit. The default limit is 1 MiB; the per-session command route (POST /v1/sessions/{uuid}/{command}) has a 64 KiB limit.
For result_set_too_large: list endpoints (sessions, rooms, members) return all matching items by default. A full matched set above 50,000 items returns this error. A smaller limit does not avoid the check because it applies to the full matched set first. Narrow a sessions query with its filters. Room and member list endpoints have no narrowing filter.
415 Unsupported Media Type
The request explicitly supplies a malformed Content-Type header or a media
type other than application/json.
429 Too Many Requests
You have exceeded the rate limit. The error body contains only code and
message. Read the integer delay from the Retry-After response header, wait
at least that many seconds, and then retry. See Rate Limits for
details.
500 Internal Server Error
An unexpected platform failure returns a top-level code, message, and opaque
support_id:
Do not parse the support ID. Quote it when you contact support. The response does not expose the technical cause or a vendor event identifier.
502 Bad Gateway
The platform could not admit a playback or DTMF prompt source. The response uses
code: playback_source_error and includes a detail object:
reasonclassifies the failure asunsupported,not_found,access_denied,timeout,unreachable,rejected,invalid_response, orpreparation_failed.source_indexidentifies the failing zero-based item when the request contains multiple URLs.retryableindicates whether retrying the same source later may succeed.upstream_statuscontains the source origin’s HTTP status when one was received.
Use detail.reason and detail.retryable to decide whether to correct the
source or retry. The response never contains source URLs, credentials, raw
upstream response bodies, filesystem paths, or media-engine details.
503 Service Unavailable
503 covers the temporary capacity and dependency failures below. Follow the
recovery action documented for the condition you receive.
529 Site Overloaded
The platform has no outbound capacity. The error body contains only code and
message. Read the integer delay from the Retry-After response header, wait
at least that many seconds, and then retry. 529 is a non-standard status code
for overload.
Handle errors
- Always check the HTTP status code first. A 2xx status means the request was accepted. Any other status indicates an error.
- Branch on the
codefield, not the message. Thecodeis a stable closed enum; themessagestring is human-readable and may change. - Capture the response
traceparent. Log the server-owned response value alongside your request context and quote it when reporting a problem to support. - Propagate W3C trace context. Send a valid
traceparentwith the request and preservetracestatewhen present. - Use the
messagefield for display and diagnostics only. Error messages are designed to be human-readable and actionable, but are not part of the programmatic contract. - Honor
Retry-After. For429and529responses, wait at least the number of seconds in the response header before retrying. Do not look for retry timing in the JSON body. - Back off after repeated retryable errors. If another
429or529follows a retry, honor itsRetry-Afterheader and increase your backoff. Use backoff for other documented temporary dependency failures andRecording unavailable. Contact support if repeated attempts fail.