Ao final deste guia, você será capaz de chamar a Batch API da OpenAI para executar milhares de requisições de modelo como um único trabalho assíncrono e recuperar todos os resultados com um desconto de 50%. Você empacotará seus prompts em um arquivo JSONL, enviará um lote, fará pesquisas até que termine e baixará a saída, para então testar cada etapa no Apidog antes de conectá-lo à produção. Se seu trabalho for mais interativo, o caminho síncrono é mais adequado, e você pode testar a API do ChatGPT com Apidog em vez disso.
O que é a Batch API e quando usá-la
A Batch API é um endpoint assíncrono para grandes volumes de chamadas de modelo que podem tolerar um atraso. Em vez de uma requisição HTTP por prompt, você empacota muitas requisições em um único arquivo JSONL, o envia como um único trabalho e faz pesquisas pela conclusão. A OpenAI executa o trabalho fora do horário de pico e retorna cada resultado em um arquivo de saída.
Você obtém dois benefícios concretos. Primeiro, um desconto fixo de 50% nos tokens de entrada e saída em comparação com a API síncrona. Segundo, maior taxa de transferência, já que os trabalhos em lote usam um pool de limite de taxa separado e não competem com seu tráfego ao vivo. A desvantagem é a latência. A OpenAI se compromete a finalizar em até 24 horas; muitos trabalhos terminam mais cedo, mas você não pode contar com isso.
Recorra ao processamento em lote quando o trabalho for offline e em grande volume:
- Classificar ou marcar um backlog de registros
- Gerar embeddings para um corpus inteiro
- Geração de conteúdo em massa (descrições de produtos, resumos, traduções)
- Executar suítes de avaliação ou comparações de modelos sobre um conjunto de dados
Ignore-o para qualquer coisa que um usuário esteja esperando. Interfaces de chat, autocompletar e agentes ao vivo precisam dos endpoints síncronos. Se você estiver gerando muitas configurações de modelo ou agente de uma vez, o processamento em lote combina bem com essa carga de trabalho; veja nosso guia sobre gerar mais de 100 configurações de agente com processamento em lote.
O que você precisa antes de começar
Todo o fluxo abrange dois endpoints, /v1/files e /v1/batches, e quatro etapas. Aqui está a estrutura antes de vermos as chamadas.
| Etapa | Endpoint | O que acontece |
|---|---|---|
| 1. Upload | POST /v1/files |
Envie seu arquivo .jsonl com purpose: "batch", receba um ID de arquivo |
| 2. Criar | POST /v1/batches |
Envie o ID do arquivo com um endpoint e janela de conclusão |
| 3. Pesquisar | GET /v1/batches/{id} |
Verifique o status até que ele indique completed |
| 4. Recuperar | GET /v1/files/{id}/content |
Baixe os resultados via output_file_id |
Para acompanhar, você precisa de uma chave de API da OpenAI exportada como OPENAI_API_KEY, um arquivo JSONL de requisições e uma ferramenta para disparar e inspecionar as chamadas. Cada etapa retorna um objeto sobre o qual você pode fazer asserções, o que torna todo o ciclo de vida fácil de testar.
Etapa 1: construir e fazer upload do arquivo JSONL
Sua entrada é um arquivo JSONL onde cada linha é uma requisição autocontida. Cada linha precisa de quatro campos: um custom_id que você escolhe (para que você possa associar os resultados de volta às entradas), o method (POST), a url (o endpoint de destino como /v1/chat/completions) e um body contendo os parâmetros reais da requisição.
{"custom_id": "req-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'shipping was slow but the product is great'"}]}}
{"custom_id": "req-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'returned it the same day'"}]}}
O custom_id deve ser único dentro do arquivo. Os resultados retornam sem ordem garantida, então esse ID é como você reconecta cada resposta à sua linha de origem. Um único lote pode conter até 50.000 requisições e o arquivo pode ter até 200 MB.
Faça upload para a Files API com o propósito batch:
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F purpose="batch" \
-F file="@requests.jsonl"
A resposta carrega um id de arquivo (algo como file-abc123). Esse é o seu input_file_id para a próxima etapa.
Etapa 2: criar o lote
Agora crie o trabalho. Você passa o input_file_id, o endpoint que você está visando e a completion_window. Atualmente, completion_window aceita um único valor, "24h".
curl https://api.openai.com/v1/batches \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_file_id": "file-abc123",
"endpoint": "/v1/chat/completions",
"completion_window": "24h",
"metadata": {"job": "sentiment-backfill"}
}'
O campo endpoint deve corresponder à url usada dentro das suas linhas JSONL. Os alvos suportados incluem /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions e /v1/moderations, entre outros. O objeto opcional metadata contém até 16 pares de chave-valor, o que é útil para marcar trabalhos que você desejará filtrar posteriormente.
A chamada retorna um objeto de lote. Os campos que mais te interessarão:
{
"id": "batch_abc123",
"object": "batch",
"endpoint": "/v1/chat/completions",
"input_file_id": "file-abc123",
"completion_window": "24h",
"status": "validating",
"output_file_id": null,
"error_file_id": null,
"request_counts": { "total": 0, "completed": 0, "failed": 0 },
"created_at": 1733452800,
"metadata": { "job": "sentiment-backfill" }
}
Etapa 3: pesquisar o status do lote
Um novo lote começa em validating. A partir daí, ele se move por um conjunto de estados documentados. Faça a pesquisa em GET /v1/batches/{batch_id} e leia o campo status.
| Status | Significado |
|---|---|
validating |
O arquivo de entrada está sendo verificado antes do início da execução |
in_progress |
As requisições estão sendo processadas |
finalizing |
A execução terminou e o arquivo de saída está sendo preparado |
completed |
Concluído; os resultados estão prontos para download |
failed |
A validação falhou; nada foi executado |
expired |
A janela de 24 horas foi encerrada antes que todas as requisições terminassem |
cancelling / cancelled |
Você solicitou um cancelamento |
O objeto request_counts (total, completed, failed) fornece o progresso em tempo real enquanto o status está em in_progress. Não há um webhook para aguardar aqui, então fazer pesquisas em um intervalo sensato (a cada poucos minutos, não a cada segundo) é o padrão correto. Você também pode cancelar um trabalho em execução com POST /v1/batches/{batch_id}/cancel se o enviou por engano.
Etapa 4: recuperar a saída
Quando o status indica completed, o objeto do lote carrega um output_file_id. Baixe o conteúdo desse arquivo através da Files API:
curl https://api.openai.com/v1/files/file-output456/content \
-H "Authorization: Bearer $OPENAI_API_KEY" > results.jsonl
A saída é novamente JSONL, uma linha por requisição. Cada linha ecoa o custom_id que você definiu, mais um objeto response contendo o código de status e o corpo. Quaisquer requisições que apresentaram erro aparecem no arquivo referenciado por error_file_id, então verifique ambos. Associe os resultados às entradas pelo custom_id, não pela ordem das linhas.
Considere as compensações de custo e janela
A matemática é simples: você economiza 50% em tokens e aceita um tempo de resposta de até 24 horas. Para um preenchimento retroativo único ou um trabalho noturno, é uma decisão fácil. Para uma funcionalidade no caminho crítico do seu produto, não é.
Algumas notas práticas:
- O desconto se aplica tanto aos tokens de entrada quanto aos de saída, em todos os modelos suportados.
- A janela de 24 horas é um limite máximo, não uma meta. Planeje para o pior cenário; se um trabalho atingir o status
expired, as requisições que foram concluídas ainda serão cobradas e retornadas, e as restantes não. - Trabalhos em lote utilizam um limite de token enfileirado separado, então um lote grande não consumirá os limites de taxa dos quais seu tráfego ao vivo depende. Se você já está atingindo os limites, nosso guia sobre limites de taxa da API GPT e como testá-los aborda o lado síncrono.
- Tokens pela metade do preço ainda podem somar um valor considerável em volume. Acompanhe os gastos por trabalho usando a tag
metadatapara poder atribuir custos posteriormente; aqui está um playbook de atribuição de custos para gastos com OpenAI.
Como testar no Apidog
A Batch API é mais propensa a erros do que uma única chamada de chat, porque os modos de falha estão espalhados por arquivos, formatação JSONL e um loop de pesquisa. Uma linha malformada em um arquivo de 50.000 requisições falha o upload inteiro, e você só saberá quando a validação for executada. Testar os endpoints do ciclo de vida antes de automatizá-los evita essa viagem de ida e volta.
Apidog é uma plataforma de API onde você pode executar cada etapa como uma requisição, encadeá-las e fazer asserções nas respostas. Ele testa e simula os endpoints; não é um SDK da OpenAI. Uma configuração realista se parece com isto:
- Valide o formato JSONL primeiro. Antes de fazer upload de qualquer coisa, confirme se cada linha contém
custom_id,method,urlebody, e quebody.modele as mensagens estão presentes. Capturar um campo ausente localmente é mais barato do que um lote com falha. - Execute o upload multipart. Envie
POST /v1/filescompurpose=batche seu arquivo, então capture oidretornado em uma variável de ambiente. - Crie o lote e faça asserções no objeto. Dispare
POST /v1/batches, então faça a asserção de que ostatusévalidatinge que oendpointcorresponde ao que você enviou. As asserções visuais do Apidog permitem que você verifique esses campos sem escrever scripts. - Pesquise e recupere. Chame
GET /v1/batches/{id}em um loop, faça a asserção quando ostatusse tornarcompleted, então extraia ooutput_file_ide baixe os resultados. - Exercite os caminhos de cancelamento e erro. Envie um arquivo propositalmente quebrado e confirme que você obtém um status
failed, e testePOST /v1/batches/{id}/cancelpara que seu tratamento de erros seja real, e não presumido.
Como o arquivo de saída chega mais tarde, você também pode configurar uma API simulada (mock) que retorna um objeto de lote concluído de exemplo e um arquivo de resultados pré-definido. Isso permite que você construa e teste sua lógica de recuperação e análise sem esperar por um trabalho real de 24 horas e sem queimar tokens durante o desenvolvimento. Quando sua equipe trabalha com especificações primeiro, você também pode gerar uma coleção de testes diretamente de uma especificação OpenAPI e manter os endpoints de lote sob cobertura de regressão em CI.
Perguntas frequentes
Quanto tempo um lote realmente leva?
A OpenAI se compromete a concluir um lote em até 24 horas. Na prática, muitos trabalhos terminam mais rápido, mas a garantia é o limite máximo de 24 horas, então construa seu sistema em torno disso. Se a janela se fechar com o trabalho inacabado, o lote muda para expired e apenas as requisições concluídas são retornadas e cobradas.
Qual é o desconto real e ele é cumulativo?
A Batch API oferece um desconto fixo de 50% em relação aos endpoints síncronos, tanto para tokens de entrada quanto de saída. É a maior alavanca de custo única que a OpenAI oferece para cargas de trabalho offline. Se você está tentando atribuir esse gasto a funcionalidades ou trabalhos, o playbook de atribuição de custos mostra como dividi-lo.
Quais endpoints posso executar em um lote?
Você define o destino tanto na url do JSONL quanto no campo endpoint do lote, e eles devem corresponder. Os destinos suportados incluem /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/completions e /v1/moderations, além de endpoints de imagem e vídeo. Verifique a documentação atual para a lista completa, já que a OpenAI a atualiza ao longo do tempo.
Por que meus resultados estão fora de ordem?
Eles não são ordenados, por design. O JSONL de saída não preserva a ordem das linhas de entrada, e é exatamente por isso que cada requisição precisa de um custom_id único. Associe os resultados às entradas por esse ID. Se duas linhas compartilharem um custom_id, você não poderá distinguir suas respostas de forma confiável.
Conclusão
Você agora tem o fluxo completo: empacote seus prompts em um arquivo JSONL, faça o upload, crie o lote, pesquise o status e recupere a saída, tudo pela metade do custo de token dentro de uma janela de 24 horas. Cada etapa retorna um objeto que você pode verificar, então, uma vez que o formato JSONL e o loop de pesquisa estejam corretos, o restante é mecânico.
Antes de automatizar, execute o ciclo de vida manualmente. Baixe o Apidog para validar seu arquivo de requisição, exercitar os endpoints de upload, criação, pesquisa e cancelamento, e fazer asserções nos campos do objeto de lote para que uma linha malformada nunca lhe custe uma viagem de ida e volta de 24 horas.
