Errors
When a request cannot be handled, the API responds with an HTTP error status and a JSON body with this shape:
{ "error": { "code": "file_too_large", "message": "The recording is larger than the plan allows." }}Write your code against code, not against message. The codes are stable. The messages are in English, are meant to be read by a person, and their wording can change.
| HTTP | code |
What happened |
|---|---|---|
400 |
bad_request |
The body is not multipart/form-data, or the request is 20 MB or larger. |
400 |
no_file |
The form has no file field with a file. |
400 |
empty_file |
The file is empty. |
401 |
unauthorized |
The key is missing, is mistyped or has been revoked. |
402 |
no_minutes |
There are no minutes of audio left for this period. |
402 |
storage_full |
The account has no storage left. |
413 |
file_too_large |
The file is larger than the maximum size of the plan. |
415 |
not_audio |
The file is not an audio recording. |
422 |
agent_required |
The recording does not say whose call it is: it has no agent_code or agent_name, and no agent code in the file name. |
422 |
unknown_agent |
Nobody in Team has that code or that name. |
What to do with each one
Section titled “What to do with each one”Request errors: 400, 413, 415
Section titled “Request errors: 400, 413, 415”The request is wrong and will still be wrong if you repeat it unchanged. Do not retry it: fix what you send.
bad_requesthas two causes. The first is sending the file as the body of the request instead of inside a form. The second is a request of 20 MB or more: that is the limit of the API, and above it the form is never read. If the error only appears with long recordings, this is the cause, and the fix is to compress the audio.no_filemeans the form arrived correctly but without a file. The field has to be named exactlyfile.empty_fileis a file of zero bytes. If you get it, check that your system is not sending the recording before it has finished writing it to disk.not_audiomeans the file does not declare anaudio/…type and its name does not end in an audio extension. Check how your system names the file inside the form.file_too_largemeans the file fits in a request but is larger than the per-file maximum of your plan. The fix is to compress the audio: for speech, mono MP3 at 64 kbps is enough.
No agent, or not on the team: 422
Section titled “No agent, or not on the team: 422”Every call belongs to an agent in Team. Retrying the same request does not help.
agent_required: sendagent_codeoragent_name, or have the file name carry the agent’s code.unknown_agent: add the agent in Team, with the same code your telephony system uses, and send the recording again. If the team already takes every seat of the plan, a free seat is needed first.
Invalid key: 401
Section titled “Invalid key: 401”Check that the header is Authorization: Bearer ck_…, with a space after Bearer and no quotes or line breaks around the key. If the header is correct, someone may have revoked the key: look at the list in Integrations. Do not retry with the same key.
Account limits: 402
Section titled “Account limits: 402”The request is correct, but the account cannot accept more for now. Retrying right away does not help.
no_minutesclears on its own when the next period starts, or when the limits of the account are raised.storage_fulldepends on the plan. On the free plan, storage counts everything uploaded and deleting calls does not give it back: it takes another plan, or a higher limit for the account. On the others it clears when you delete old calls in the app. See Plan and limits.
The sensible thing to do is stop sending, tell whoever manages the account and keep the pending recordings to send them later. Usage and limits are in Settings → Plan & Usage, and are explained in Plan and limits.
Failures on our side: 5xx and dropped connections
Section titled “Failures on our side: 5xx and dropped connections”A 500, a 502, a 503 or a connection that drops without a response points to a problem on our side or along the way. These are the ones to retry:
- Wait before you repeat the request, and wait longer on each attempt: 5 seconds, 30 seconds, 2 minutes.
- Always send the same
external_id. If the first request did arrive, the second one does not duplicate the call. - After several failed attempts, leave the recording in a queue for later instead of continuing to retry.
Summary
Section titled “Summary”| Codes | What to do | |
|---|---|---|
| Do not retry | 400, 401, 413, 415 |
Fix the request or the key. |
| Wait | 402 |
Stop, tell someone and resume when the account has room. |
| Retry | 5xx, no response |
With increasing waits and the same external_id. |
The order of the checks
Section titled “The order of the checks”If a request has several problems, you see the first one in this list:
- The key (
unauthorized). - The format of the body (
bad_request) and the presence of the file (no_file). - That the file is audio (
not_audio) and is not empty (empty_file). - Whether the
external_idalready exists: in that case the response is200and nothing else is checked. - The agent (
agent_required,unknown_agent). - The size (
file_too_large), the storage (storage_full) and the minutes (no_minutes).