# API Error Handling — Error Types, Codes & doc_url

> Every v1 error is a JSON object with type, code, message, and doc_url — this page documents the full error type taxonomy and every individual error code, and is exactly what a returned doc_url links back to.

Every failed v1 request — every non-2xx response — returns the same JSON shape, listed in full below. This page is also what every error's `doc_url` links to: each code has its own anchored section, so following a `doc_url` from an actual error response lands you directly on the explanation for that exact code.

## The error shape

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "missing_parameter",
    "message": "A required parameter is missing.",
    "doc_url": "https://imagetotable.ai/developers/guides/errors#missing_parameter",
    "param": "file"
  }
}
```

- `type` — the broad category this error falls into (see the table below). Useful for coarse branching in your error-handling code ("is this an auth problem or a validation problem") without checking every individual `code`.
- `code` — the specific, stable error identifier. This is what you should match on in code — it won't change even if `message`'s wording is improved later.
- `message` — a human-readable explanation. Useful for logs and debugging, not meant to be parsed.
- `doc_url` — a direct link to this page's section for that exact `code`.
- `param` — present only on validation-style errors (`missing_parameter`, `invalid_parameter`, `duplicate_field_name`), naming the specific request field that caused the error. Omitted entirely — not `null` — when not applicable.

## Error types

Every `code` belongs to exactly one `type`:

| Type | Meaning |
| --- | --- |
| authentication_error | Something is wrong with how (or whether) you authenticated the request. |
| invalid_request_error | The request itself is malformed — a missing or invalid parameter. |
| not_found_error | The resource referenced in the URL (a document, batch, or template ID) doesn't exist, or doesn't belong to your account. |
| insufficient_credits | Your account doesn't have enough credits to perform the requested (paid) action. |
| rate_limit_error | You've exceeded the request rate for this endpoint category — see Rate Limits . |
| internal_error | Something went wrong on our end, not yours. |

## A special case: `processing_error`

`processing_error` is **not** a `type` you'll ever see in a top-level `{"error": ...}` response. It never causes an API call itself to fail. Instead, it describes a single document within a batch that could not be extracted — you'll see it reflected as `"status": "failed"` on that one document inside an otherwise-200-OK `GET /batches/{batch_name}/results` response, alongside documents in the same batch that succeeded fine. Don't treat a document-level failure inside a successful API call as an error to retry the whole batch over — check each document's own `status`.

## Error codes

### missing_api_key

**Type:** `authentication_error` · **HTTP status:** 401

No API key was provided. Send it as `Authorization: Bearer <key>`.

### invalid_api_key

**Type:** `authentication_error` · **HTTP status:** 401

The API key provided is invalid, or the account it belongs to is disabled.

### plan_required

**Type:** `authentication_error` · **HTTP status:** 403

The API is not available on the Free plan. Upgrade to Basic or higher to use it.

### missing_parameter

**Type:** `invalid_request_error` · **HTTP status:** 400

A required parameter is missing. Check `param` on the error object for which one.

### invalid_parameter

**Type:** `invalid_request_error` · **HTTP status:** 400

A parameter has an invalid value. Check `param` and `message` for specifics — this is a catch-all code covering everything from a malformed `crop` string to an out-of-range `limit` to a batch with nothing eligible to process.

### duplicate_field_name

**Type:** `invalid_request_error` · **HTTP status:** 400

A field with this name already exists on this template. Field names must be unique within a template.

### idempotency_key_reused

**Type:** `invalid_request_error` · **HTTP status:** 400

This `Idempotency-Key` was already used for a request with different parameters. Use a new key for a genuinely different request — see [Idempotency](/developers/guides/idempotency) for the full behavior.

### document_not_found

**Type:** `not_found_error` · **HTTP status:** 404

No document was found with the given ID (either it doesn't exist, or it doesn't belong to your account).

### batch_not_found

**Type:** `not_found_error` · **HTTP status:** 404

No batch was found with the given name.

### template_not_found

**Type:** `not_found_error` · **HTTP status:** 404

No template was found with the given ID.

### insufficient_credits

**Type:** `insufficient_credits` · **HTTP status:** 402

Not enough credits to perform this action. Check `GET /account` for your current `available_credits` before retrying.

### rate_limit_exceeded

**Type:** `rate_limit_error` · **HTTP status:** 429

Too many requests. Slow down and retry after the window resets — see the `X-RateLimit-Reset` response header and the [Rate Limits](/developers/guides/rate-limits) guide.

### internal_error

**Type:** `internal_error` · **HTTP status:** 500

An unexpected error occurred. If this persists, it's on us, not you — if you can reproduce it reliably, that's useful information to include if you reach out about it.

---

Source: https://imagetotable.ai/developers/guides/errors
