API para gerar PDF DANFSe a partir do XML
Contrato técnico para software houses, ERPs e integrações que transformam XML de origem aceito em PDF DANFSe por requisição.
OpenAPI 3.1, versionado e sem contrato paralelo
A referência normativa da API é o OpenAPI 3.1 canônico. Ele define rotas, autenticação, idempotência, limites, respostas e Problem Details.
Esta página é um guia de integração. Em caso de dúvida sobre caminho, campo, cabeçalho, limite ou status HTTP, prevalece o contrato OpenAPI versionado.
Referência e validação
A base canônica é
https://api.cmpsoftware.com.br. O lote usa
https://api.cmpsoftware.com.br/v1/danfse/batch; não
existe host separado para lote.
Para verificar uma integração em staging, execute o quickstart versionado no repositório com Tokens da API fornecidos pelo ambiente:
export STAGING_API_TOKEN STAGING_PAID_API_TOKEN
STAGING_API_URL=https://api.cmpsoftware.com.br bun plano-de-controle/conta/quickstart-staging.ts O quickstart envia somente o fixture sintético dos checks de contrato. Não inclua credenciais, XML fiscal, chave fiscal ou dados pessoais em código, exemplos ou logs.
Rotas da API
-
POST /v1/danfse -
Entrada: XML UTF-8 bruto em
application/xml, com até 1 MiB. Saída: PDF emapplication/pdf. -
POST /v1/danfse/trial - Contrato unitário com marca d’água e limite de uma conversão a cada 30 dias.
-
POST /v1/danfse/batch -
Entrada: de 1 a 50 XMLs por
multipart, no campo repetidofiles, ou um ZIP com arquivos na raiz. Saída: ZIP com manifesto.
Leiautes de XML do contrato: 1.00 e 1.01, com resultado ou erro individual para cada item do lote.
Quickstart seguro
Os comandos usam o fixture sintético versionado em
src/lib/danfse/fixtures/nfse-1.00.xml. Defina os Tokens
da API no ambiente; o script cria o ZIP de entrada localmente e
grava cada resposta binária em um arquivo explícito.
STAGING_API_URL="https://api.cmpsoftware.com.br"
test -n "$STAGING_API_TOKEN" || (printf '%s\n' 'defina o token de trial' >&2; exit 1)
test -n "$STAGING_PAID_API_TOKEN" || (printf '%s\n' 'defina o token pago' >&2; exit 1)
STAGING_XML_FILE="src/lib/danfse/fixtures/nfse-1.00.xml"
STAGING_OUTPUT_DIR="./.quickstart-output"
STAGING_ZIP_FILE="$STAGING_OUTPUT_DIR/danfse-input.zip"
STAGING_UNIT_OUTPUT="$STAGING_OUTPUT_DIR/danfse-unit.pdf"
STAGING_TRIAL_OUTPUT="$STAGING_OUTPUT_DIR/danfse-trial.pdf"
STAGING_MULTIPART_OUTPUT="$STAGING_OUTPUT_DIR/danfse-multipart.zip"
STAGING_ZIP_OUTPUT="$STAGING_OUTPUT_DIR/danfse-zip.zip"
mkdir -p "$STAGING_OUTPUT_DIR"
bun -e 'import { readFileSync, writeFileSync } from "node:fs"; import { criarZipEntradaXml } from "./plano-de-controle/conta/lote-zip.ts"; const [xmlPath, zipPath] = process.argv.slice(1); writeFileSync(zipPath, criarZipEntradaXml([{ nome: "nfse-1.00.xml", xml: readFileSync(xmlPath) }]));' "$STAGING_XML_FILE" "$STAGING_ZIP_FILE"
curl --silent --show-error --fail-with-body --output "$STAGING_UNIT_OUTPUT" --url "$STAGING_API_URL/v1/danfse" \
--header "Authorization: Bearer $STAGING_PAID_API_TOKEN" \
--header "Content-Type: application/xml" \
--header "Idempotency-Key: quickstart-unit-$(uuidgen)" \
--data-binary "@$STAGING_XML_FILE"
curl --silent --show-error --fail-with-body --output "$STAGING_TRIAL_OUTPUT" --url "$STAGING_API_URL/v1/danfse/trial" \
--header "Authorization: Bearer $STAGING_API_TOKEN" \
--header "Content-Type: application/xml" \
--header "Idempotency-Key: quickstart-trial-$(uuidgen)" \
--data-binary "@$STAGING_XML_FILE"
curl --silent --show-error --fail-with-body --output "$STAGING_MULTIPART_OUTPUT" --url "$STAGING_API_URL/v1/danfse/batch" \
--header "Authorization: Bearer $STAGING_PAID_API_TOKEN" \
--header "Idempotency-Key: quickstart-multipart-$(uuidgen)" \
--form "files=@$STAGING_XML_FILE;type=application/xml"
curl --silent --show-error --fail-with-body --output "$STAGING_ZIP_OUTPUT" --url "$STAGING_API_URL/v1/danfse/batch" \
--header "Authorization: Bearer $STAGING_PAID_API_TOKEN" \
--header "Content-Type: application/zip" \
--header "Idempotency-Key: quickstart-zip-$(uuidgen)" \
--data-binary "@$STAGING_ZIP_FILE" Repetir uma requisição com a mesma chave e a mesma entrada é seguro: o servidor devolve o mesmo resultado de consumo, sem nova cobrança. Para uma nova operação, gere uma nova chave. Consulte o OpenAPI para limites, cabeçalhos, saídas e Problem Details completos.
Autenticação e idempotência
O contrato de autenticação usa Authorization: Bearer <token>
em todas as rotas.
O cabeçalho Idempotency-Key é obrigatório e vale por 24
horas. Repetir a mesma chave com a mesma entrada devolve o mesmo resultado
de consumo, sem cobrar outra conversão.
Versões rastreáveis
A resposta unitária inclui Request-Id,
Danfse-Renderer-Version, Danfse-Normative-Version e
Danfse-Xml-Version. No lote, as versões comuns ficam nos
cabeçalhos e a versão do XML aparece em cada item do manifesto.
Mudanças incompatíveis usam nova versão major. A política de versionamento mantém a versão anterior por 90 dias após o aviso, salvo risco urgente ou obrigação legal.
Erros seguros e processamento stateless
Formato de erro
O contrato de erro segue a RFC 9457 em application/problem+json, com type, title, status,
code, detail e requestId seguros.
A resposta não repete XML, PDF, chave fiscal ou dados pessoais.
Arquivos transitórios
A política de arquivos transitórios não armazena XML ou PDF após a resposta, inclusive quando houver erro. Logs, métricas e suporte operam sem o conteúdo dos arquivos; apenas metadados técnicos mínimos são registrados.
A API converte o XML aceito; não emite, consulta, busca, autoriza ou cancela NFS-e.
Planos e blocos para os dois canais
Compare os planos mensais e blocos avulsos para o Conversor web e a API DANFSe.
Plano 1.000
R$ 29
1.000 Conversões DANFSe por mês
A franquia mensal não acumula para o ciclo seguinte.
Plano 10.000
R$ 99
10.000 Conversões DANFSe por mês
A franquia mensal não acumula para o ciclo seguinte.
Bloco 20
R$ 9,90
20 Conversões DANFSe
Créditos com validade de 12 meses.
Bloco 250
R$ 29
250 Conversões DANFSe
Créditos com validade de 12 meses.
Condições comerciais
- Saldo compartilhado entre o Conversor web e a API DANFSe.
- Sem cobrança automática de excedentes.
- Blocos utilizáveis mesmo sem plano mensal ativo.
- Trial da API: uma conversão com marca d’água por Conta a cada 30 dias, encerrado após o primeiro pagamento.