Ir para o conteúdo
Documentação

Portal do desenvolvedor

A API REST v1 da MadNotas recebe JSON, devolve JSON e fala com a SEFAZ e com a Sefin Nacional por você, para NF-e, NFC-e, NFS-e e as notas recebidas (DF-e). Esta página reúne o que vale para todas as rotas; os guias mostram cada fluxo.

Endereço base

URL base
https://notas.madbuilder.dev/api/v1

Todas as rotas usam HTTPS, recebem Content-Type: application/json e respondem em UTF-8. Datas seguem ISO 8601 com fuso (2026-10-29T14:03:12-03:00); valores em reais usam ponto decimal e até 2 casas.

Listas (GET /nfe, /nfce, /webhooks, /webhooks/eventos, /nfe/{id}/eventos e as demais) aceitam ?limite de 1 a 100 e devolvem tem_mais e proximo_cursor: para a página seguinte, repita a chamada com ?cursor= e esse valor. As tabelas de /utilitarios aceitam limite, mas não cursor. Parâmetro inválido responde 422 parametro_invalido, com o motivo em detalhes (lista de erros).

Autenticação

Envie a chave de API no cabeçalho Authorization. A chave é criada no painel, em Integração › Chaves de API, e aparece uma única vez: guarde-a no cofre de segredos do seu sistema.

Cabeçalho
Authorization: Bearer mn_sim_SuaChaveAqui

O prefixo da chave define o ambiente. Não existe parâmetro para trocar de ambiente: quem decide é a chave.

PrefixoAmbienteSEFAZCertificadoConta na franquia
mn_sim_SimulaçãoSimulada, nunca a realNão precisaNão
mn_hom_HomologaçãoReal, ambiente de testes (tpAmb 2)A1 do emitenteNão
mn_prod_ProduçãoReal, com valor fiscal (tpAmb 1)A1 do emitenteSim

Com mn_hom_ ou mn_prod_ e o emitente sem A1 válido, a emissão volta 422 certificado_indisponivel antes de reservar número. O botão Experimente desta documentação usa só chave mn_sim_; as outras são recusadas com 403 origem_docs_nao_permitida.

Teto por chave, útil para revenda. Cada chave pode ter o próprio limite de requisições por minuto, de 1 até o do plano: em Integração › Chaves de API, no campo Limite por minuto ao criar a chave ou na ação de mesmo nome na lista. Vazio usa o do plano. Assim, uma software house dá a cada cliente uma chave com um teto, e um cliente com laço de reenvio não consome o limite dos outros. O teto vale para todas as rotas da chave, e passar dele responde 429 com Retry-After. GET /conta/uso mostra, em chave.limite_efetivo, o limite que vale para a chave usada.

Uma chave pode ficar restrita a um emitente (CNPJ) e a algumas permissões. Chave revogada responde 401 na chamada seguinte. Toda resposta traz o cabeçalho MadNotas-Ambiente com o ambiente da chave usada.

Formato de erro

Erro de requisição (chave, permissão, payload inválido, limite) volta sempre no mesmo envelope, com status HTTP adequado:

401 Unauthorized
{
  "erro": {
    "tipo": "autenticacao",
    "codigo": "chave_invalida",
    "mensagem": "Chave de API inválida, expirada ou revogada.",
    "detalhes": []
  },
  "request_id": "req_01jbx4k2m9q7t3v8w5z6y1r0ac"
}
HTTPQuando
401Chave ausente, inválida ou revogada.
402Conta suspensa ou limite de notas de produção do período de teste atingido.
403Empresa inativa ou chave sem permissão para a rota.
404Recurso não existe ou pertence a outra conta.
409Mesma ref com conteúdo diferente e a nota não está rejeitada.
413Corpo da requisição acima de 5 MB (corpo_muito_grande). Recusado antes de ser lido e antes da autenticação, com o mesmo envelope de erro.
415Corpo enviado com Content-Type que não é JSON (tipo_conteudo_invalido).
422Payload inválido. Nada foi criado nem numerado; detalhes lista todos os campos com o caminho no JSON. Também quando falta o certificado A1 do emitente em homologação ou produção (certificado_indisponivel).
429Limite de requisições por minuto. Espere os segundos de Retry-After.

Rejeição da SEFAZ não é erro HTTP. A nota foi criada e está no estado rejeitada: a resposta é 201 com a lista erros, e você corrige reenviando com a mesma ref. Veja Erros e rejeições.

Estados da nota

StatusSignificadoFinal?
processandoRecebida e a caminho da SEFAZ ou aguardando resposta. Consulte de novo ou espere o webhook.Não
autorizadaSEFAZ autorizou o uso. XML e DANFE disponíveis.Pode ser cancelada
rejeitadaSEFAZ recusou. Corrija e reenvie: o número é mantido.Não
denegadaUso denegado por irregularidade fiscal do emitente ou do destinatário.Sim
contingenciaNFC-e emitida offline; será transmitida quando a SEFAZ voltar.Não
canceladaCancelamento homologado pela SEFAZ.Sim
descartadaRejeitada que você desistiu de corrigir. O número volta para uso.Sim

Idempotência e reenvio seguro

Toda nota leva uma ref: o identificador do pedido no seu sistema, único por ambiente e modelo, um texto de até 100 caracteres com letras, números e . : / - _. Vazia, só com espaços, com outro caractere ou que não seja texto volta 422 com ref_invalida no campo ref (no /validar, valido: false com o mesmo erro); "ref": null é nota sem ref (e sem a proteção abaixo). Ela torna o reenvio seguro depois de um timeout:

  • Mesma ref e mesmo conteúdo: a API devolve a nota já criada (200 com Idempotent-Replayed: true).
  • Mesma ref, conteúdo novo e nota rejeitada: vale como correção, com o mesmo número.
  • Mesma ref, conteúdo novo e qualquer outro estado: 409.

Nas demais rotas de escrita, envie o cabeçalho Idempotency-Key (até 255 caracteres; acima disso, 400 idempotency_key_invalida). A resposta da primeira chamada fica guardada por 24 horas e é repetida para a mesma chave. A inutilização também é segura para repetir: pedir de novo a mesma faixa já inutilizada devolve 200 com Idempotent-Replayed: true e o mesmo id.

Limites de uso

Cada chave tem um limite de requisições por minuto, definido pelo plano (veja Preços) ou por um teto menor gravado na própria chave (veja Autenticação). As respostas trazem RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset; acima do limite, 429 com Retry-After.

Rastreio de chamadas

Toda resposta traz X-Request-Id. Você pode enviar o seu (8 a 64 caracteres: letras, números, . _ : -) e ele é repetido na resposta e no log. Informe esse valor ao falar com o suporte: no painel, em Integração › Logs da API, ele leva à requisição e à resposta completas.

Teste a chave agora

curl https://notas.madbuilder.dev/api/v1/ping \
  -H "Authorization: Bearer $MADNOTAS_CHAVE"