Integre o download de XML de NF-e ao seu sistema: consulte uma chave e receba o XML na resposta, mande lotes de milhares de chaves, leia as notas que a captura automática recebe da SEFAZ e seja avisado por webhook. Para ERPs, sistemas contábeis e quem quer revender — o preço cai com o volume.
Todas as rotas ficam em https://baixaxml.com.br/api e respondem JSON. Autentique com uma chave de API, criada no painel em Configurações → Chaves de API, no cabeçalho x-api-key. A chave age em nome da sua conta e usa o mesmo saldo do painel: guarde-a no servidor, nunca no navegador ou no aplicativo do usuário final.
É preciso ter o e-mail da conta confirmado. As rotas que gastam crédito devolvem 400 com error: "SaldoInsuficiente" e faltamCentavos quando o saldo não cobre — a recarga é por Pix, no painel.
Preços na API
Por XML entregue, o mesmo preço do painel. Chave não encontrada e falha da fonte não são cobradas.
A faixa usa o volume da conta: o tamanho do pedido somado aos XMLs entregues nos últimos 30 dias. Quem consulta uma chave por vez, mas muitas no mês, paga o mesmo que pagaria em lote. Veja as faixas em Preços ou em GET /creditos/precos.
Consulta repetida não paga de novo: a mesma chave pela mesma conta em até 24 horas sai sem custo.
Antes de mandar um lote, GET /creditos/orcamento diz o preço e o total exatos.
Limites e erros
Até 100 requisições por minuto por chave de API, e o mesmo por endereço de origem — vale o que bater primeiro. Acima disso a resposta é 429; espere e tente de novo. Para volume, prefira lotes à consulta avulsa: um lote de 100 mil chaves é uma requisição só.
Erros vêm sempre neste formato:
{
"statusCode": 404,
"error": "NaoEncontrada",
"message": "A fonte não tem o XML desta chave. Nada foi cobrado."
}
401 — chave de API ausente, inválida ou revogada.
403 — e-mail da conta ainda não confirmado.
404 — o recurso não existe ou é de outra conta (não confirmamos ids alheios).
503 — fonte temporariamente fora do ar; respeite o Retry-After.
Recebendo webhooks
Cadastre a URL com POST /integracoes/webhooks. A cada evento enviamos um POST com este corpo:
{
"id": "evt_6c1f…", // o mesmo em todas as tentativas: deduplique por ele
"evento": "lote.concluido",
"criadoEm": "2026-10-09T13:41:00.000Z",
"dados": { "jobId": "nfe_…", "status": "CONCLUIDO", "total": 1200,
"ok": 1183, "notfound": 17, "erro": 0, "cobradoCentavos": 7098 }
}
lote.concluido — o lote terminou (CONCLUIDO ou ERRO), já com o valor cobrado.
captura.xml_disponivel — chegou o XML completo de uma nota da captura (notaId, chave, empresa, emitente, valor). Baixe em GET /dfe/notas/{notaId}/xml.
captura.nota_cancelada — o emitente cancelou uma nota recebida.
Responda 2xx em até 10 segundos. Qualquer outra resposta, ou nenhuma, conta como falha: tentamos de novo depois de 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h. Só aceitamos URLs https:// públicas.
Valide a assinatura antes de confiar no conteúdo. O cabeçalho X-BaixaXML-Assinatura traz t=<unix>,v1=<hex>: o HMAC-SHA256 de <t>.<corpo cru> com o segredo do webhook. Recuse se o t for de mais de 5 minutos atrás.
import hmac, hashlib, time
def assinatura_valida(corpo_cru: bytes, cabecalho: str, segredo: str) -> bool:
partes = dict(p.split("=", 1) for p in cabecalho.split(","))
if abs(time.time() - int(partes["t"])) > 300:
return False
esperado = hmac.new(segredo.encode(), partes["t"].encode() + b"." + corpo_cru,
hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, partes["v1"])
Consulta por chave
Uma chave, o XML na resposta. Para integrar nota a nota no seu sistema.
GET/nfe/consulta/{chave}
Consultar o XML de uma NF-e
Busca o XML original (com a assinatura do emitente) pela chave de acesso. A mesma chave consultada de novo em até 24 horas não é cobrada outra vez. Com formato=xml, a resposta é o próprio arquivo.
Cobrança: 1 XML na faixa de preço da conta, só se encontrar. O valor cobrado vem no cabeçalho X-Cobrado-Centavos.
400 — Chave com formato inválido ou dígito verificador errado.
400 — Saldo insuficiente (error: "SaldoInsuficiente", com faltamCentavos).
404 — A fonte não tem o XML (NaoEncontrada). Nada é cobrado.
503 — Fonte fora do ar (FonteIndisponivel), com Retry-After. Nada é cobrado.
Lotes
Muitas chaves de uma vez. O lote roda em segundo plano: acompanhe pelo status ou receba o webhook lote.concluido.
POST/nfe/lote/chaves
Criar um lote
Envie as chaves em texto (uma por linha, ou separadas por vírgula). Sequências de 44 dígitos são extraídas e repetidas são descartadas. O valor do lote é reservado na hora.
Cobrança: Reserva o lote inteiro na criação; no fim, cobra só os XMLs entregues e devolve o resto.
O que aconteceu com cada chave já processada: ok, notfound (a fonte não tem) ou erro (falha que persistiu). JSON paginado, ou o arquivo inteiro com formato=csv.
400 — Saldo insuficiente (error: "SaldoInsuficiente", com faltamCentavos).
Captura automática (certificado A1)
As notas emitidas contra os CNPJs da sua conta, direto da SEFAZ. Certificados e empresas são cadastrados no painel; pela API você lê as notas. Em liberação gradual.
GET/dfe/plano
Plano da captura
Faixa paga, CNPJs em uso, data e valor da renovação, e quanto custaria ativar mais um CNPJ agora.
Leitura incremental: guarde o cursor e mande na próxima chamada para receber só o que mudou (nota nova, XML completo que chegou, cancelamento). Repita enquanto temMais for true.