Skip to navigation

Guia de PIX em lote

Pague dezenas ou milhares de PIX a partir de um CSV ou de JSON, com conferência prévia e aceite explícito antes do dinheiro sair.

O PIX em lote resolve o caso em que você tem uma planilha — folha de pagamento, repasse a fornecedores, comissões, reembolsos — e quer pagar tudo de uma vez sem escrever um loop de POST /pix/out. Você sobe as linhas, a API confere chaves, duplicidades, saldo e limites antes de qualquer débito, e só depois do seu aceite explícito cada linha vira um PIX out comum, com os mesmos limites, políticas, webhooks e lançamentos no extrato de PIX Out.

Quando usar lote e quando usar PIX avulso

Use o lote quando as linhas já existem juntas (um arquivo, um fechamento) e você quer um resumo para aprovar e um relatório único no fim. Use POST /pix/out quando o pagamento nasce de um evento isolado e precisa de resposta síncrona. Os dois caminhos geram o mesmo PIX e os mesmos webhooks pix.out.*.

Como funciona

itens INVALID acknowledged: true GET template POST batchesDRAFT POST items/csvPUT items POST reviewREVIEWING → REVIEWED GET items/export?status=invalidcorrigir e reenviar POST dispatchQUEUED → PROCESSING 1 PixOut por itempix.out.completed / failed COMPLETED | PARTIAL_FAILED | FAILEDpix.batch.completed POST receipts (ZIP)GET items/export?status=failed

Três decisões de desenho que valem para toda a superfície:

  • Somente API (M2M). As rotas exigem credencial com escopo pix_out.create (ou api2/write legado). Token de usuário humano não cria nem dispara lote; o Portal e o Internet Banking não expõem essa superfície. Uma credencial só-leitura (read) consegue acompanhar lotes (GET), baixar o modelo e comprovantes, mas não cria, edita nem dispara.
  • Habilitação em dois níveis. A CorpX liga a feature pix_batch no tenant e a seção pixBatch.enabled = true na policy da conta. Sem a primeira a API responde 403 feature_disabled; sem a segunda, 403 pix_batch_account_disabled. Peça a ativação ao seu gerente de conta informando as contas que vão operar em lote.
  • Nada sai sem conferência e aceite. O dispatch exige lote REVIEWED, zero itens inválidos, saldo suficiente e acknowledged: true no corpo. O resumo da conferência existe para ser mostrado a quem aprova.

Pré-requisitos

ItemOnde ver
Credencial M2M com escopo pix_out.create restrita às contas que vão pagarAutenticação
Feature pix_batch no tenant e pixBatch.enabled na policy da conta (ativação CorpX)Políticas
Assinatura de webhook para pix.batch.completed e, se quiser granularidade, pix.out.completed / pix.out.failedWebhooks
Se a conta usa travas ou PIN transacional, os cabeçalhos de cash out no dispatchSegurança da conta

Início rápido

Cinco chamadas levam um arquivo do zero ao pagamento. Nos exemplos, $BASE é https://tenant.api.corpx.com/v1/accounts/{accountId} e os cabeçalhos Authorization: Bearer $TOKEN e X-Tenant-Id estão implícitos.

1

Baixe o modelo

curl "$BASE/pix/batches/template" -o pix-lote-modelo.csv
2

Crie o lote

curl -X POST "$BASE/pix/batches" \
-H "Idempotency-Key: folha-2026-09" \
-H "Content-Type: application/json" \
-d '{"name": "Folha de setembro"}'
# 201 → {"batchId": "pxb_…", "status": "DRAFT", …}
3

Suba as linhas

curl -X POST "$BASE/pix/batches/$BATCH/items/csv" \
-H "Content-Type: text/csv" \
--data-binary @folha-setembro.csv
# 200 com o lote e os itens; 400 com errors[] se alguma linha estiver errada (nada é salvo)
4

Confira

curl -X POST "$BASE/pix/batches/$BATCH/review" # 202, status REVIEWING
curl "$BASE/pix/batches/$BATCH" # repita até status REVIEWED; leia "review"
5

Aprove e dispare

curl -X POST "$BASE/pix/batches/$BATCH/dispatch" \
-H "Content-Type: application/json" \
-d '{"acknowledged": true}'
# 202, status QUEUED. Aguarde o webhook pix.batch.completed.

Rotas

Todas sob /v1/accounts/{accountId}/pix/batches. A coluna Escopo indica o que a credencial precisa ter; read acompanha, pix_out.create opera.

Método e rotaEscopoO que faz
GET /templatereadBaixa pix-lote-modelo.csv com as colunas e duas linhas de exemplo.
POST /pix_out.createCria um lote DRAFT. Idempotency-Key obrigatório.
GET /readLista lotes da conta (status, page, pageSize).
GET /{batchId}readLote, review, statistics e itens paginados (status, reviewStatus, page, pageSize).
PUT /{batchId}/itemspix_out.createAdiciona de 1 a 50 itens em JSON.
POST /{batchId}/items/csvpix_out.createAdiciona itens a partir de um CSV (corpo cru, até 5 MiB).
DELETE /{batchId}/items/{itemId}pix_out.createRemove um item.
POST /{batchId}/reviewpix_out.createInicia a conferência assíncrona.
POST /{batchId}/dispatchpix_out.createDispara os pagamentos. Exige acknowledged: true.
GET /{batchId}/items/exportreadCSV de correção (status=failed padrão, invalid, completed, all; separator=comma).
GET /{batchId}/items/{itemId}/receiptreadPDF do comprovante de um item COMPLETED.
POST /{batchId}/receiptspix_out.create ou exports.createJob que gera o ZIP com todos os comprovantes.

A referência campo a campo está em Referência da API → PIX em lote.

1. O arquivo

GET .../pix/batches/template devolve pix-lote-modelo.csv: UTF-8 com BOM e separador ;, que o Excel em português abre direto. O conteúdo é exatamente este:

identifier;amount;description;pixKeyType;pixKey;receiverName;receiverDocument;bankIspb;bankCode;branch;accountNumber;accountType
folha-set-001;1436.85;Pagamento setembro;CPF;12345678909;;;;;;;
folha-set-002;2500.00;Fornecedor;;;EMPRESA EXEMPLO LTDA;12345678000195;60701190;341;0001;123456;CHECKING

Cada linha é um PIX e preenche um dos dois blocos de destinatário:

ColunaRegra
identifierObrigatório. Sua chave de negócio, até 38 caracteres, única no lote e entre os pagamentos vivos da conta (mesma regra do identifier do PIX out). Vira o identifier do pagamento e do extrato.
amountObrigatório e positivo. Aceita 1234.56, 1.234,56 ou R$ 1.234,56.
descriptionOpcional, até 140 caracteres. Vai no PIX como descrição.
pixKeyType, pixKeyModo chave. pixKey liga o modo; pixKeyType (CPF, CNPJ, EMAIL, PHONE, EVP) é opcional e detectado pelo formato. Nome, documento e banco do recebedor são resolvidos no DICT na conferência.
receiverName, receiverDocument, bankIspb, bankCode, branch, accountNumber, accountTypeModo dados bancários. Nome, CPF/CNPJ, ISPB ou código COMPE, agência, conta com dígito e tipo (CHECKING, SAVINGS, PAYMENT, SALARY; vazio = CHECKING).
Regras do parser que evitam retrabalho
  • O cabeçalho é casado por nome, sem importar ordem ou caixa; colunas que você não usa podem ficar vazias ou ser omitidas.
  • ; e , são detectados automaticamente; aspas seguem o padrão CSV.
  • As colunas errorCode e errorMessage do arquivo de correção são ignoradas na entrada: o arquivo exportado sobe de volta como está.
  • Linha com pixKey e dados bancários ao mesmo tempo é rejeitada — escolha um modo por linha.

2. Criar o lote

curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/batches" \
-H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: tenant-suaempresa" \
-H "Idempotency-Key: folha-2026-09" \
-H "Content-Type: application/json" \
-d '{"name": "Folha de setembro"}'
  • Idempotency-Key (até 128 caracteres) é obrigatório; repetir a mesma chave na mesma conta devolve o lote existente com 200 em vez de criar outro. Use algo que identifique o fechamento (folha-2026-09), não um UUID aleatório — assim um retry do seu lado nunca abre lote duplicado.
  • name é opcional (até 120 caracteres) e aparece nas listagens e no resumo.csv dos comprovantes.

Resposta 201:

{
"batchId": "pxb_3f9c2a1b7d4e5f60718293a4b5c6d7e8",
"name": "Folha de setembro",
"status": "DRAFT",
"totalItems": 0,
"totalAmount": "0.00",
"completedItems": 0,
"failedItems": 0,
"limits": { "maxItems": 50, "source": "default" },
"statistics": {
"total": 0, "pending": 0, "processing": 0, "completed": 0, "failed": 0,
"reviewedOk": 0, "invalid": 0,
"totalAmount": "0.00", "validAmount": "0.00", "completedAmount": "0.00", "failedAmount": "0.00",
"progressPercentage": 0
},
"items": [],
"page": 1, "pageSize": 50, "totalPages": 0, "hasNext": false,
"createdAt": "2026-09-30T13:00:00Z",
"updatedAt": "2026-09-30T13:00:00Z"
}

limits.maxItems é o tamanho máximo deste lote nesta conta e limits.source diz de onde veio (default = 50, tenant ou account, até 5.000). Valores monetários são sempre strings decimais com duas casas ("1436.85"), nunca números de ponto flutuante.

3. Enviar os itens

Você pode misturar os dois métodos no mesmo lote, em quantas chamadas precisar, enquanto o lote estiver DRAFT ou REVIEWED.

curl -X POST ".../pix/batches/{batchId}/items/csv" \
-H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: text/csv" \
--data-binary @folha-setembro.csv

O corpo é o arquivo cru (até 5 MiB; acima disso 413). O upload é atômico: se uma linha estiver inválida a resposta é 400 pix_batch_csv_invalid com a lista de problemas e nada é salvo.

{
"errorCode": "pix_batch_csv_invalid",
"message": "one or more rows are invalid; nothing was saved",
"errors": [
{ "line": 3, "field": "amount", "message": "must be a positive amount" },
{ "line": 7, "field": "pixKey", "message": "use either pixKey or the bank account columns, not both" },
{ "line": 9, "field": "identifier", "message": "duplicated identifier (first seen on line 4)" }
],
"docs": "https://docs.api.corpx.com/baas/guias/referencia/erros#pix_batch_csv_invalid"
}

line conta a partir do cabeçalho = linha 1, então 3 é a segunda linha de dados — igual ao que o Excel mostra. Um arquivo com mais linhas que limits.maxItems é 400 pix_batch_too_large.

Regras comuns aos dois métodos

  • Idempotência por linha. Repetir um identifier com o mesmo conteúdo é ignorado (não duplica, não dá erro). Repetir com conteúdo diferente é 409 pix_batch_item_conflict e a chamada inteira é recusada — corrija o arquivo em vez de contar com sobrescrita.
  • Remover. DELETE .../items/{itemId} tira um item; o itemId (pxi_…) vem em items[] do lote.
  • Estados editáveis. Só DRAFT e REVIEWED aceitam itens ou remoção. Qualquer alteração num lote REVIEWED o devolve a DRAFT e zera a conferência: você precisa revisar de novo antes de disparar. Em REVIEWING ou depois do dispatch, 409 pix_batch_not_editable.
  • Tamanho. O total de itens do lote nunca passa de limits.maxItems; a chamada que estouraria o teto é recusada inteira com 400 pix_batch_too_large.

4. Conferir (review)

POST /v1/accounts/{accountId}/pix/batches/{batchId}/review → 202, status REVIEWING

A conferência é assíncrona e roda antes de qualquer débito. Repetir o POST enquanto está REVIEWING só devolve o estado atual. Por item, nesta ordem:

VerificaçãoreviewError.errorCode
Valor positivoinvalid_amount
identifier já usado por um pagamento vivo na conta (inclusive de outro lote)identifier_conflict
Valor acima do limite por operação da contalimit_exceeded_transaction
Chave PIX inexistente, inativa ou malformada (consulta DICT)key_not_found, key_inactive, invalid_pix_key
DICT indisponível após 3 tentativasdict_lookup_failed

No modo chave o DICT resolve nome, documento e banco do recebedor, que passam a aparecer em items[].receiver — é o que você mostra para quem aprova. As consultas usam o cache de 24 h da conta e contam na janela de consultas DICT como GET /pix/key/{pixKey}; leia Consultas de chave PIX antes de conferir milhares de chaves novas. Itens em dados bancários são aceitos como enviados; a validação da conta destino acontece no liquidante, na execução.

Acompanhe com GET .../pix/batches/{batchId}. Quando status vira REVIEWED, review traz o resumo:

{
"reviewedAt": "2026-09-30T13:09:30Z",
"totalItems": 120, "validItems": 118, "invalidItems": 2,
"totalAmount": "143685.00", "validAmount": "141200.00",
"balance": { "available": "150000.00", "sufficient": true, "checked": true },
"limits": [
{ "window": "daily_out", "enforced": true, "limit": "500000.00", "used": "12000.00", "available": "488000.00", "sufficient": true },
{ "window": "monthly", "enforced": false, "limit": "0.00", "used": "0.00", "available": "0.00", "sufficient": true }
],
"warnings": []
}
  • balance e limits são um retrato do momento. O saldo é checado de novo no dispatch e cada PIX passa pelos limites por janela na execução. limits[].window é daily_out (6h–20h) ou nightly_out (20h–6h) conforme a hora da conferência, mais monthly; enforced: false significa que a conta não tem teto configurado naquela janela.
  • balance.checked: false quer dizer que o liquidante não respondeu; o aviso vai para warnings[] e não bloqueia.
  • warnings[] não bloqueia o aceite (ex.: saldo insuficiente agora — pode entrar dinheiro até o dispatch). Itens INVALID bloqueiam.
  • Se a conferência não conseguir rodar, o lote volta a DRAFT e review traz um campo error; basta chamar review de novo.

Um item reprovado fica assim em items[]:

{
"itemId": "pxi_9b1c…", "line": 17, "identifier": "folha-set-017",
"mode": "KEY", "amount": "980.00", "description": "Pagamento setembro",
"status": "PENDING", "reviewStatus": "INVALID",
"receiver": { "name": "", "documentNumber": "", "keyType": "EMAIL", "key": "ex-funcionario@empresa.com", "bankCode": "", "bankIspb": "" },
"reviewError": { "errorCode": "key_not_found", "message": "chave PIX não encontrada no DICT" },
"createdAt": "2026-09-30T13:02:11Z", "updatedAt": "2026-09-30T13:09:28Z"
}

Para corrigir, baixe só as linhas reprovadas, ajuste e suba de novo (o identifier igual com conteúdo novo é recusado — remova o item antes com DELETE, ou use um identifier novo), depois confira outra vez:

GET /v1/accounts/{accountId}/pix/batches/{batchId}/items/export?status=invalid
GET /v1/accounts/{accountId}/pix/batches/{batchId}?reviewStatus=invalid

5. Disparar (dispatch)

curl -X POST ".../pix/batches/{batchId}/dispatch" \
-H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: tenant-suaempresa" \
-H "X-Acting-Document: 12345678909" \
-H "X-Transaction-Pin: 123456" \
-H "Content-Type: application/json" \
-d '{"acknowledged": true}'

acknowledged: true é a declaração de que o resumo da conferência foi lido e aprovado — grave do seu lado quem aprovou e quando. Sem ele a API responde 409 pix_batch_acknowledgement_required. O dispatch ainda exige, nesta ordem:

  1. Lote REVIEWED (409 pix_batch_not_reviewed).
  2. Ao menos um item (409 pix_batch_empty) e total dentro de limits.maxItems (400 pix_batch_too_large).
  3. Nenhum item INVALID e todos conferidos (409 pix_batch_has_invalid_items / 409 pix_batch_not_reviewed).
  4. Saldo disponível maior ou igual ao total do lote no momento do dispatch (422 pix_batch_insufficient_balance — nada é iniciado).
Dispatch movimenta dinheiro

O dispatch é uma rota de cash out: valem as travas de saída da conta, o PIN transacional e os cabeçalhos X-Acting-Document / X-Transaction-Pin / X-Acting-Ip exatamente como em POST /pix/out (ver Segurança da conta). Os cabeçalhos só são necessários se a conta tiver PIN ou travas configurados. Depois do 202 não há cancelamento: os itens já em voo seguem até liquidar ou falhar.

Resposta 202 com status: QUEUED e dispatchedAt. Repetir o dispatch de um lote já disparado é idempotente (200 com o estado atual), então um retry por timeout de rede é seguro.

6. Acompanhar

Cada item vira um PixOut.Workflow próprio — o mesmo que atende POST /pix/out — com identifier igual ao da linha e idempotência {batchId}_{itemId}. Ele passa pelas mesmas políticas, limites por janela e registro no extrato de um PIX avulso, e emite os mesmos pix.out.completed, pix.out.failed ou pix.out.timeout. O lote paga até 5 itens em paralelo (configuração CorpX) e só avança quando o liquidante responde; um item lento não trava os demais.

Estados do lote

statusSignificadoEditável?
DRAFTRecebendo itens.Sim
REVIEWINGConferência em andamento.Não
REVIEWEDConferido; pronto para o aceite. Qualquer edição volta para DRAFT.Sim
QUEUEDDispatch aceito; aguardando o processador.Não
PROCESSINGItens sendo pagos. statistics avança.Não
COMPLETEDTodos os itens liquidaram.Não
PARTIAL_FAILEDAlguns liquidaram, outros falharam. Baixe o export de falhas.Não
FAILEDNenhum item liquidou.Não

Estados do item

statusreviewStatusQuando
PENDINGPENDINGRecém-adicionado, ainda não conferido.
PENDINGOK / INVALIDConferido; INVALID traz reviewError.
PROCESSINGOKPixOut em voo.
COMPLETEDOKLiquidado: paymentId, endToEndId, transactionId, completedAt.
FAILEDOKRecusado ou expirado: error.errorCode e error.message com o vocabulário do PIX avulso (insufficient_funds, limit_exceeded_daily, timeout, …).

GET .../pix/batches/{batchId} traz statistics e os itens paginados (page, pageSize até 200), filtráveis por status (pending, processing, completed, failed) e reviewStatus (pending, ok, invalid):

{
"batchId": "pxb_3f9c2a1b7d4e5f60718293a4b5c6d7e8",
"status": "PROCESSING",
"totalItems": 120, "totalAmount": "141200.00",
"completedItems": 87, "failedItems": 2,
"statistics": {
"total": 120, "pending": 0, "processing": 31, "completed": 87, "failed": 2,
"reviewedOk": 120, "invalid": 0,
"totalAmount": "141200.00", "validAmount": "141200.00",
"completedAmount": "102340.00", "failedAmount": "1960.00",
"progressPercentage": 74.17
},
"items": [
{
"itemId": "pxi_1a2b…", "line": 1, "identifier": "folha-set-001",
"mode": "KEY", "amount": "1436.85", "description": "Pagamento setembro",
"status": "COMPLETED", "reviewStatus": "OK",
"receiver": { "name": "JOAO ANTONIO DA CONCEICAO", "documentNumber": "12345678909", "keyType": "CPF", "key": "12345678909", "bankCode": "341", "bankIspb": "60701190" },
"paymentId": "pay_1f2e3d4c", "endToEndId": "E5087192120260930131200abcdef0123",
"transactionId": "9f8e7d6c-5b4a-4321-8765-43210fedcba9",
"completedAt": "2026-09-30T13:12:01Z",
"createdAt": "2026-09-30T13:02:11Z", "updatedAt": "2026-09-30T13:12:01Z"
}
],
"page": 1, "pageSize": 50, "totalPages": 3, "hasNext": true,
"reviewedAt": "2026-09-30T13:09:30Z",
"acknowledgedAt": "2026-09-30T13:10:02Z",
"dispatchedAt": "2026-09-30T13:10:02Z",
"createdAt": "2026-09-30T13:00:00Z", "updatedAt": "2026-09-30T13:12:01Z"
}

Webhook de fechamento

Ao final a API envia pix.batch.completed. Ele é o fechamento do lote e não substitui os eventos por item: para reconciliar linha a linha use pix.out.completed / pix.out.failed (o identifier do evento é o da sua linha) ou a lista de itens.

{
"id": "pix-batch-pxb_3f9c2a1b7d4e5f60718293a4b5c6d7e8-completed",
"type": "pix.batch.completed",
"occurredAt": "2026-09-30T13:12:40.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-suaempresa",
"accountId": "acc_123456",
"data": {
"batchId": "pxb_3f9c2a1b7d4e5f60718293a4b5c6d7e8",
"accountId": "acc_123456",
"status": "PARTIAL_FAILED",
"statistics": {
"total": 120, "completed": 118, "failed": 2,
"totalAmount": "141200.00", "completedAmount": "139240.00", "failedAmount": "1960.00"
}
}
}

Assine com authType: HMAC, valide X-Signature sobre os bytes brutos e deduplique pelo id — detalhes em Webhooks.

Webhook primeiro, polling como reserva

Prefira reagir a pix.batch.completed. Se precisar de polling (uma barra de progresso, por exemplo), consulte GET .../pix/batches/{batchId} a cada 10–30 s e leia só status e statistics; não liste os itens a cada ciclo.

7. Corrigir e reenviar

GET /v1/accounts/{accountId}/pix/batches/{batchId}/items/export?status=failed

Devolve, no mesmo formato do modelo, só as linhas que falharam na execução ou foram marcadas inválidas na conferência, com duas colunas a mais no fim: errorCode e errorMessage. O cabeçalho X-Total-Rows diz quantas linhas vieram.

identifier;amount;description;pixKeyType;pixKey;receiverName;receiverDocument;bankIspb;bankCode;branch;accountNumber;accountType;errorCode;errorMessage
folha-set-017;980.00;Pagamento setembro;EMAIL;ex-funcionario@empresa.com;;;;;;;;key_not_found;chave PIX não encontrada no DICT
folha-set-044;1200.00;Pagamento setembro;;;MARIA DA SILVA;98765432100;;001;1234;56789-0;CHECKING;limit_exceeded_daily;limite diário de saída excedido

Corrija e suba o arquivo como está em um novo lote — o parser ignora as colunas de erro. Um identifier que falhou pode ser reutilizado; um que liquidou não (a conferência o apontaria como identifier_conflict), o que protege contra pagar duas vezes a mesma linha.

status=Linhas incluídas
failed (padrão)Falharam na execução ou reprovadas na conferência.
invalidSó as reprovadas na conferência (use enquanto o lote está REVIEWED).
completedSó as liquidadas — útil para conciliar com o endToEndId.
allTodas, com errorCode/errorMessage vazios onde não houve erro.

separator=comma troca ; por , para ferramentas em inglês.

8. Comprovantes

Os comprovantes são PDFs no padrão CorpX (logo do tenant quando configurada, pagador, recebedor com documento mascarado, valor, descrição, identifier, endToEndId, data de liquidação em horário de Brasília).

Um item — resposta direta em application/pdf, só para itens COMPLETED (409 pix_batch_receipt_unavailable):

GET /v1/accounts/{accountId}/pix/batches/{batchId}/items/{itemId}/receipt

Lote inteiro — para lotes encerrados (COMPLETED, PARTIAL_FAILED ou FAILED com ao menos um item liquidado; senão 409 pix_batch_no_receipts):

curl -X POST ".../pix/batches/{batchId}/receipts" \
-H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: tenant-suaempresa"
{
"exportId": "exp_7c1d2e3f-…",
"accountId": "acc_123456",
"batchId": "pxb_3f9c2a1b7d4e5f60718293a4b5c6d7e8",
"type": "pix_batch_receipts",
"format": "zip",
"status": "PENDING",
"receipts": 118,
"download": "/v1/accounts/acc_123456/exports/exp_7c1d2e3f-…/download",
"createdAt": "2026-09-30T13:15:00Z"
}

O ZIP é gerado em segundo plano. Chame a rota em download: enquanto o job roda ela responde 409 not_ready; quando termina, devolve downloadUrl pré-assinada (válida por expiresIn segundos) e checksumMd5. O arquivo traz um PDF por item liquidado e um resumo.csv com as colunas linha, identificador, destinatario, valor, endToEnd, data, arquivo e erro (preenchida só se algum PDF não pôde ser gerado).

Os PDFs seguem o padrão {AAAA-MM-DD}_{HHMM}_PIX_{valor}_{destinatario}_{identifier}_{endToEnd}.pdf — por exemplo 2026-09-30_1312_PIX_1436-85_JOAO-ANTONIO-DA-CONCEICAO_folha-set-001_E5087192120260930131200abcdef0123.pdf — sem acentos e com sufixo -2, -3… em caso de colisão.

Boas práticas

  • Uma Idempotency-Key por fechamento. folha-2026-09, fornecedores-2026-09-30… Assim um retry da criação nunca abre um segundo lote, e você consegue reencontrar o lote pelo seu próprio calendário.
  • identifier determinístico e único por linha. Monte-o a partir dos seus dados ({folha}-{matricula}), nunca de um contador em memória. É ele que liga o PIX ao seu sistema no extrato, nos webhooks e no arquivo de correção — e é ele que impede pagar a mesma linha duas vezes.
  • Confira sempre antes de pedir aprovação. Mostre review (totais, saldo, limites, inválidos) a quem aprova e só então envie acknowledged: true. Guarde quem aprovou, quando e o reviewedAt que estava na tela.
  • Separe quem monta de quem dispara. Uma credencial read pode acompanhar; só a credencial com pix_out.create dispara. Se a conta usa PIN transacional, o dispatch exige o PIN do operador que aprova.
  • Trate PARTIAL_FAILED como rotina, não exceção. Chaves excluídas e contas encerradas acontecem em qualquer folha grande. Baixe items/export?status=failed, corrija e suba um novo lote; não refaça o lote inteiro.
  • Reconcilie por identifier e endToEndId. O pix.out.completed de cada item e a linha em items[] trazem os dois; o endToEndId é o comprovante perante o Banco Central.
  • Respeite as janelas de limite. O review mostra daily_out/nightly_out e monthly. Um lote maior que o limite disponível do dia não é bloqueado no dispatch — os itens excedentes falham na execução com limit_exceeded_*. Se for o caso, divida em lotes por dia ou peça ajuste de limite.
  • Lotes grandes. Para milhares de linhas, suba por CSV (uma chamada) em vez de dezenas de chunks JSON, e peça à CorpX o maxItems adequado antes do fechamento.

Perguntas frequentes

Não. Depois do 202 os itens já estão em execução no liquidante. O que você controla é o momento do aceite: até o dispatch o lote é apenas um rascunho e pode ser editado ou simplesmente abandonado em DRAFT/REVIEWED.

Ele volta para DRAFT e todos os itens voltam a reviewStatus: PENDING. Você precisa chamar review de novo. Isso vale para adicionar, remover ou reenviar um item — a conferência sempre reflete o conteúdo atual.

review.balance é um retrato do momento; outro pagamento pode ter saído entre a conferência e o aceite. O dispatch checa o saldo de novo e recusa sem iniciar nada se ele for menor que o total do lote. Reabasteça a conta ou remova linhas e confira novamente.

A conferência valida o que dá para validar sem mover dinheiro: chave, duplicidade, valor, limite por operação, saldo e janelas no agregado. Na execução entram as regras do liquidante e do banco de destino (conta encerrada, limite diário consumido por outros pagamentos, política da conta). O código de erro é o mesmo do PIX avulso e vem em error.errorCode.

Um identifier de item que falhou pode ser usado em um novo lote. Um que liquidou não: a conferência marca identifier_conflict, porque na conta existe um pagamento vivo com esse identificador. Essa é a proteção contra pagamento duplicado — não a contorne gerando sufixos aleatórios.

Sim, como PIX out individuais, com o identifier de cada linha. Não existe um lançamento agregado do lote; GET .../pix/batches/{batchId} e o resumo.csv dos comprovantes são a visão consolidada.

Sim, uma consulta por chave distinta não presente no cache de 24 h da conta, contada na mesma janela de GET /pix/key/{pixKey}. Chaves repetidas no lote e chaves consultadas recentemente não geram nova consulta. Em dados bancários não há consulta ao DICT.

Crie um lote pequeno, suba duas ou três linhas de valor simbólico para contas suas, confira e dispare — o fluxo e os webhooks são idênticos aos de um lote de milhares de linhas. Para validar apenas o arquivo sem pagar nada, pare depois do review: o parser e a conferência já apontam todo problema de formato, chave e duplicidade.

Erros

CódigoHTTPQuando
feature_disabled403Tenant sem a feature pix_batch.
pix_batch_account_disabled403Conta sem pixBatch.enabled = true na policy.
missing_idempotency_key400POST /pix/batches sem Idempotency-Key.
pix_batch_not_found / pix_batch_item_not_found404Lote ou item não existe nesta conta.
pix_batch_chunk_invalid / pix_batch_csv_invalid400Upload rejeitado; errors[] aponta linha e campo. 413 quando o CSV passa de 5 MiB.
pix_batch_too_large400Acima de limits.maxItems.
pix_batch_item_conflict409identifier repetido com conteúdo diferente.
pix_batch_not_editable409Lote em REVIEWING ou já disparado.
pix_batch_empty409Lote sem itens.
pix_batch_not_reviewed409Dispatch sem conferência válida.
pix_batch_has_invalid_items409Conferência marcou itens inválidos.
pix_batch_acknowledgement_required409Dispatch sem acknowledged: true.
pix_batch_insufficient_balance422Saldo disponível menor que o total no dispatch.
pix_batch_no_receipts / pix_batch_receipt_unavailable409Lote não encerrado ou item não liquidado.
receipt_render_failed500Falha ao gerar o PDF; repita a chamada.
workflow_unavailable503Orquestração indisponível; repita a chamada.

A lista completa, com âncoras, está em Tratamento de erros.

Veja também

  • PIX Out — o pagamento avulso que cada linha do lote executa.
  • Consultas de chave PIX — cota e cache do DICT usados na conferência.
  • Segurança da conta — travas, PIN transacional e cabeçalhos de cash out.
  • Idempotência — como a Idempotency-Key se comporta em toda a API.
  • Webhooks — pix.batch.completed e os eventos pix.out.* por item.