Consultar Situação do Lote/Carnê
Novo Consulta a situação de todos os boletos de um lote ou carnê em uma única chamada. Cada item de titulos[] traz exatamente o mesmo contrato do Consultar Situação individual — registro, pagamento, baixa, protesto, Pix e dados de conferência — sem que você precise consultar título por boleto.
O que este endpoint faz
Seção intitulada “O que este endpoint faz”- Devolve a situação de todos os boletos de um lote ou carnê em uma chamada.
- Aceita o token do lote ou o
tokenControleUsuarioinformado na criação. - A resposta
200traz o envelopebatch, comboletos[]etitulos[]do mesmo tamanho. - Cada item de
titulos[]segue o contrato da consulta individual, sem o envelopeboleto.
Quando usar
Seção intitulada “Quando usar”Use esta consulta para acompanhar um lote ou carnê inteiro sem pedir a situação boleto a boleto. Cada item repete o contrato da consulta individual. Para o arquivo do lote, use Obter PDF.
Cenários recomendados
Seção intitulada “Cenários recomendados”| Cenário | Recomendação |
|---|---|
| Acompanhar o registro de todos os boletos após criar um lote ou carnê | Sim |
Descobrir quais títulos têm impedimento (registro.erro) em uma chamada |
Sim |
| Conciliar pagamento/baixa das parcelas de um carnê | Sim |
| Exibir um painel do lote (pagos, em aberto, com erro) no seu sistema | Sim |
| Obter o PDF do lote | Não — use Obter PDF |
Onde se encaixa no ciclo de vida
Seção intitulada “Onde se encaixa no ciclo de vida”Depois de criar o lote ou o carnê, esta consulta mostra a situação de todos os títulos; em seguida, obtenha o PDF ou verifique se o lote está pronto.
Pré-requisitos
Seção intitulada “Pré-requisitos”- Token do lote (
batch.token) ou obatch.tokenControleUsuarioinformado na criação - Plano: Personalizado — sem o plano ativo, a rota responde
403com o código8D1C5814
A autenticação é HTTP Basic com a API Key. Veja Autenticação.
Endpoint
Seção intitulada “Endpoint”GET https://sandbox.boletocloud.com/api/v1/batch/boletos/{token}/situacaoGET https://sandbox.boletocloud.com/api/v1/carnes/{token}/situacao
GET https://sandbox.boletocloud.com/api/v1/batch/boletos/controle/{tokenControleUsuario}/situacaoGET https://sandbox.boletocloud.com/api/v1/carnes/controle/{tokenControleUsuario}/situacao- Sandbox Desenvolvimento e testes
https://sandbox.boletocloud.com/api/ v1/ batch/ boletos/ {token}/ situacao https://sandbox.boletocloud.com/api/ v1/ carnes/ {token}/ situacao https://sandbox.boletocloud.com/api/ v1/ batch/ boletos/ controle/ {tokenControleUsuario}/ situacao https://sandbox.boletocloud.com/api/ v1/ carnes/ controle/ {tokenControleUsuario}/ situacao - Produção Operação real
https://app.boletocloud.com/api/ v1/ batch/ boletos/ {token}/ situacao https://app.boletocloud.com/api/ v1/ carnes/ {token}/ situacao https://app.boletocloud.com/api/ v1/ batch/ boletos/ controle/ {tokenControleUsuario}/ situacao https://app.boletocloud.com/api/ v1/ carnes/ controle/ {tokenControleUsuario}/ situacao
A rota é a mesma nos dois ambientes; só o host muda. Em Produção, use a API Key e o token da conta de Produção.
/batch/boletos/...: para lotes criados via POST /batch/boletos./carnes/...: para carnês criados via POST /carnes.- Rota por
{token}: use quando você guarda o token do lote (batch.token) retornado no201da criação — o mesmo usado para obter o PDF. - Rota por
controle/{tokenControleUsuario}: use quando você informoubatch.tokenControleUsuariona criação e quer consultar pelo identificador do seu sistema — inclusive para recuperar a criação após timeout (404= pode reenviar).
As quatro rotas retornam o mesmo contrato JSON (raiz batch). Use sempre a rota da família em que o lote foi criado.
Requisição
Seção intitulada “Requisição”Headers
Seção intitulada “Headers”| Header | Valor | Obrigatório |
|---|---|---|
Accept |
application/json |
Não |
Authorization |
Basic {credenciais} |
Sim |
Parâmetros da URL
Seção intitulada “Parâmetros da URL”| Parâmetro | Tipo | Descrição |
|---|---|---|
token |
string | Token do lote/carnê (batch.token), retornado na criação |
tokenControleUsuario |
string | Valor de batch.tokenControleUsuario informado na criação (rota /controle/); resolve em qualquer caixa |
Exemplos de código
Seção intitulada “Exemplos de código”# Lote (batch)curl "https://sandbox.boletocloud.com/api/v1/batch/boletos/TOKEN_DO_LOTE/situacao" \ -H "Accept: application/json" \ -u "api-key_SUA-API-KEY:token"
# Carnêcurl "https://sandbox.boletocloud.com/api/v1/carnes/TOKEN_DO_CARNE/situacao" \ -H "Accept: application/json" \ -u "api-key_SUA-API-KEY:token"
# Resumo rápido com jq: situação de registro de cada boletocurl -s "https://sandbox.boletocloud.com/api/v1/carnes/TOKEN_DO_CARNE/situacao" \ -H "Accept: application/json" -u "api-key_SUA-API-KEY:token" \ | jq -r '.batch.titulos[] | "\(.tokenControleUsuario // .token): \(.registro.situacao)"'import javax.ws.rs.client.ClientBuilder;import javax.ws.rs.core.Response;import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
public class ConsultaSituacaoLote { public static void main(String[] args) { String tokenLote = "TOKEN_DO_LOTE"; Response response = ClientBuilder.newClient() .target("https://sandbox.boletocloud.com/api/v1/batch/boletos") .path("/" + tokenLote + "/situacao") .register(HttpAuthenticationFeature.basic("api-key_SUA-API-KEY", "token")) .request(APPLICATION_JSON) .get();
if (response.getStatus() == 200) { System.out.println("Situação do lote: " + response.readEntity(String.class)); } else { System.out.println("Erro: " + response.getStatus()); } }}import okhttp3.Credentialsimport okhttp3.OkHttpClientimport okhttp3.Request
fun main() { val tokenLote = "TOKEN_DO_LOTE" val client = OkHttpClient() val credential = Credentials.basic("api-key_SUA-API-KEY", "token")
val request = Request.Builder() .url("https://sandbox.boletocloud.com/api/v1/batch/boletos/$tokenLote/situacao") .header("Authorization", credential) .header("Accept", "application/json") .build()
client.newCall(request).execute().use { response -> if (response.isSuccessful) { println("Situação do lote: ${response.body?.string()}") } else { println("Erro: ${response.code}") } }}using System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Text.Json;using System.Threading.Tasks;
class Program { static async Task Main(string[] args) { var tokenLote = "TOKEN_DO_LOTE"; using var client = new HttpClient(); var credentials = Convert.ToBase64String( Encoding.ASCII.GetBytes("api-key_SUA-API-KEY:token")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync( $"https://sandbox.boletocloud.com/api/v1/batch/boletos/{tokenLote}/situacao");
if (response.IsSuccessStatusCode) { using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); var titulos = doc.RootElement.GetProperty("batch").GetProperty("titulos"); foreach (var titulo in titulos.EnumerateArray()) { var registro = titulo.GetProperty("registro").GetProperty("situacao").GetString(); Console.WriteLine($"{titulo.GetProperty("token").GetString()}: {registro}"); } } else { Console.WriteLine($"Erro: {(int)response.StatusCode}"); } }}const https = require('https');
const tokenLote = 'TOKEN_DO_LOTE';const options = { hostname: 'sandbox.boletocloud.com', path: `/api/v1/batch/boletos/${tokenLote}/situacao`, method: 'GET', auth: 'api-key_SUA-API-KEY:token', headers: {'Accept': 'application/json'}};
const req = https.request(options, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { if (res.statusCode === 200) { const { batch } = JSON.parse(data); console.log(`Lote ${batch.token}: ${batch.total} título(s)`); const pendentes = batch.titulos.filter(t => ['REGISTRO_PENDENTE', 'REGISTRO_EM_PROGRESSO'].includes(t.registro.situacao)); const precisamDeAcao = batch.titulos.filter(t => t.registro.situacao === 'REGISTRO_REJEITADO' && t.registro.erro !== null); console.log(`Aguardando registro: ${pendentes.length}`); console.log(`Precisam de ação: ${precisamDeAcao.length}`); } else { console.log(`Erro: ${res.statusCode}`); } });});
req.end();package main
import ( "encoding/json" "fmt" "net/http")
type situacaoLote struct { Batch struct { Token string `json:"token"` Total int `json:"total"` Boletos []string `json:"boletos"` Titulos []struct { Token string `json:"token"` Registro struct { Situacao string `json:"situacao"` } `json:"registro"` } `json:"titulos"` } `json:"batch"`}
func main() { tokenLote := "TOKEN_DO_LOTE" req, _ := http.NewRequest("GET", "https://sandbox.boletocloud.com/api/v1/batch/boletos/"+tokenLote+"/situacao", nil) req.SetBasicAuth("api-key_SUA-API-KEY", "token") req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close()
if resp.StatusCode == 200 { var s situacaoLote json.NewDecoder(resp.Body).Decode(&s) fmt.Printf("Lote %s: %d titulo(s)\n", s.Batch.Token, s.Batch.Total) for _, t := range s.Batch.Titulos { fmt.Printf("%s: %s\n", t.Token, t.Registro.Situacao) } } else { fmt.Printf("Erro: %d\n", resp.StatusCode) }}<?php$tokenLote = 'TOKEN_DO_LOTE';$url = "https://sandbox.boletocloud.com/api/v1/batch/boletos/$tokenLote/situacao";$api_key = 'api-key_SUA-API-KEY';
$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']);curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);curl_setopt($ch, CURLOPT_USERPWD, "$api_key:token");curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);
if ($http_code == 200) { $batch = json_decode($response, true)['batch']; echo "Lote {$batch['token']}: {$batch['total']} título(s)\n"; foreach ($batch['titulos'] as $titulo) { echo "{$titulo['token']}: {$titulo['registro']['situacao']}\n"; }} else { echo "Erro ($http_code): $response\n";}?>import requestsfrom requests.auth import HTTPBasicAuth
token_lote = 'TOKEN_DO_LOTE'response = requests.get( f'https://sandbox.boletocloud.com/api/v1/batch/boletos/{token_lote}/situacao', auth=HTTPBasicAuth('api-key_SUA-API-KEY', 'token'), headers={'Accept': 'application/json'})
if response.status_code == 200: batch = response.json()['batch'] print(f"Lote {batch['token']}: {batch['total']} título(s)")
TERMINAIS = {'REGISTRO_CONFIRMADO', 'REGISTRO_REJEITADO', 'REGISTRO_NAO_SOLICITADO'} aguardando = [t for t in batch['titulos'] if t['registro']['situacao'] not in TERMINAIS] # REJEITADO com erro: null e supersessao (pago/baixado antes do registro) — sem acao precisam_de_acao = [t for t in batch['titulos'] if t['registro']['situacao'] == 'REGISTRO_REJEITADO' and t['registro']['erro'] is not None]
print(f'Aguardando registro: {len(aguardando)}') for titulo in precisam_de_acao: erro = titulo['registro']['erro'] print(f"Ação necessária em {titulo['token']}: {erro['codigo']} ({erro['origem']})")else: print(f'Erro: {response.status_code}')require 'net/http'require 'uri'require 'json'
token_lote = 'TOKEN_DO_LOTE'uri = URI("https://sandbox.boletocloud.com/api/v1/batch/boletos/#{token_lote}/situacao")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| request = Net::HTTP::Get.new(uri) request.basic_auth('api-key_SUA-API-KEY', 'token') request['Accept'] = 'application/json'
response = http.request(request) if response.code == '200' batch = JSON.parse(response.body)['batch'] puts "Lote #{batch['token']}: #{batch['total']} título(s)" batch['titulos'].each do |titulo| puts "#{titulo['token']}: #{titulo['registro']['situacao']}" end else puts "Erro: #{response.code}" endend(require '[clj-http.client :as client])
(let [token-lote "TOKEN_DO_LOTE" response (client/get (str "https://sandbox.boletocloud.com/api/v1/batch/boletos/" token-lote "/situacao") {:basic-auth ["api-key_SUA-API-KEY" "token"] :accept :json :as :json})] (if (= 200 (:status response)) (doseq [titulo (get-in response [:body :batch :titulos])] (println (:token titulo) "->" (get-in titulo [:registro :situacao]))) (println "Erro:" (:status response))))Resposta
Seção intitulada “Resposta”200 OK — Situação do lote
Seção intitulada “200 OK — Situação do lote”A consulta foi realizada, inclusive quando o lote não tem boletos ativos (total: 0). O body é JSON com a raiz batch.
Headers
Seção intitulada “Headers”| Header | Descrição |
|---|---|
X-BoletoCloud-Token |
Ecoa o token do lote |
Envelope raiz batch nas quatro rotas. Cenário do exemplo: carnê de 2 parcelas — a primeira registrada com PIX disponível, a segunda ainda com registro em progresso e sem encargos definidos.
{ "batch": { "token": "vSD9nA6iTFXhTComVKF-cQoY9Wq5RJkuJoTLPje8zVE=", "tokenControleUsuario": "contrato-456", "total": 2, "boletos": [ "TOKEN_DO_TITULO_1", "TOKEN_DO_TITULO_2" ], "titulos": [ { "situacao": "EM_ABERTO", "token": "TOKEN_DO_TITULO_1", "tokenControleUsuario": "contrato-456-parcela-1", "numero": "12345678901", "documento": "CT-456/1", "valor": 500.00, "emissao": "2026-07-01", "vencimento": "2026-08-01", "pagador": { "nome": "Lucas Mendes", "cprf": "111.111.111-11" }, "multa": { "percentual": 2.00, "valor": null, "diasParaEncargos": 1 }, "juros": { "percentualAoDia": 0.0333, "valorFixoAoDia": null, "diasParaEncargos": 1 }, "descontos": [ { "percentual": 5.00, "valor": null, "dias": 10 } ], "linhaDigitavel": "23790.50004 00000.000000 00000.000000 1 00000000050000", "codigoDeBarras": "23791000000000500005000000000000000000000000", "registro": { "situacao": "REGISTRO_CONFIRMADO", "registrar": true, "data": "2026-07-01", "erro": null, "descricao": null }, "pagamento": null, "baixa": null, "protesto": null, "pix": { "situacao": "PIX_GERADO", "erro": null, "txId": "tx-abc-123", "codigoEMV": "00020126580014BR.GOV.BCB.PIX..." } }, { "situacao": "EM_ABERTO", "token": "TOKEN_DO_TITULO_2", "tokenControleUsuario": "contrato-456-parcela-2", "numero": "12345678902", "documento": "CT-456/2", "valor": 500.00, "emissao": "2026-07-01", "vencimento": "2026-09-01", "pagador": { "nome": "Lucas Mendes", "cprf": "111.111.111-11" }, "multa": null, "juros": null, "descontos": [], "linhaDigitavel": "23790.50004 00000.000000 00000.000000 2 00000000050000", "codigoDeBarras": "23792000000000500005000000000000000000000000", "registro": { "situacao": "REGISTRO_EM_PROGRESSO", "registrar": true, "data": null, "erro": null, "descricao": "Registro enviado ao banco; aguardando processamento." }, "pagamento": null, "baixa": null, "protesto": null, "pix": null } ] }}Campos da resposta
Seção intitulada “Campos da resposta”Campos do Envelope
Seção intitulada “Campos do Envelope”| Campo | Tipo | Descrição |
|---|---|---|
token |
string | Token do lote/carnê na Boleto Cloud |
tokenControleUsuario |
string | null | Token de controle do lote (batch.tokenControleUsuario) informado na criação; null quando não usado |
total |
integer | Quantidade de boletos na resposta — sempre igual ao tamanho de boletos[] e de titulos[] |
boletos[] |
array | Token (string) de cada boleto, alinhado por índice com titulos[] — boletos[i] é o token de titulos[i] |
titulos[] |
array | Situação completa de cada boleto do lote, na ordem vencimento crescente (empate: ordem de criação) |
titulos[] — o contrato é o do individual
Seção intitulada “titulos[] — o contrato é o do individual”Cada item de titulos[] é exatamente o payload do Consultar Situação individual, sem o envelope boleto. Valem as mesmas regras — não redocumentadas aqui de propósito:
- Situação Resumo (
PAGO,BAIXADO,EM_ABERTO); - Política de Nulos (blocos nunca omitidos;
descontossempre lista); - Dados de Conferência (pagador, multa, juros, descontos e suas escalas);
- Bloco
registro(5 estados + erro estruturado com código e origem); - Blocos
pagamento,baixa,protestoepix.
Não há estados novos na visão agregada: o que você já trata no individual, trata igual aqui.
Como interpretar
Seção intitulada “Como interpretar”Níveis de Identificação
Seção intitulada “Níveis de Identificação”Um lote envolve identificadores em níveis diferentes — não os confunda:
| Identificador | Nível | Quem define | Uso |
|---|---|---|---|
batch.token |
Lote | Boleto Cloud | Obter PDF e consultar a situação agregada |
batch.tokenControleUsuario |
Lote | Você | Token de controle do lote: recuperação após timeout e consulta pela rota /controle/ |
titulos[].token |
Título | Boleto Cloud | Operações individuais (segunda via, baixa, situação individual) |
titulos[].tokenControleUsuario |
Título | Você | Correlacionar cada boleto com o seu sistema (Idempotência) |
- Correlacione por
tokenoutokenControleUsuariode cada boleto — nunca pela posição no array. A ordem évencimentocrescente (empate: ordem de criação). Os identificadores são o vínculo confiável com o seu sistema. O invariante dentro de uma resposta está em Campos do Envelope. - Boletos excluídos ficam fora de
boletos[]e detitulos[]juntos, etotalreflete a lista retornada. Um lote cujos boletos foram todos excluídos responde200com o envelope íntegro e as listas vazias — o lote existe, apenas não tem boletos ativos:
{ "batch": { "token": "vSD9nA6iTFXhTComVKF-cQoY9Wq5RJkuJoTLPje8zVE=", "tokenControleUsuario": "contrato-456", "total": 0, "boletos": [], "titulos": [] }}- Retrato por boleto: os títulos da mesma resposta podem refletir momentos diferentes.
| Status | Código | Quando ocorre | O que fazer |
|---|---|---|---|
400 |
— | Token ou chave malformados. | Corrija o token ou o tokenControleUsuario na URL. |
403 |
8D1C5814 |
Conta sem o plano Personalizado ativo. No sandbox, o 403 persiste até a ativação do plano na conta de sandbox. |
Ative o plano Personalizado. Veja Planos & API. |
404 |
— | Lote não existe para a sua conta. Na rota /controle/, não há lote com esse identificador. |
Na rota /controle/, reenvie o POST. Na rota por {token}, confira o token do lote. |
A lista completa dos códigos está em Códigos de erro.
Próximos passos
Seção intitulada “Próximos passos”| Ação | Endpoint | Plano | Descrição |
|---|---|---|---|
| Obter PDF do lote | GET /batch/boletos/{token} |
Plano: Personalizado | Arquivo do lote, com um boleto por página |
| Obter PDF do carnê | GET /carnes/{token} |
Plano: Personalizado | Arquivo do carnê |
| Recuperar a criação | GET .../controle/{tokenControleUsuario}/situacao |
Plano: Personalizado | Idempotência no lote: 404 nessa rota permite reenviar o POST |
Verificar se o lote está pronto
Seção intitulada “Verificar se o lote está pronto”Após criar um lote/carnê, a pergunta operacional é dupla: todos os boletos concluíram o registro? e algum boleto precisa de ação? A receita é aplicar as regras de leitura do individual sobre cada item:
GET .../{token}/situacaono lote (uma chamada, não 300);- Para cada boleto:
registro.situacaoemREGISTRO_CONFIRMADO,REGISTRO_REJEITADOouREGISTRO_NAO_SOLICITADO= terminal;REGISTRO_PENDENTE/REGISTRO_EM_PROGRESSO= aguarde; - Precisa de ação =
REGISTRO_REJEITADOcomregistro.erropresente — oerro.codigodiz qual ação. JáREGISTRO_REJEITADOcomerro: nullé a supersessão do individual: o boleto foi pago ou baixado antes de o registro concluir; o motivo real está empagamento/baixae não há ação de registro a tomar; - Repita a consulta em intervalos razoáveis enquanto houver registros pendentes.
Veja Uso responsável da API.
