# Errors (/api/errors)

Every error has the same shape:

```json
{
  "error": {
    "type": "billing_error",
    "code": "insufficient_balance",
    "message": "This needs $0.51 and the API wallet has $0.18 free. Add money in Settings › Developers.",
    "param": null,
    "doc_url": "https://docs.taad.app/api/errors#insufficient-balance",
    "request_id": "req_06F8Q3W1ZJ4K2M9N7P5R3T1V0X"
  }
}
```

Act on `code`; show `message` to a person; quote `request_id` if you write to us. Some errors carry more fields, listed below.

## Your key [#your-key]

### `missing_key` [#missing-key]

`401`. No key. Send it as `Authorization: Bearer taad_…`.

### `malformed_key` [#malformed-key]

`401`. That isn't a Taad key: it doesn't start with `taad_` or `taadtest_`, it was cut short when copied, or it was changed. Copy it again whole.

### `unknown_key` [#unknown-key]

`401`. We don't know this key: it was rolled (and the old one's time is up), or it belongs somewhere else. Roll or make a key in Settings › Developers.

### `revoked_key` [#revoked-key]

`401`. This key was revoked. Make a new one.

### `expired_key` [#expired-key]

`401`. This key reached its expiry date. Make a new one.

### `missing_scope` [#missing-scope]

`403`. The key can't do this; `scope` names what it needs. Make a key with it.

### `read_only_key` [#read-only-key]

`403`. The key only reads.

### `browser_not_allowed` [#browser-not-allowed]

`403`. The call came from a web page. Keys must stay on your server: call the API from there.

### `key_in_url` [#key-in-url]

`400`. A key was in the URL. URLs end up in logs: send it in the `Authorization` header, and roll that key.

### `api_paused` [#api-paused]

`403`. We paused the API for this account. Write to us.

## Money [#money]

### `payment_required` [#payment-required]

`402`. The API needs a paid plan or money in the API wallet (for an organization: paid seats or money in its wallet). Your keys are kept and work again once that's true.

### `insufficient_balance` [#insufficient-balance]

`402`. This paid call needs more than the API wallet has free. `needed_usd` and `available_usd` say how much. Add money in Settings › Developers.

### `key_cap_reached` [#key-cap-reached]

`402`. This key has spent its weekly cap (`weekly_cap_usd`). Raise it in Settings, or wait until `resets_at`.

## Your request [#your-request]

### `invalid_request` [#invalid-request]

`400`. Something in the request isn't right; `param` names the field and the message says why.

### `not_found` [#not-found]

`404`. No such thing, or it's outside what this key reaches (another workspace, or deleted).

### `livemode_mismatch` [#livemode-mismatch]

`404`. A sandbox id sent with a live key, or the other way round.

### `not_ready` [#not-ready]

`409`. The recording is still being transcribed; try again after `retry_after` seconds, or wait for `recording.ready`.

### `duplicate_reference` [#duplicate-reference]

`409`. Another recording in this workspace already has this `client_reference_id`; its id is in the error.

### `limit_reached` [#limit-reached]

`409`. You've reached a limit (webhook endpoints, for instance); the message says which.

### `version_conflict` [#version-conflict]

`412`. It changed since the version you sent in `If-Match`. Read it again, then retry.

### `cursor_expired` [#cursor-expired]

`410`. That events cursor is older than 30 days. Start again from `GET /v1/recordings?updated_after=…`.

### `file_too_large` [#file-too-large]

`413`. Too big: a file sent in the request is at most 90 MB, a file fetched from an `audio_url` at most 200 MB.

### `too_long` [#too-long]

`413`. The audio is longer than four hours, the most we take in one recording.

### `unsupported_media_type` [#unsupported-media-type]

`415`. We can't take this kind of file. Audio (MP3, M4A, AAC, WAV, FLAC, Ogg, WebM) and video (MP4, WebM) work.

### `unreadable_audio` [#unreadable-audio]

`422`. The file couldn't be read as audio.

### `unprocessable` [#unprocessable]

`422`. The request was understood but can't be done as it is; the message says why.

### `unsafe_url` [#unsafe-url]

`400`. The address isn't one we'll call: it must be `https` and reachable from the internet.

## Retrying [#retrying]

### `idempotency_key_reused` [#idempotency-key-reused]

`409`. This `Idempotency-Key` was used with a different request. Use a new key.

### `request_in_progress` [#request-in-progress]

`409`. The first request with this `Idempotency-Key` is still running. Try again in a moment.

### `rate_limited` [#rate-limited]

`429`. Too many requests. Wait `Retry-After` seconds.

### `queue_full` [#queue-full]

`429`. Too much audio is waiting to be transcribed. Wait `Retry-After` seconds and send it again.

## Ours [#ours]

### `internal` [#internal]

`500`. Something went wrong on our side. Try again; if it keeps happening, write to us with the `request_id`.

### `unavailable` [#unavailable]

`503`. That call isn't available right now. Try again in a moment.
