Skip to main content
Corti uses standard HTTP status codes. 4xx errors indicate a problem with the request; 5xx errors indicate a problem on Corti’s side. Error responses are in JSON and differ between the SDKs and the REST API. The tabs below cover each.
Some Corti products handle errors and authentication differently than what is described below:
  • Admin API — Separate from the Corti API used for speech to text, text generation, and agentic workflows. See the Administration API reference for details. Please contact us if you have interest in this functionality or further questions.
  • Agents API — The JSON format of the error response is different. See the Agents API docs for more info.
  • Embedded Assistant — Authentication is handled differently. See the Embedded Assistant Authentication docs for those methods.
The SDK throws typed error classes on any non-2xx response or internal failure. Each class exposes a different set of attributes. See Error Handling for full details.

Error Classes

HTTP Status Codes

Token endpoint errors are returned as JSON in the response body. Corti API errors are returned in the WWW-Authenticate response header with no body. The header is not accessible from the exception directly; use .WithRawResponse() on the request if you need it.
Attempting to access a resource that belongs to a different OAuth client also returns a 404, not a 403. This is intentional. Returning a 403 would confirm that the resource exists, which is a security risk.
You have exceeded the rate limit for the API. The SDK automatically retries with exponential backoff. The default retry limit is 2. Override per request:
If the error persists, reduce request frequency or contact support to discuss your rate limit requirements.
An unexpected error occurred on the Corti side. Double check the request format and retry the request. If the issue persists, contact support.
The service is temporarily unavailable. Retry with exponential backoff. Monitor the status page.

WebSocket APIs

WebSocket errors from /streams and /transcribe are surfaced as plain Error objects whose message is the server status code (e.g. CONFIG_DENIED, CONFIG_MISSING, CONFIG_TIMEOUT).
Every CONFIG_* server message also carries a reason field with human-readable details behind the failure. Whether you can read it depends on the mode you connected in:
  • Default mode (client.stream.connect({ id, configuration }) / client.transcribe.connect({ configuration })): the SDK handles the handshake-phase and CONFIG_* messages internally. It rejects connect() with just the bare code. The reason is not exposed.
  • awaitConfiguration: false or manual mode: the raw message, including msg.reason, flows through socket.on('message', …).
You sent a config message, but it’s invalid.
You sent a non-config frame before any valid config message arrived.
Only reachable when you opt out of the automatic handshake. Default mode sends config for you.
The 10-second handshake window elapsed without any config message arriving.
Only reachable in manual mode. The default handshake sends config well within the 10s budget.