---
title: "Processors"
description: "Create, list, update, disable, enable and delete OCR processors, and pin or follow model versions."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ezghcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Processors

A processor is a saved OCR configuration in a project: the model and version to use, the
document languages, the output format and the detail level. You process documents by sending
them to a processor. By default, a project can have up to 50 processors.

## Processor fields

| Field | Description |
| --- | --- |
| `id` | The processor's ID, a UUID. API paths use it. |
| `slug` | A short ID such as `prc_4k2m9x0a7qpe`. |
| `resourceName` | The processor's resource name, used in IAM policies and Trails: `ezgh:us-west-1:org_…:prj_…:prc_…`. It never changes. |
| `organizationId`, `projectId`, `region` | Where the processor is. `region` is `us-west-1`. |
| `name` | 1 to 100 characters, without control characters. Names don't have to be unique. |
| `description` | Up to 2,000 characters. Default: empty. |
| `model` | A model ID from the [catalog](/ocr/models), such as `unlimited-ocr`. |
| `modelVersion` | An exact version, such as `1.0.0`, or `latest`. See [Model versions](#model-versions). |
| `resolvedModelVersion` | The version `modelVersion` resolves to now. |
| `languages` | Language codes from the model's `capabilities.languages`, without duplicates. Default: none. |
| `outputFormat` | `text` or `json-layout`, from the model's `capabilities.outputFormats`. See [Output formats](/ocr/process-documents#output-formats). |
| `options.detail` | A detail level from the model's `capabilities.details`. Default and only value: `high`. |
| `tags` | Up to 50 key-value pairs. Keys are 1 to 128 characters and can't start with `ezgh:`; values are up to 256 characters. |
| `state` | `active` or `disabled`. `status` has the same value. |
| `createdAt`, `updatedAt` | Times, RFC 3339 with milliseconds. |
| `warnings` | Problems with the configured model version, as `{ "code", "message" }`. Usually empty. |

## Create a processor

You need `ocr.processors.create` on the project.

### Console

1. In the [console](https://console.ezghcloud.com), choose the project, open **OCR**, and select
**Processors**.
2. Select **Create processor**.
3. **Model**: enter a **Name**, an optional **Description**, and choose a model.
4. **Version**: choose **Latest** or a specific version.
5. **Output**: choose the **Languages**, the **Output format** (**Text** or **JSON layout**),
and the **Detail**: **High**.
6. **Review**: check the settings and select **Create processor**.
### CLI

```sh
ezgh ocr processors create --name receipts --language en --project web
ezgh ocr processors create --name forms --output-format json-layout --version 1.0.0 --project web
```

| Flag | Sets | Default |
| --- | --- | --- |
| `--name` | `name` (required) | |
| `--description` | `description` | |
| `--model` | `model` | `unlimited-ocr` |
| `--version` | `modelVersion` | `latest` |
| `--language` | `languages` (repeat, or separate with commas) | none |
| `--output-format` | `outputFormat` | `text` |
| `--detail` | `options.detail` | `high` |

`--project` takes a project ID, slug or name. Without it, `ezgh` uses `EZGH_PROJECT` or the
profile's project.
### API

Call [CreateProcessor](/ocr-api/CreateProcessor/). `name`, `model`, `modelVersion` and
`outputFormat` are required.

```sh
curl -X POST \
  -H "Authorization: Bearer $EZGH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name": "Receipts", "model": "unlimited-ocr", "modelVersion": "latest", "languages": ["en"], "outputFormat": "text", "options": {"detail": "high"}}' \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors"
```

The response is `201 Created`, with the processor's path in `Location` and its version in
`ETag`:

```json
{
  "id": "0199a3d0-2b3c-7d4e-9f50-6b7c8d9e0f1a",
  "slug": "prc_4k2m9x0a7qpe",
  "resourceName": "ezgh:us-west-1:org_k3f9a0x2m7qp:prj_g7h8i9j0k1l2:prc_4k2m9x0a7qpe",
  "organizationId": "0199a3c2-5b1e-7d40-9f3a-2c8e6b1d4f70",
  "projectId": "0199a3c2-6c2f-7e51-8a4b-3d9f7c2e5a81",
  "region": "us-west-1",
  "name": "Receipts",
  "description": "",
  "model": "unlimited-ocr",
  "modelVersion": "latest",
  "languages": ["en"],
  "outputFormat": "text",
  "options": { "detail": "high", "detectTables": false, "detectHandwriting": false },
  "tags": {},
  "state": "active",
  "status": "active",
  "createdAt": "2026-09-30T17:02:11.408Z",
  "updatedAt": "2026-09-30T17:02:11.408Z",
  "resolvedModelVersion": "1.0.0",
  "warnings": []
}
```

## List and view processors

### Console

**OCR** > **Processors** lists the current project's processors with their **Model**,
**Output format**, **Detail**, **State** and **Created** time. Select a processor to open its
page, which shows its IDs and state, its **Configuration**, and **Try it**, where you can
process a document.
### CLI

```sh
ezgh ocr processors list --project web
ezgh ocr processors get receipts --project web
```

`get` takes a processor's ID, slug or name.
### API

```sh
curl -H "Authorization: Bearer $EZGH_API_KEY" \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors?limit=20"

curl -H "Authorization: Bearer $EZGH_API_KEY" \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors/$PROCESSOR_ID"
```

[ListProcessors](/ocr-api/ListProcessors/) returns `{ "processors": [...], "nextCursor": ... }`,
newest first. It takes `limit` (1 to 100, default 20) and `cursor` (the previous page's
`nextCursor`). [GetProcessor](/ocr-api/GetProcessor/) returns one processor, with an
`ETag` header.

## Update a processor

[UpdateProcessor](/ocr-api/UpdateProcessor/) (`PATCH`) changes the fields you send and
leaves the others unchanged.

- `languages`, `tags` and `options` are replaced whole. Sending `options` replaces all options:
  any option you leave out returns to its default.
- Changing `model` requires `modelVersion` in the same request.
- `null` values and unknown fields are refused with `400 invalid_request`.
- The configuration (`model`, `modelVersion`, `languages`, `outputFormat`, `options`) is checked
  against the catalog only when one of those fields is in the request. You can rename a
  processor whose configuration is no longer valid.

### Console

On the processor's page, open **Configuration** and select **Edit configuration**. Change the
**Name**, **Description**, **Model**, **Version** or output settings, and select **Save**.
### CLI

```sh
ezgh ocr processors update receipts --name "Receipts (EU)" --language en,zh --project web
```

Flags are the same as `create`. `--language` replaces the languages. `ezgh` sends the ETag it
just read; if the processor changed in between, nothing is changed and you run the command again.
### API

```sh
curl -X PATCH \
  -H "Authorization: Bearer $EZGH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "If-Match: $ETAG" \
  -d '{"languages": ["en", "zh"]}' \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors/$PROCESSOR_ID"
```

The response is `200` with the updated processor and its new `ETag`.

## Disable, enable and delete

A disabled processor refuses documents (`409 processor_disabled`) until you enable it. You can
still read, update and delete it. Enabling checks the configuration against the catalog again
and refuses a retired model version or an option the model no longer offers.

Deleting a processor is permanent. It stops counting toward the project's processor quota.
When a project is deleted, its processors are deleted too.

### Console

On the processor's page, select **Disable**, **Enable** or **Delete**, and confirm.
### CLI

```sh
ezgh ocr processors disable receipts --project web
ezgh ocr processors enable receipts --project web
ezgh ocr processors delete receipts --project web
```

`delete` asks for confirmation; `--yes` skips it.
### API

```sh
curl -X POST -H "Authorization: Bearer $EZGH_API_KEY" \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors/$PROCESSOR_ID/disable"

curl -X POST -H "Authorization: Bearer $EZGH_API_KEY" \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors/$PROCESSOR_ID/enable"

curl -X DELETE -H "Authorization: Bearer $EZGH_API_KEY" \
  "https://ocr.ezghcloud.com/v1/organizations/$ORG_ID/projects/$PROJECT_ID/ocr/processors/$PROCESSOR_ID"
```

[DisableProcessor](/ocr-api/DisableProcessor/) and
[EnableProcessor](/ocr-api/EnableProcessor/) take no body (or `{}`) and return `200` with
the processor; a processor already in that state is returned unchanged.
[DeleteProcessor](/ocr-api/DeleteProcessor/) returns `204`.

## Model versions

`modelVersion` is either:

- **An exact version**, such as `1.0.0`. The processor keeps using it until you change it. If
  the version is deprecated, `warnings` has `model_version_deprecated`. A retired version can't
  be chosen, and a processor pinned to one gets `model_version_retired` and can't process
  documents (`409 model_unavailable`).
- **`latest`**, which follows the model's `latestVersion`. Each request uses the version that is
  latest at that time.

`resolvedModelVersion` shows the version in use now, and each processing result's
`modelVersion` shows the version that produced it.

## Concurrent changes

`GetProcessor`, `CreateProcessor` and every change return an `ETag`. Send it as `If-Match` on
`PATCH`, `DELETE`, `disable` or `enable` to apply the change only if the processor hasn't changed
since you read it. Otherwise the request fails with `412 precondition_failed`; read the processor
again and retry. `If-Match` is optional; `*` matches any version.

## Retries

`CreateProcessor`, `DisableProcessor` and `EnableProcessor` accept an `Idempotency-Key` header
(1 to 200 characters). A retry with the same key and the same request returns the first
response instead of acting again. Keys are kept for at least 24 hours. Reusing a key for a
different request fails with `409 idempotency_conflict`; a retry while the first request is
still running fails with `409 idempotency_in_progress`.

## Errors

| Status | Code | Cause |
| --- | --- | --- |
| `400` | `invalid_request` | A missing, unknown, `null` or invalid field. `issues` lists each problem as `{ "path", "message" }`. |
| `400` | `invalid_cursor` | A cursor from another project, or edited |
| `403` | `access_denied` | The caller lacks the action on the project or processor |
| `404` | `not_found` | The organization, project or processor doesn't exist or you can't see it |
| `401` | `unauthenticated` | Missing or invalid credentials |
| `409` | `quota_exceeded` | The project is at its processor quota (`ocr.processors.count`, 50 by default) |
| `409` | `organization_deletion_pending` | The organization is being deleted |
| `409` | `idempotency_conflict`, `idempotency_in_progress` | See [Retries](#retries) |
| `412` | `precondition_failed` | `If-Match` doesn't match the processor's current `ETag` |
| `429` | `quota_exceeded` | Too many creates in the project (`ocr.processors.createsPerMinute`, 10 per minute by default) |
| `429` | `too_many_requests` | Too many requests. Retry after the `Retry-After` header's seconds |
| `503` | `unavailable` | A dependency is unavailable. Retry after the `Retry-After` header's seconds |

Quota refusals have no `Retry-After` header. See [Pricing and limits](/ocr/pricing-and-limits).

Source: https://docs.ezghcloud.com/ocr/processors/index.mdx
