# Modelo de Tarefa Assíncrona — Estados de Processamento de Documentos e Lotes

> Como o processamento assíncrono de documentos e lotes funciona na API v1 — a máquina de estados enfileirado/processando/sucesso/falha/cancelado e a cadeia de timestamps created_at/started_at/completed_at.

Fazer upload de um documento não o processa, e iniciar o processamento não o conclui na mesma requisição. Cada documento e lote passa por um conjunto fixo e fechado de status — esta página cobre esse ciclo de vida do início ao fim.

## Ciclo de vida dos status

Cada documento (e, de forma agregada, cada lote) está sempre exatamente em um de cinco estados:

```text
enfileirado → processando → sucesso | falha | cancelado
```

- `queued` — enviado e/ou aguardando um worker pegá-lo.
- `processing` — um worker assumiu o documento e está extraindo dados ativamente.
- `succeeded` — extração concluída; o campo `line_items` na resposta de resultados está preenchido.
- `failed` — a extração não pôde ser concluída para este documento (é um resultado *em nível de documento*, não um erro de chamada de API — veja a nota sobre `processing_error` em [Tratamento de Erros](/developers/guides/errors)).
- `canceled` — o documento foi removido da fila antes do processamento começar (por exemplo, seu lote foi excluído enquanto ainda estava `queued`).

Este conjunto de cinco valores é um contrato público, deliberadamente desacoplado de quaisquer estados internos que o sistema use nos bastidores. Novos estados intermediários internos podem ser introduzidos posteriormente sem nunca adicionar um sexto valor aqui — toda resposta v1 que você analisa hoje continuará funcionando.

## A cadeia de timestamps

Tanto as respostas de documento (`GET /documents/{id}`) quanto de lote (`GET /batches/{batch_name}/results`) trazem os mesmos três campos, permitindo distinguir entre "na fila mas travado", "em execução ativa" e "genuinamente concluído":

| Campo | Definido quando |
| --- | --- |
| created_at | O documento foi enviado (ou, para um lote, o envio mais antigo dentro dele). |
| started_at | Um worker assumiu o documento e começou a processá-lo. Permanece null enquanto o status ainda for queued . |
| completed_at | O documento atingiu um estado terminal — succeeded , failed ou canceled . Permanece null enquanto ainda estiver queued ou processing . No nível do lote, permanece null até que todos os documentos do lote tenham um — um lote com qualquer documento ainda em andamento não está "concluído", mesmo que alguns de seus documentos já tenham terminado. |

## Polling vs. webhooks

Você tem duas maneiras de saber quando um lote está concluído:

- **Polling** — chame `GET /batches/{batch_name}` periodicamente e verifique `all_done`. Simples, sem necessidade de infraestrutura da sua parte, mas desperdiça requisições se você fizer polling agressivamente demais (veja [Limites de Taxa](/developers/guides/rate-limits) para o teto de 120/minuto nos endpoints de status) ou lentamente demais (latência adicional antes de perceber a conclusão).
- **Webhooks** — registre uma URL de callback uma vez com `PUT /batches/{batch_name}/webhook` e seja notificado no momento em que o lote terminar, em vez de perguntar repetidamente. Consulte o guia de [Webhooks](/developers/guides/webhooks) — ele também cobre o que acontece se você adicionar mais documentos a um lote e processá-lo novamente depois que ele já notificou você uma vez (resumo: você é notificado novamente automaticamente, sem necessidade de registro extra).

Para um único lote pequeno processado uma vez, fazer polling algumas vezes é o mais simples. Para qualquer coisa de maior volume, ou onde você não queira um loop de requisições parado esperando, webhooks são a melhor opção.

---

Source: https://imagetotable.ai/pt/developers/guides/async-model
