API do BAIXA XML

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.

Começando

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.

curl https://baixaxml.com.br/api/nfe/consulta/35241012345678000190550010000123451234567892 \
  -H "x-api-key: bxk_SUA_CHAVE"

É 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.

Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';

function assinaturaValida(corpoCru, cabecalho, segredo) {
  const { t, v1 } = Object.fromEntries(cabecalho.split(',').map((p) => p.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const esperado = createHmac('sha256', segredo).update(`${t}.${corpoCru}`).digest('hex');
  return timingSafeEqual(Buffer.from(esperado), Buffer.from(v1));
}
Python
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.

ParâmetroOndeDescrição
chave *caminhoChave de acesso, 44 dígitos.
formatoqueryxml para receber o arquivo cru em vez de JSON.
Exemplo
curl "https://baixaxml.com.br/api/nfe/consulta/35241012345678000190550010000123451234567892" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "chave": "35241012345678000190550010000123451234567892",
  "xml": "<nfeProc xmlns=\"http://www.portalfiscal.inf.br/nfe\" versao=\"4.00\">…</nfeProc>",
  "cobradoCentavos": 6,
  "repetida": false
}
  • 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.

ParâmetroOndeDescrição
chaves *corpo JSONAs chaves, em texto livre.
Exemplo
curl -X POST "https://baixaxml.com.br/api/nfe/lote/chaves" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -H "content-type: application/json" \
  -d '{"chaves":"35241012345678000190550010000123451234567892"}'
Resposta
{
  "jobId": "nfe_1728480000000_k2x9q1a",
  "total": 1200,
  "custoCentavos": 7200,
  "status": "PENDENTE"
}
  • 400 — Nenhuma chave válida no texto.
  • 400 — Saldo insuficiente (error: "SaldoInsuficiente", com faltamCentavos).

POST/nfe/lote

Criar um lote a partir de arquivo

O mesmo, enviando um .csv ou .txt (até 200 MB) em multipart/form-data. As chaves podem estar em qualquer coluna.

Cobrança: Igual ao lote por texto.

ParâmetroOndeDescrição
arquivo *multipartCSV ou TXT com as chaves.
Exemplo
curl -X POST "https://baixaxml.com.br/api/nfe/lote" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -F "arquivo=@arquivo"
Resposta
{
  "jobId": "nfe_1728480000000_k2x9q1a",
  "total": 85000,
  "custoCentavos": 340000,
  "status": "PENDENTE"
}
  • 400 — Saldo insuficiente (error: "SaldoInsuficiente", com faltamCentavos).

GET/nfe/lote

Listar os lotes

Os lotes da conta, do mais recente para o mais antigo.

Exemplo
curl "https://baixaxml.com.br/api/nfe/lote" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
[
  {
    "id": "nfe_1728480000000_k2x9q1a",
    "status": "CONCLUIDO",
    "total": 1200,
    "ok": 1183,
    "notfound": 17,
    "erro": 0,
    "createdAt": "2026-10-09T13:00:00.000Z",
    "finishedAt": "2026-10-09T13:41:00.000Z"
  }
]

GET/nfe/lote/{jobId}

Status de um lote

status: PENDENTE, PROCESSANDO, CONCLUIDO ou ERRO. progresso vai de 0 a 1.

ParâmetroOndeDescrição
jobId *caminhoO jobId da criação.
Exemplo
curl "https://baixaxml.com.br/api/nfe/lote/nfe_1728480000000_k2x9q1a" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "id": "nfe_1728480000000_k2x9q1a",
  "status": "PROCESSANDO",
  "total": 1200,
  "ok": 640,
  "notfound": 9,
  "erro": 0,
  "processados": 649,
  "pendentes": 551,
  "progresso": 0.5408
}
  • 404 — Lote inexistente ou de outra conta.

GET/nfe/lote/{jobId}/resultados

Resultado por chave

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.

ParâmetroOndeDescrição
jobId *caminhoO jobId.
statusqueryFiltra por ok, notfound ou erro.
formatoquerycsv para baixar tudo (chave;status;motivo).
paginaqueryPágina, a partir de 1.
porPaginaqueryAté 1.000 (padrão 500).
Exemplo
curl "https://baixaxml.com.br/api/nfe/lote/nfe_1728480000000_k2x9q1a/resultados" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "jobId": "nfe_1728480000000_k2x9q1a",
  "status": "CONCLUIDO",
  "total": 1200,
  "pagina": 1,
  "porPagina": 500,
  "itens": [
    {
      "chave": "35241012345678000190550010000123451234567892",
      "status": "ok"
    },
    {
      "chave": "3524…",
      "status": "notfound",
      "motivo": "Nota não localizada"
    }
  ]
}

GET/nfe/lote/{jobId}/xml/{chave}

XML de uma chave do lote

Um arquivo só, sem precisar baixar o ZIP.

ParâmetroOndeDescrição
jobId *caminhoO jobId.
chave *caminhoChave de acesso.
Exemplo
curl "https://baixaxml.com.br/api/nfe/lote/nfe_1728480000000_k2x9q1a/xml/35241012345678000190550010000123451234567892" \
  -H "x-api-key: bxk_SUA_CHAVE"

Resposta: arquivo application/xml.

  • 404 — A chave não tem XML neste lote.

GET/nfe/lote/{jobId}/download

ZIP do lote

Todos os XMLs obtidos até agora — funciona também com o lote em andamento. Os arquivos ficam disponíveis por 48 horas depois do fim do lote.

ParâmetroOndeDescrição
jobId *caminhoO jobId.
Exemplo
curl "https://baixaxml.com.br/api/nfe/lote/nfe_1728480000000_k2x9q1a/download" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -o lote.zip

Resposta: arquivo application/zip.

  • 404 — Nenhum XML ainda.

DELETE/nfe/lote/{jobId}

Cancelar ou apagar um lote

Cancela o lote em andamento (cobra só o que já foi entregue) ou apaga um lote concluído e os arquivos dele.

ParâmetroOndeDescrição
jobId *caminhoO jobId.
Exemplo
curl -X DELETE "https://baixaxml.com.br/api/nfe/lote/nfe_1728480000000_k2x9q1a" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "ok": true,
  "removido": "nfe_1728480000000_k2x9q1a"
}

SPED

Envie a EFD ICMS/IPI ou a EFD Contribuições e baixe os XMLs das notas escrituradas, com filtros. Analisar é gratuito; o download vira um lote.

POST/sped/analises

Enviar arquivos SPED

multipart/form-data com um ou mais TXT do SPED, ou ZIP com eles (até 300 MB cada). A análise roda em segundo plano.

ParâmetroOndeDescrição
arquivos *multipartOs arquivos (campo repetido).
nomemultipartNome para identificar a análise.
Exemplo
curl -X POST "https://baixaxml.com.br/api/sped/analises" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -F "arquivos=@arquivo" \
  -F "nome=valor"
Resposta
{
  "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
  "status": "PROCESSANDO"
}

GET/sped/analises/{id}

Situação e resumo da análise

Quantidade de notas, período e a situação (PROCESSANDO, CONCLUIDA, ERRO).

ParâmetroOndeDescrição
id *caminhoId da análise.
Exemplo
curl "https://baixaxml.com.br/api/sped/analises/6f92dd6b-5352-4c7f-a065-db421f252f4d" \
  -H "x-api-key: bxk_SUA_CHAVE"

POST/sped/analises/{id}/baixar

Baixar os XMLs das notas do SPED

Cria um lote com as chaves das notas que atendem aos filtros (todos opcionais). A partir daí é um lote comum.

Cobrança: Igual ao lote.

ParâmetroOndeDescrição
id *caminhoId da análise.
competenciascorpo JSONAAAA ou AAAA-MM.
cfopscorpo JSONCFOPs, 4 dígitos.
operacoescorpo JSONE (entrada) e/ou S (saída).
emissoescorpo JSONP (própria) e/ou T (terceiros).
modeloscorpo JSONEx.: 55.
situacoescorpo JSONCódigo de situação do SPED, 2 dígitos.
Exemplo
curl -X POST "https://baixaxml.com.br/api/sped/analises/6f92dd6b-5352-4c7f-a065-db421f252f4d/baixar" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "jobId": "nfe_1728480000000_k2x9q1a",
  "total": 5508,
  "custoCentavos": 33048
}
  • 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.

Exemplo
curl "https://baixaxml.com.br/api/dfe/plano" \
  -H "x-api-key: bxk_SUA_CHAVE"

GET/dfe/empresas

Empresas monitoradas

Situação de cada CNPJ, última consulta à SEFAZ, certificado e contagem de notas.

Exemplo
curl "https://baixaxml.com.br/api/dfe/empresas" \
  -H "x-api-key: bxk_SUA_CHAVE"

GET/dfe/notas/alteracoes

Notas novas ou alteradas

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.

ParâmetroOndeDescrição
cursorqueryO da resposta anterior. Vazio = desde o começo.
empresaIdquerySó desta empresa.
limitequeryAté 500 (padrão 100).
Exemplo
curl "https://baixaxml.com.br/api/dfe/notas/alteracoes" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "itens": [
    {
      "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
      "chave": "35241012345678000190550010000123451234567892",
      "emitenteDoc": "12345678000190",
      "emitenteNome": "FORNECEDOR SA",
      "valor": "1500.50",
      "dataEmissao": "2026-10-08T14:22:00.000Z",
      "situacao": "AUTORIZADA",
      "xmlCompleto": true,
      "disponivel": true,
      "manifestacao": "CIENCIA",
      "empresa": {
        "cnpj": "98765432000110",
        "nome": "Cliente Ltda"
      },
      "alteradaEm": "2026-10-09T10:01:12.000Z"
    }
  ],
  "cursor": "MjAyNi0xMC0wOVQxMDowMToxMi4wMDBafDZmOTI…",
  "temMais": false
}

GET/dfe/notas

Buscar notas recebidas

Listagem paginada com filtros, como no painel.

ParâmetroOndeDescrição
empresaIdqueryEmpresa.
dequeryEmissão a partir de (AAAA-MM-DD).
atequeryEmissão até.
situacaoqueryAUTORIZADA, CANCELADA ou DENEGADA.
buscaqueryEmitente, CNPJ ou chave.
paginaqueryPágina.
porPaginaqueryItens por página.
Exemplo
curl "https://baixaxml.com.br/api/dfe/notas" \
  -H "x-api-key: bxk_SUA_CHAVE"

GET/dfe/notas/{id}/xml

XML de uma nota recebida

O XML completo, quando já chegou da SEFAZ.

ParâmetroOndeDescrição
id *caminhoId da nota (não a chave).
Exemplo
curl "https://baixaxml.com.br/api/dfe/notas/6f92dd6b-5352-4c7f-a065-db421f252f4d/xml" \
  -H "x-api-key: bxk_SUA_CHAVE"

Resposta: arquivo application/xml.

  • 400 — Só o resumo chegou até agora.
  • 404 — Nota inexistente ou de outra conta.

GET/dfe/notas/zip

ZIP das notas recebidas

Os XMLs completos que atendem aos mesmos filtros da busca.

ParâmetroOndeDescrição
empresaIdqueryEmpresa.
dequeryEmissão a partir de.
atequeryEmissão até.
Exemplo
curl "https://baixaxml.com.br/api/dfe/notas/zip" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -o lote.zip

Resposta: arquivo application/zip.

Webhooks

Avisamos uma URL sua quando algo acontece, em vez de você consultar em intervalos. Veja a seção "Recebendo webhooks" para validar a assinatura.

GET/integracoes/webhooks/eventos

Eventos disponíveis

Os nomes que podem ser assinados.

Exemplo
curl "https://baixaxml.com.br/api/integracoes/webhooks/eventos" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
[
  "lote.concluido",
  "captura.xml_disponivel",
  "captura.nota_cancelada"
]

GET/integracoes/webhooks

Listar webhooks

Os endpoints cadastrados e a última entrega de cada um.

Exemplo
curl "https://baixaxml.com.br/api/integracoes/webhooks" \
  -H "x-api-key: bxk_SUA_CHAVE"

POST/integracoes/webhooks

Cadastrar um webhook

URL https:// pública e os eventos. O segredo de assinatura aparece só nesta resposta — guarde. Até 5 por conta.

ParâmetroOndeDescrição
url *corpo JSONOnde entregar.
eventos *corpo JSONUm ou mais eventos.
Exemplo
curl -X POST "https://baixaxml.com.br/api/integracoes/webhooks" \
  -H "x-api-key: bxk_SUA_CHAVE" \
  -H "content-type: application/json" \
  -d '{"url":"https://seu-sistema.com.br/webhooks/baixaxml","eventos":["lote.concluido"]}'
Resposta
{
  "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
  "url": "https://seu-sistema.com.br/webhooks/baixaxml",
  "eventos": [
    "lote.concluido"
  ],
  "ativo": true,
  "segredo": "whsec_…"
}
  • 400 — URL que não é https, de rede interna, evento desconhecido ou limite atingido.

PATCH/integracoes/webhooks/{id}

Alterar um webhook

Troca URL ou eventos, ou pausa com ativo: false.

ParâmetroOndeDescrição
id *caminhoId do webhook.
urlcorpo JSONNova URL.
eventoscorpo JSONNovos eventos.
ativocorpo JSONPausar/retomar.
Exemplo
curl -X PATCH "https://baixaxml.com.br/api/integracoes/webhooks/6f92dd6b-5352-4c7f-a065-db421f252f4d" \
  -H "x-api-key: bxk_SUA_CHAVE"

DELETE/integracoes/webhooks/{id}

Remover um webhook

Entregas pendentes dele são descartadas.

ParâmetroOndeDescrição
id *caminhoId do webhook.
Exemplo
curl -X DELETE "https://baixaxml.com.br/api/integracoes/webhooks/6f92dd6b-5352-4c7f-a065-db421f252f4d" \
  -H "x-api-key: bxk_SUA_CHAVE"

POST/integracoes/webhooks/{id}/teste

Enviar um evento de teste

Entrega um evento teste agora e devolve o resultado (status HTTP da sua URL ou o erro).

ParâmetroOndeDescrição
id *caminhoId do webhook.
Exemplo
curl -X POST "https://baixaxml.com.br/api/integracoes/webhooks/6f92dd6b-5352-4c7f-a065-db421f252f4d/teste" \
  -H "x-api-key: bxk_SUA_CHAVE"

POST/integracoes/webhooks/{id}/segredo

Gerar outro segredo

Para rotação ou se o segredo vazou. O antigo deixa de valer na hora.

ParâmetroOndeDescrição
id *caminhoId do webhook.
Exemplo
curl -X POST "https://baixaxml.com.br/api/integracoes/webhooks/6f92dd6b-5352-4c7f-a065-db421f252f4d/segredo" \
  -H "x-api-key: bxk_SUA_CHAVE"

GET/integracoes/webhooks/{id}/entregas

Últimas entregas

As 50 mais recentes, com situação (entregue, pendente, falhou), tentativas e o último erro.

ParâmetroOndeDescrição
id *caminhoId do webhook.
Exemplo
curl "https://baixaxml.com.br/api/integracoes/webhooks/6f92dd6b-5352-4c7f-a065-db421f252f4d/entregas" \
  -H "x-api-key: bxk_SUA_CHAVE"

Conta e créditos

Saldo, preços e extrato.

GET/creditos

Saldo

Disponível, reservado em lotes em andamento e a tabela de preços.

Exemplo
curl "https://baixaxml.com.br/api/creditos" \
  -H "x-api-key: bxk_SUA_CHAVE"

GET/creditos/orcamento

Quanto custa

O preço por XML e o total para N chaves, já com o volume dos últimos 30 dias da conta, e se o saldo cobre.

ParâmetroOndeDescrição
chaves *queryQuantidade de chaves.
Exemplo
curl "https://baixaxml.com.br/api/creditos/orcamento?chaves=1200" \
  -H "x-api-key: bxk_SUA_CHAVE"
Resposta
{
  "chaves": 1200,
  "volumeRecente": 8400,
  "precoUnitarioCentavos": 6,
  "totalCentavos": 7200,
  "saldoCentavos": 25000,
  "suficiente": true,
  "faltamCentavos": 0
}

GET/creditos/precos

Tabela de preços

As faixas por volume. Pública.

Exemplo
curl "https://baixaxml.com.br/api/creditos/precos"

GET/creditos/extrato

Extrato

Recargas, reservas, consumos e devoluções, com o saldo depois de cada um.

Exemplo
curl "https://baixaxml.com.br/api/creditos/extrato" \
  -H "x-api-key: bxk_SUA_CHAVE"