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 APIused 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.
- JavaScript SDK
- C# .NET SDK
- REST API
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
| Class | Thrown when | Attributes |
|---|---|---|
CortiError | API returned a non-2xx HTTP response (4xx / 5xx) | message, statusCode, body, rawResponse |
CortiSDKError | SDK infrastructure error (e.g. localStorage unavailable) | message, code, cause |
ParseError | Input validation failed (e.g. missing PKCE verifier, invalid JWT) | message, errors |
JsonError | Response body could not be parsed as JSON | message, errors |
HTTP Status Codes
400 — Bad Request
400 — Bad Request
| Error code | When it occurs | How to resolve |
|---|---|---|
bad_request | The request body or query parameters are malformed or missing required fields. | Double check the fields submitted to be sure of correct format and necessary fields. |
401 — Unauthorized
401 — Unauthorized
403 — Forbidden
403 — Forbidden
| When it occurs | How to resolve |
|---|---|
| Accessing a resource (interaction, recording, transcript, document) that belongs to a different client. | Verify the resource ID was created by the authenticated client. |
404 — Not Found
404 — Not Found
| Error | When it occurs | How to resolve |
|---|---|---|
Invalid '{resource_name}' '{resource_id}' | The requested resource does not exist. | Verify the ID and parent resource ID is correct and was created under the authenticated tenant. |
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.
429 — Too Many Requests
429 — Too Many Requests
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.
500 — Internal Server Error
500 — Internal Server Error
An unexpected error occurred on the Corti side. Double check the request format and retry the request. If the issue persists, contact support.
503 — Service Unavailable
503 — Service Unavailable
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).`CONFIG_DENIED`
`CONFIG_DENIED`
You sent a config message, but it’s invalid.
reason from server | Likely cause | Fix |
|---|---|---|
invalid language code: must be a valid BCP 47 language tag | transcription.primaryLanguage is not a supported code. | Use a supported language code. |
invalid output locale: language should not be empty | mode.type: "facts" without mode.outputLocale. | Add outputLocale. |
invalid output locale: invalid language code: must be a valid BCP 47 language tag | mode.type: "facts" with invalid mode.outputLocale code. | Use a supported language code |
unknown mode | mode.type is not "transcription" or "facts". | Use one of the two supported values. |
invalid participants | Participant role outside doctor / patient / multiple. | Use one of the three supported roles. |
invalid audio format: MIME type not allowed... | audioFormat MIME type is not in the supported list. | Use a supported MIME type or omit the field. |
`CONFIG_MISSING`
`CONFIG_MISSING`
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.reason from server | Cause | Fix |
|---|---|---|
No valid configuration provided for interaction | A non-config frame reached the server before a config message. Typically sendAudio() / sendFlush() / sendEnd() in manual mode, or a raw socket.send() queued before OPEN in awaitConfiguration: false. | Be sure to call sendConfiguration() immediately after waitForOpen(), or pass configuration to connect() and let the SDK handle the handshake.` |
`CONFIG_TIMEOUT`
`CONFIG_TIMEOUT`
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.reason from server | Cause | Fix |
|---|---|---|
| Manual mode: no configuration provided within 10s | Server’s 10s handshake timer expired. | Call sendConfiguration() immediately after waitForOpen(). |