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. It also includes public API requests
that accept only server-sent events. 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 Accept: application/json for API responses. On requests with a JSON body,
send Content-Type: application/json. The public API doesn’t provide
server-sent events. Use signed webhooks for lifecycle updates. Request-body
limits are documented under 413 Payload Too Large.
HTTP status codes
400 Bad Request
The request is malformed or contains invalid parameters. Missing or malformed
Authorization headers return 400. Invalid credentials return
401 Unauthorized.
401 Unauthorized
The supplied credentials are invalid. Missing or malformed Authorization
headers return 400 invalid_authorization_header instead.
403 Forbidden
The request is authenticated, but the action is not permitted. A 403 indicates a policy or resource limit.
404 Not Found
The requested path or resource does not exist.
405 Method Not Allowed
The request path exists, but it does not accept the HTTP method you used.
406 Not Acceptable
The public API returns 406 when an Accept header requests an event-stream
representation without permitting an application/json response. JSON can be
accepted through application/json, application/*, or */* at a positive
quality value. An exact application/json;q=0 range overrides a broader
wildcard. The response uses the application/json content type and the
invalid_request code.
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, participants) 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 participant 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.