# Referência da API de Lotes — Iniciar, Exportar e Excluir

> Inicie a extração em um lote de documentos enviados, liste e filtre seus lotes, consulte o status agregado, obtenha resultados JSON reorganizados, exporte para Excel/Word e exclua lotes para a API v1 do ImageToTable.ai.

Um **lote** é um grupo nomeado de um ou mais [Documentos](/developers/reference/documents) que você processa, consulta e obtém resultados em conjunto. Você não cria um lote explicitamente — ele é criado implicitamente na primeira vez que você envia um documento com esse `batch_name` (consulte [Enviar um documento](/developers/reference/documents#upload-a-document)).

## Iniciar processamento de um lote

Inicia a extração em todos os documentos elegíveis atualmente no lote (qualquer um que ainda não esteja `processing` ou `succeeded`). Este é o endpoint que realmente consome créditos — um por documento na fila.

`POST /api/v1/batches/{batch_name}/process`

### Parâmetros

| Nome | Local | Tipo | Descrição |
| --- | --- | --- | --- |
| batch_name | path | string | O lote a ser processado. |
| template_id | body (JSON) | integer, opcional | Um modelo salvo a ser aplicado. Tem prioridade sobre fields se ambos forem fornecidos. |
| fields | body (JSON) | array, opcional | Lista de campos ad-hoc apenas para esta execução — [{"name": "...", "format_requirement": "..."}] ou um array simples de strings de nome. Ignorado se template_id for fornecido. Omita ambos para deixar o modelo inferir as colunas por conta própria. |
| quality | body (JSON) | string, opcional | "fast" ou "high" . Omita para usar a configuração thinking_type da sua conta — consulte Configurações da Conta e Comportamento da API . |
| webhook_url | body (JSON) | string, opcional | Registra (ou atualiza) o callback de conclusão deste lote na mesma chamada — equivalente a também chamar Registrar um webhook de lote . Deve ser http:// ou https:// . |
| Idempotency-Key | header, opcional | string | Fortemente recomendado — este endpoint deduz créditos. Consulte Idempotência . |

`quality` é a única configuração da conta que a API permite sobrescrever por chamada — todas as outras preferências de nível de conta (anotação automática de bbox, política de retenção) são lidas da sua conta e não podem ser sobrescritas por requisição. Consulte [Configurações da Conta e Comportamento da API](/developers/guides/account-settings) para o panorama completo, incluindo por que `auto_annotate_bbox` pode fazer com que esta chamada também cobre pela anotação de bbox, mesmo que você nunca tenha chamado aquele endpoint.

**O campo `webhook_registered` da resposta reflete apenas esta chamada específica** — ele é `true` se e somente se *esta* requisição incluiu `webhook_url`, e não se o lote tem um webhook ou não. Um lote cujo webhook foi configurado anteriormente via [Registrar um webhook de lote](/developers/reference/webhooks) (e não repetido aqui) disparará corretamente seu callback ao ser concluído, mas este campo ainda retorna `false` para aquela chamada — ele não verifica se um `BatchWebhook` já existe. Não trate um `false` aqui como "nenhum webhook será disparado para este lote."

Chamar este endpoint novamente em um lote que você já processou e foi notificado — após fazer upload de mais documentos nele — rearma automaticamente o webhook desse lote se ele já tiver sido disparado, para que a conclusão da nova leva também notifique. Nenhuma chamada extra é necessária para que isso aconteça; consulte a seção "Reprocessando um lote" do [guia de Webhooks](/developers/guides/webhooks#reprocessing-a-batch) para a semântica exata (incluindo o que acontece se duas levas se sobrepuserem).

### Erros possíveis

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Tratamento de Erros](/developers/guides/errors).
- `batch_not_found` — não existem documentos sob este `batch_name` na sua conta.
- `invalid_parameter` — valor inválido de `quality`/`webhook_url`/`template_id`, ou nenhum documento no lote está atualmente elegível para processamento (todos já concluídos/em processamento, ou o lote está vazio).
- `template_not_found`
- `insufficient_credits` — créditos disponíveis insuficientes para cobrir os documentos sendo enfileirados.

## Listar lotes

Retorna uma lista paginada e filtrável de resumos dos seus lotes — o equivalente ao "Files Filter" para consumidores da API. Retorna apenas resumos (`document_count`, `status` agregado); use [Obter resultados do lote](#get-batch-results) para obter os dados completos por documento de um lote específico.

`GET /api/v1/batches`

### Parâmetros

| Nome | Localização | Tipo | Descrição |
| --- | --- | --- | --- |
| source | query, opcional | string | Um dos valores: direct , collect , email_inbox , api (enviado via POST /documents , diferente de direct que é o web app principal) ou share (um alias que cobre tanto collect quanto email_inbox ). Omita para todas as origens. |
| q | query, opcional | string | Correspondência de substring sem diferenciação de maiúsculas/minúsculas nos nomes de arquivos dentro do lote. |
| date_from | query, opcional | string ( YYYY-MM-DD ) | Limite inferior inclusivo para o horário de upload. |
| date_to | query, opcional | string ( YYYY-MM-DD ) | Limite superior inclusivo para o horário de upload (final do dia). |
| status | query, opcional | string | Lista separada por vírgulas de status públicos ( queued,processing,succeeded,failed,canceled ) para filtrar. |
| template_id | query, opcional | integer | Apenas lotes que usaram este modelo. |
| mode | query, opcional | string | O único valor aceito nesta versão é "table" (o único modo que v1 suporta atualmente). Reservado para futuros modos de extração. |
| limit | query, opcional | integer | 1–100. Padrão 20. |
| page_token | query, opcional | string | Cursor opaco de um next_page_token de resposta anterior. Veja Paginação . |

### Erros possíveis

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Tratamento de Erros](/developers/guides/errors).
- `invalid_parameter` — `mode`, `limit`, `status` ou `page_token` inválidos.

## Obter status do lote

Status agregado leve de um lote — contagens por status público mais uma flag `all_done`, útil para um loop de polling barato que ainda não precisa do payload completo de resultados.

`GET /api/v1/batches/{batch_name}`

### Parâmetros

| Nome | Localização | Tipo | Descrição |
| --- | --- | --- | --- |
| batch_name | path | string | O lote a verificar. |

### Erros possíveis

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Tratamento de Erros](/developers/guides/errors).
- `batch_not_found`

## Obter resultados do lote

A principal forma de recuperar dados extraídos. Cada documento no lote é retornado com seus `line_items` remodelados — um array de objetos `{field_name: value}`, um por linha extraída. Por padrão, os valores dos campos são escalares simples (string, número, etc.).

`GET /api/v1/batches/{batch_name}/results`

### Parâmetros

| Nome | Localização | Tipo | Descrição |
| --- | --- | --- | --- |
| batch_name | path | string | O lote para buscar resultados. |
| include | query, opcional | string | "bbox" — quando definido, cada valor de campo se torna {"value": ..., "bbox": {...}|null} em vez de um escalar simples, e cada documento recebe um campo bbox_status . Veja abaixo — isso nunca dispara um novo job de bbox, apenas retorna o que já foi computado. |

`?include=bbox` lê apenas resultados retroalimentados — ele não chama [Disparar anotação de bbox](/developers/reference/documents#trigger-bbox-annotation) por você. Se o bbox nunca foi disparado para um documento (manualmente ou pela configuração `auto_annotate_bbox` da sua conta), os campos desse documento simplesmente retornam com `"bbox": null`.

**Campos de localização pura são um terceiro formato distinto.** Alguns campos de modelo pedem ao modelo para localizar algo em vez de transcrever texto (ex.: "localize a foto do retrato"). Para esses campos, o valor inteiro *é* uma localização — então, em vez de um escalar ou do par `{"value","bbox"}` acima, você recebe `{"type": "image_region", "bbox": {...}, "image_url": "..."}`, **independentemente de `?include=bbox` estar definido** — a caixa não é metadado opcional aqui, é o único conteúdo do campo. `image_url` aponta para um JPEG recortado pronto para download (veja [Obter imagem de um documento](/developers/reference/documents#get-a-document-image)) para que você não precise recortar o original a partir de quatro números.

Cada objeto `bbox` — em qualquer formato — usa `"unit": "normalized"`: as coordenadas são floats de 0 a 1 relativos à largura/altura da página, não pixels nem uma escala de 0 a 1000. Consulte o guia [Bounding Boxes](/developers/guides/bbox) para a ressalva de precisão — essas coordenadas vêm diretamente do modelo sem uma verificação de precisão em nível de pixel, portanto, trate-as como "aproximadas" em vez de exatas em documentos densos ou complexos.

### Erros possíveis

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Error Handling](/developers/guides/errors).
- `batch_not_found`

## Exportar um lote

Um download de conveniência — `results` acima é o formato canônico e estruturado para o qual esta API foi projetada; este endpoint existe para extrair os mesmos dados para uma planilha sem que você precise escrever código de remodelação por conta própria. Apenas xlsx — v1 suporta apenas o modo tabela (extração), e a exportação para Word (docx) no aplicativo principal é exclusivamente a saída nativa do modo page_word (um prompt e formato de resultado totalmente diferentes), que v1 não expõe. Não há opção de "dados de tabela como um documento Word" aqui.

`GET /api/v1/batches/{batch_name}/export`

### Parâmetros

| Nome | Localização | Tipo | Descrição |
| --- | --- | --- | --- |
| batch_name | path | string | O lote a ser exportado. |
| format | query, opcional | string | Apenas xlsx (o padrão) é aceito. |

A resposta é um download de arquivo (`Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`), não JSON — não há exemplo de resposta JSON para este endpoint.

### Possíveis erros

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Tratamento de Erros](/developers/guides/errors).
- `batch_not_found`
- `invalid_parameter` (`param: "format"`) — qualquer valor diferente de `xlsx`.

## Excluir um lote

Exclui permanentemente todos os documentos do lote. Qualquer documento ainda `queued` é reembolsado antes da exclusão. Isso também remove o registro de webhook do lote (se houver) e quaisquer jobs de anotação de bbox vinculados aos seus documentos.

`DELETE /api/v1/batches/{batch_name}`

### Parâmetros

| Nome | Localização | Tipo | Descrição |
| --- | --- | --- | --- |
| batch_name | path | string | O lote a ser excluído. |

### Possíveis erros

- `missing_api_key` / `invalid_api_key` / `plan_required` — consulte [Tratamento de Erros](/developers/guides/errors).
- `batch_not_found` — diferente de outros recursos, excluir um `batch_name` que não é seu (ou que não existe) retorna 404 aqui, não um no-op silencioso.

## Code Examples

### Iniciar processamento de um lote

POST /api/v1/batches/{batch_name}/process

**cURL**

```bash
curl -X POST https://imagetotable.ai/api/v1/batches/july-invoices/process \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
        "fields": [
          {"name": "invoice_number"},
          {"name": "invoice_date", "format_requirement": "YYYY-MM-DD"},
          {"name": "total_amount"}
        ],
        "quality": "high",
        "webhook_url": "https://example.com/webhooks/imagetotable"
      }'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/batches/july-invoices/process",
    headers={
        "Authorization": f"Bearer {os.environ['API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "fields": [
            {"name": "invoice_number"},
            {"name": "invoice_date", "format_requirement": "YYYY-MM-DD"},
            {"name": "total_amount"},
        ],
        "quality": "high",
        "webhook_url": "https://example.com/webhooks/imagetotable",
    },
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices/process", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    fields: [
      { name: "invoice_number" },
      { name: "invoice_date", format_requirement: "YYYY-MM-DD" },
      { name: "total_amount" },
    ],
    quality: "high",
    webhook_url: "https://example.com/webhooks/imagetotable",
  }),
});
console.log(await response.json());
```

### Resposta

```json
{
  "batch_name": "july-invoices",
  "queued": 3,
  "quality": "high",
  "webhook_registered": true
}
```

### Iniciar processamento — com um modelo salvo

POST /api/v1/batches/{batch_name}/process

A outra das duas formas de especificar o que extrair — `template_id` tem prioridade sobre `fields` se você enviar ambos, e é a escolha mais comum quando você reutiliza a mesma lista de colunas em várias execuções, em vez de declará-la ad-hoc toda vez.

**cURL**

```bash
curl -X POST https://imagetotable.ai/api/v1/batches/july-invoices/process \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"template_id": 42}'
```

**Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://imagetotable.ai/api/v1/batches/july-invoices/process",
    headers={
        "Authorization": f"Bearer {os.environ['API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"template_id": 42},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices/process", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ template_id: 42 }),
});
console.log(await response.json());
```

### Resposta

```json
{
  "batch_name": "july-invoices",
  "queued": 3,
  "quality": "fast",
  "webhook_registered": false
}
```

`quality` aqui é `"fast"` porque foi omitido da requisição e usou a configuração de `thinking_type` da conta, não porque um modelo foi usado — `template_id`/`fields` e `quality` são parâmetros independentes.

### Listar lotes

GET /api/v1/batches

**cURL**

```bash
curl "https://imagetotable.ai/api/v1/batches?status=succeeded&limit=20" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    params={"status": "succeeded", "limit": 20},
)
print(response.json())
```

**Javascript**

```javascript
const url = new URL("https://imagetotable.ai/api/v1/batches");
url.searchParams.set("status", "succeeded");
url.searchParams.set("limit", "20");

const response = await fetch(url, {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### Resposta

```json
{
  "data": [
    {
      "batch_name": "july-invoices",
      "status": "succeeded",
      "document_count": 3,
      "created_at": "2026-07-16T09:12:03+00:00"
    }
  ],
  "has_more": false,
  "next_page_token": null
}
```

### Obter status do lote

GET /api/v1/batches/{batch_name}

**cURL**

```bash
curl https://imagetotable.ai/api/v1/batches/july-invoices \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches/july-invoices",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices", {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### Resposta

```json
{
  "batch_name": "july-invoices",
  "document_count": 3,
  "status_counts": {
    "queued": 0,
    "processing": 0,
    "succeeded": 3,
    "failed": 0,
    "canceled": 0
  },
  "all_done": true,
  "created_at": "2026-07-16T09:12:03+00:00"
}
```

### Obter resultados do lote

GET /api/v1/batches/{batch_name}/results

**cURL**

```bash
curl https://imagetotable.ai/api/v1/batches/july-invoices/results \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches/july-invoices/results",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices/results", {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### Resposta — padrão (sem include)

```json
{
  "batch_name": "july-invoices",
  "status": "succeeded",
  "created_at": "2026-07-16T09:12:03+00:00",
  "started_at": "2026-07-16T09:12:05+00:00",
  "completed_at": "2026-07-16T09:12:14+00:00",
  "documents": [
    {
      "document_id": "8f14e45f-ceea-467e-9de1-a3e9c93a9c95",
      "filename": "invoice_042.jpg",
      "status": "succeeded",
      "created_at": "2026-07-16T09:12:03+00:00",
      "started_at": "2026-07-16T09:12:05+00:00",
      "completed_at": "2026-07-16T09:12:14+00:00",
      "line_items": [
        {
          "invoice_number": "INV-1042",
          "invoice_date": "2026-07-01",
          "total_amount": "1,204.50"
        }
      ]
    }
  ]
}
```

### Obter resultados do lote — com bbox

GET /api/v1/batches/{batch_name}/results?include=bbox

**cURL**

```bash
curl "https://imagetotable.ai/api/v1/batches/july-invoices/results?include=bbox" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches/july-invoices/results",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    params={"include": "bbox"},
)
print(response.json())
```

**Javascript**

```javascript
const url = new URL("https://imagetotable.ai/api/v1/batches/july-invoices/results");
url.searchParams.set("include", "bbox");

const response = await fetch(url, {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### Resposta — `?include=bbox`

```json
{
  "batch_name": "july-invoices",
  "status": "succeeded",
  "created_at": "2026-07-16T09:12:03+00:00",
  "started_at": "2026-07-16T09:12:05+00:00",
  "completed_at": "2026-07-16T09:12:14+00:00",
  "documents": [
    {
      "document_id": "8f14e45f-ceea-467e-9de1-a3e9c93a9c95",
      "filename": "invoice_042.jpg",
      "status": "succeeded",
      "created_at": "2026-07-16T09:12:03+00:00",
      "started_at": "2026-07-16T09:12:05+00:00",
      "completed_at": "2026-07-16T09:12:14+00:00",
      "bbox_status": "succeeded",
      "line_items": [
        {
          "invoice_number": {
            "value": "INV-1042",
            "bbox": {"x1": 0.121, "y1": 0.084, "x2": 0.418, "y2": 0.112, "unit": "normalized"}
          },
          "total_amount": {
            "value": "1,204.50",
            "bbox": null
          },
          "portrait_photo": {
            "type": "image_region",
            "bbox": {"x1": 0.740, "y1": 0.060, "x2": 0.920, "y2": 0.260, "unit": "normalized"},
            "image_url": "https://imagetotable.ai/api/v1/documents/8f14e45f-ceea-467e-9de1-a3e9c93a9c95/image?crop=0.7241%2C0.0426%2C0.9359%2C0.2774"
          }
        }
      ]
    }
  ]
}
```

### Exportar lote

GET /api/v1/batches/{batch_name}/export

**cURL**

```bash
curl "https://imagetotable.ai/api/v1/batches/july-invoices/export?format=xlsx" \
  -H "Authorization: Bearer $API_KEY" \
  -o july-invoices.xlsx
```

**Python**

```python
import os
import requests

response = requests.get(
    "https://imagetotable.ai/api/v1/batches/july-invoices/export",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    params={"format": "xlsx"},
)
with open("july-invoices.xlsx", "wb") as f:
    f.write(response.content)
```

**Javascript**

```javascript
import { writeFile } from "node:fs/promises";

const url = new URL("https://imagetotable.ai/api/v1/batches/july-invoices/export");
url.searchParams.set("format", "xlsx");

const response = await fetch(url, {
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
await writeFile("july-invoices.xlsx", Buffer.from(await response.arrayBuffer()));
```

### Excluir lote

DELETE /api/v1/batches/{batch_name}

**cURL**

```bash
curl -X DELETE https://imagetotable.ai/api/v1/batches/july-invoices \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import os
import requests

response = requests.delete(
    "https://imagetotable.ai/api/v1/batches/july-invoices",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices", {
  method: "DELETE",
  headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
console.log(await response.json());
```

### Resposta

```json
{
  "batch_name": "july-invoices",
  "deleted": 3,
  "canceled": 1
}
```

---

Source: https://imagetotable.ai/pt/developers/reference/batches
