/v1/agent/* come back as JSON with a status and a message:
-
Validation failures (
422) return pydantic’s error list, one entry per problem. Offending input values are stripped, so write-only credentials are never echoed back: -
Phone-call creation (
POST /v1/agent/phone-calls) adds a machine-readablereasonfield to its errors; see Outbound calls for the full list. -
A request body that isn’t valid JSON returns
400with"Malformed JSON"; a missing body or wrongContent-Typereturns a bare415. -
A missing or malformed
Authorizationheader returns a bare401with aWWW-Authenticate: Bearerheader; a present-but-bad credential returns the JSON shape ("Invalid token","Token expired").
Status codes
400 vs 422
422 is field-level validation: unknown fields (the public surface rejects them), length caps, enum values, invalid IANA timezones, dynamic-variable naming. 400 is semantic: an override not enabled for the agent, mutually exclusive pagination parameters (page + cursor), an undecodable cursor, a page offset past 100,000 rows, or a knowledge upload that isn’t UTF-8 plain text.
Two quirks worth coding around:
- Explicit
nullis rejected onPATCHendpoints with422: omit a field to keep its value, send""to clear a text field. - Path-parameter validation renders
404, not422: a non-integer{version_number}looks like a missing version.
403: what was refused
404: anti-enumeration
A resource that exists but belongs to another team returns the identical404 body as one that never existed. This applies to agents, sessions, tools, knowledge sources, phone numbers, and versions. Released phone numbers and deleted knowledge sources behave the same. Never use 404 vs 403 to probe for existence.
The recording endpoint adds one more meaning: Recording not found on a real session means it was never recorded.
409: conflicts
Billing and rate limits
Exactly two endpoints charge before acting, and both can return402 Out of API credit: POST /v1/agent/sessions (API-key callers) and POST /v1/agent/phone-numbers (the first rental day). Anonymous public sessions never see 402. An out-of-credit owner surfaces to visitors as 403 Agent is unavailable. Usage is settled after each call and never fails a request.
429 applies only to anonymous session creation on public agents, in fixed per-minute windows per agent and per client IP. API-key traffic is not rate limited on this surface; your backend is the gate.
5xx
502 names the failing upstream in the message: the conversation gateway (Agent gateway is unreachable) or the telephony provider (Twilio refused the request: …). Retrying is safe. A failed phone-number purchase leaves the row visible with status error, refunds the day charge, and can be released; a failed release keeps the number live so releasing again retries. 503 means a platform dependency was briefly unreachable; retry with backoff.
Going further
Authenticated sessions
The session token flow: request fields, lifetime, errors.
Public agents
Origin allowlists and the errors unique to keyless access.

