API do Notanexo
Emita NF-e, NFC-e e NFS-e, consulte e baixe XML e PDF direto do seu sistema, sobre a mesma base fiscal do painel. Eventos de NF-e/NFC-e também estão disponíveis pela API; para cancelamento e substituição de NFS-e, use o painel.
https://api.notanexo.com.br
201 ou 202, leia isto primeiro
A emissão espera a SEFAZ por até 15 segundos. Com veredito nesse prazo, a resposta é
201, com o documento já em AUTHORIZED ou
REJECTED. Sem veredito (a SEFAZ ainda não respondeu, ou a emissão caiu
para contingência), a resposta é 202, com o mesmo id,
status: "PROCESSING" (ou CONTINGENCY_PENDING) e um
cabeçalho Location apontando para o documento. A transmissão continua
rodando depois do 202.
O resultado final chega de duas formas, e você escolhe uma ou as duas: consultando
GET /v1/documents/:id, ou por webhook, sem precisar consultar nada
(DOCUMENT_AUTHORIZED, DOCUMENT_REJECTED,
DOCUMENT_CONTINGENCY). Os webhooks são configurados no painel, em
Automação → Webhooks, e cada entrega chega assinada com HMAC SHA-256 no cabeçalho
x-notanexo-signature.
Do zero à nota autorizada
Sete passos, cada comando pronto pra copiar.
1. Crie a chave
No painel: Automação → Chaves de API → nome da chave, escopo "Emitir e consultar" e ambiente "Homologação". O segredo aparece uma única vez, na tela de criação.
export NOTANEXO_KEY="nx_test_<id>_<segredo>"
2. Confira a chave e o plano
curl https://api.notanexo.com.br/v1/status \
-H "Authorization: Bearer $NOTANEXO_KEY"
Resposta, resumida:
{
"key": { "prefix": "nx_test_<id>…", "name": "ERP da loja", "scope": "WRITE", "environment": "HOMOLOGATION" },
"emitter": { "cnpj": "12345678000199", "corporateName": "Loja Exemplo LTDA", "uf": "MT", "modelsEnabled": ["NFE", "NFCE"] },
"plan": { "code": "profissional", "name": "Profissional" },
"limits": { "emissionsPerMinute": 10, "readsPerMinute": 60, "concurrentEmissions": 2 },
"sefaz": {
"mode": "direct",
"services": [
{ "model": "NFE", "cStat": "107", "xMotivo": "Servico em Operacao", "authorizer": "SEFAZ/MT" },
{ "model": "NFCE", "cStat": "107", "xMotivo": "Servico em Operacao", "authorizer": "SEFAZ/MT" }
]
}
}
3. Emita uma NF-e
Idempotency-Key é obrigatório aqui: um valor por pedido, não por
tentativa. payments[].method aceita o código tPag
de dois dígitos ou o apelido (veja a tabela mais abaixo).
O externalId é único por empresa somando homologação e produção: um
valor usado em teste não pode ser reusado em produção. Mande sempre externalId:
além de ligar a nota ao seu pedido, ele é uma segunda trava contra nota em dobro.
curl -X POST https://api.notanexo.com.br/v1/nfe \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-1001" \
-d '{
"externalId": "pedido-1001",
"operationNature": "VENDA",
"destinationUf": "MT",
"consumerFinal": true,
"isRetail": false,
"consumer": {
"name": "Maria Souza",
"document": "12345678909",
"address": { "street": "Rua das Flores", "number": "100", "district": "Centro", "city": "Cuiaba", "cityCode": "5103403", "state": "MT", "zipCode": "78005000" }
},
"items": [{ "sku": "CAMISETA-P", "description": "Camiseta", "quantity": 1, "unitPrice": 10, "taxMetadata": { "ncm": "61091000", "cfop": "5102" } }],
"payments": [{ "method": "01", "amount": 10 }]
}'
Troque endereço, UF e código IBGE pelos do seu cliente; o emitente deste exemplo é de MT. Resposta 201, resumida:
{
"id": "clz1a2b3c4d5e6f7g8h9",
"model": "NFE",
"status": "AUTHORIZED",
"number": 1042,
"serie": 1,
"accessKey": "5126…0421",
"protocol": "135260000001234",
"links": { "self": "/v1/documents/clz1a2b3c4d5e6f7g8h9", "xml": "/v1/documents/clz1a2b3c4d5e6f7g8h9/xml", "pdf": "/v1/documents/clz1a2b3c4d5e6f7g8h9/pdf" }
}
Serviços: emita uma NFS-e
Habilite NFS-e na empresa e cadastre o serviço e seus tributos no painel. A chave define
a empresa e o ambiente; serviceId identifica o serviço cadastrado.
externalId e Idempotency-Key são obrigatórios
e devem permanecer iguais ao repetir a mesma operação.
POST /v1/nfse
Authorization: Bearer SUA_CHAVE
Content-Type: application/json
Idempotency-Key: servico-1001-homologacao
{
"externalId": "servico-1001-homologacao",
"serviceId": "ID_DO_SERVICO_CADASTRADO",
"serie": 1,
"amount": 150,
"competenceDate": "2026-09-11",
"tomador": { "name": "Tomador sintético", "document": "52998224725" }
}
Troque os exemplos pelos dados da prestação. Consulte o resultado, XML e DANFSe pelos mesmos endpoints de documentos. Uma resposta 202 mantém o mesmo ID enquanto a emissão termina. Em Integrações, há templates de NF-e/NFS-e para n8n e Make, com configuração das credenciais e do mapeamento da operação.
4. Consulte o documento
curl https://api.notanexo.com.br/v1/documents/clz1a2b3c4d5e6f7g8h9 \
-H "Authorization: Bearer $NOTANEXO_KEY"
5. Baixe o XML e o DANFE
curl https://api.notanexo.com.br/v1/documents/clz1a2b3c4d5e6f7g8h9/xml \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-o nota.xml
curl https://api.notanexo.com.br/v1/documents/clz1a2b3c4d5e6f7g8h9/pdf \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-o danfe.pdf
6. Carta de correção e inutilização
Carta de correção só existe para NF-e (a NFC-e cancela e reemite), e só para nota
AUTHORIZED (uma nota cancelada não aceita mais correção);
correctionText entre 15 e 1000 caracteres;
acknowledgeDeadline vale aqui também (prazo de 720 horas). Sem
Idempotency-Key: a rota não é idempotente.
curl -X POST https://api.notanexo.com.br/v1/documents/clz1a2b3c4d5e6f7g8h9/correction \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-H "Content-Type: application/json" \
-d '{ "correctionText": "Correção do CFOP do item 1, de 5102 para 5101, sem alterar valor, quantidade ou tributo." }'
Inutilização de faixa, com Idempotency-Key:
curl -X POST https://api.notanexo.com.br/v1/inutilizations \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: inutilizacao-serie1-1050-1052" \
-d '{
"model": "NFE",
"serie": 1,
"startNumber": 1050,
"endNumber": 1052,
"justification": "Numeracao pulada por falha no sistema de vendas antes da emissao."
}'
7. Cancele, se precisar
Justificativa entre 15 e 255 caracteres. O prazo depende da UF: em geral 24 horas para NF-e (MT: 8 horas;
PR e RS: 7 dias; PI: 60 dias) e 30 minutos para NFC-e. Fora do prazo sem acknowledgeDeadline, a
resposta é 422 VALIDATION_ERROR com
details.reasonCode: "CANCELLATION_DEADLINE_EXPIRED". Com
acknowledgeDeadline: true a chamada tenta mesmo assim, e quem decide
é a SEFAZ. Depois de cancelada, a nota não aceita mais carta de correção.
curl -X POST https://api.notanexo.com.br/v1/documents/clz1a2b3c4d5e6f7g8h9/cancel \
-H "Authorization: Bearer $NOTANEXO_KEY" \
-H "Content-Type: application/json" \
-d '{ "justification": "Pedido cancelado pelo cliente antes do envio." }'
Chave, escopo e ambiente
Toda chave começa com nx_live_… (produção) ou
nx_test_… (homologação). A chave carrega exatamente uma empresa
(um CNPJ) e um ambiente; o corpo da requisição nunca escolhe nenhum dos dois.
Escopo READ só consulta. Escopo WRITE emite,
registra eventos (cancelamento, correção, inutilização) e também consulta, porque quem emite
precisa acompanhar o que emitiu.
Guarde a chave no seu servidor, nunca no navegador: a API não libera CORS, de propósito. Para trocar de chave, crie outra, aponte o seu sistema para ela e só depois revogue a antiga. Revogar tem efeito imediato.
Idempotência
Idempotency-Key é obrigatório em POST /v1/nfe,
POST /v1/nfce, POST /v1/nfse e POST /v1/inutilizations: de 1 a
255 caracteres ASCII visíveis (sem espaço nem quebra de linha). Sem o cabeçalho, ou fora desse
formato, a resposta é 400 IDEMPOTENCY_KEY_REQUIRED.
A mesma chave com o mesmo corpo, dentro de 24 horas, devolve a mesma resposta, com o cabeçalho
Idempotency-Replayed: true. Um 202 repetido continua 202: o estado
atual do documento se lê com GET, não pelo replay.
A mesma chave com um corpo diferente responde 409 IDEMPOTENCY_KEY_REUSED.
Uma requisição com a mesma chave ainda em andamento responde
409 IDEMPOTENCY_IN_PROGRESS. Se o erro acontece antes de o documento
existir, a chave fica livre para tentar de novo.
Limites por plano
O balde é por chave. Rotas de escrita consomem o balde de emissões; rotas de leitura, o de leituras.
| Plano | Emissões/min | Leituras/min | Emissões simultâneas |
|---|---|---|---|
| Grátis e Essencial | Sem API | ||
| Profissional | 20 | 120 | 3 |
| Multiempresa | 30 | 180 | 5 |
Toda resposta de uma chave válida cujo plano inclui a API traz
RateLimit-Limit, RateLimit-Remaining e
RateLimit-Reset (a exceção é o 403 PLAN_LIMIT_REACHED
de plano sem API, que não tem teto a informar). Ao estourar o teto, a resposta é
429 com Retry-After também. Os contadores
zeram se o servidor reiniciar. A franquia de notas do plano (quantas notas por mês) é a mesma
do painel; o teto de chamadas por minuto aqui é um limite à parte.
Status do documento
| Status | O que significa |
|---|---|
PROCESSING | Documento criado, transmissão em andamento; ainda sem veredito da SEFAZ. |
AUTHORIZED | Autorizado. XML e DANFE já disponíveis. |
REJECTED | Rejeitado pela SEFAZ; o motivo vem em sefaz.cStat e sefaz.xMotivo. |
CANCELLED | Cancelado, dentro ou fora do prazo (com acknowledgeDeadline). |
CONTINGENCY_PENDING | Emitido em contingência; a transmissão para a SEFAZ ainda está pendente. |
Lista e paginação
GET /v1/documents?status=&model=&issuedFrom=AAAA-MM-DD&issuedTo=AAAA-MM-DD&limit=
limit vai até 100. Os documentos vêm em data,
mais novo primeiro; a página traz nextCursor. Para a próxima página,
mande esse valor de volta como cursor. Não existe paginação por número de
página nem por offset.
{
"data": [ { "id": "clz1a2b3c4d5e6f7g8h9", "model": "NFE", "status": "AUTHORIZED", "..." : "..." } ],
"nextCursor": null
}
nextCursor é null na última página.
Meios de pagamento
payments[].method aceita o código tPag de dois dígitos, ou um destes apelidos:
| Código (tPag) | Apelido |
|---|---|
| 01 | dinheiro, cash |
| 02 | cheque |
| 03 | credito, credit_card |
| 04 | debito, debit_card |
| 15 | boleto |
| 17 | pix |
Cartão (03, 04) e Pix (17) geram o grupo <card> no XML.
Código 99 exige metadata.xPag descrevendo
qual foi o meio de pagamento.
Erros
Todo erro tem o mesmo formato: { "code", "message", "details" }.
O motivo fiscal, quando existe, atravessa sem tradução: procure em
details ou, no corpo do documento, em
sefaz.cStat e sefaz.xMotivo.
| Código | HTTP | O que fazer |
|---|---|---|
SCHEMA_VALIDATION_ERROR | 400 | Corpo ou parâmetros fora do schema; details.issues traz o caminho de cada campo. |
VALIDATION_ERROR | 400, 409 ou 422 | Regra de negócio (cursor inválido, documento ainda sem XML, prazo de cancelamento ou correção vencido com details.reasonCode etc.); leia message. |
IDEMPOTENCY_KEY_REQUIRED | 400 | Cabeçalho Idempotency-Key ausente, ou fora do formato (1 a 255 caracteres ASCII visíveis). |
API_KEY_INVALID | 401 | Confira o cabeçalho Authorization: Bearer nx_…. |
API_KEY_REVOKED | 401 | Chave revogada no painel; crie outra. |
API_SCOPE_INSUFFICIENT | 403 | A chave é READ e a rota exige WRITE. |
PLAN_LIMIT_REACHED | 403 | Causa mais comum no /v1: o plano não tem a capacidade api (details.capability). Também cobre franquia mensal de notas esgotada ou sem plano ativo. |
ORGANIZATION_INACTIVE | 403 | Organização cancelada (só consulta), ou emissão em produção sem assinatura ativa; regularize o plano. |
NOT_FOUND | 404 | Documento não existe para esta chave (empresa ou ambiente diferente contam como inexistente). |
IDEMPOTENCY_KEY_REUSED | 409 | Mesma Idempotency-Key com corpo diferente; use uma chave nova. |
IDEMPOTENCY_IN_PROGRESS | 409 | Já existe uma requisição em andamento com esta chave; aguarde. |
SERIES_MISSING | 409 | Série não configurada no ambiente; configure em Minha empresa → Séries. |
EXTERNAL_ID_TAKEN | 409 | Já existe documento com este externalId nesta empresa. O externalId é único por empresa somando homologação e produção: um valor usado em teste não pode ser reusado em produção. |
EMITTER_NOT_READY | 400 ou 409 | Empresa sem certificado ativo, com certificado vencido, sem a credencial de NF-e, ou sem o CSC, para NFC-e; no 409, details.errors lista cada causa e details.requestedModel traz o modelo. |
MODEL_NOT_ENABLED | 400 | Empresa não habilitada para o modelo solicitado (NF-e, NFC-e ou NFS-e). |
CERTIFICATE_EXPIRED | 400 | Certificado da empresa venceu; renove no painel. |
CSC_MISSING | 400 | NFC-e sem CSC configurado (ou incompleto); configure em Minha empresa → NFC-e. |
SEFAZ_REJECTION | não é erro de requisição | A chamada responde 201/202 normalmente; o motivo da rejeição vem em sefaz.cStat/sefaz.xMotivo, dentro do documento. |
SEFAZ_TIMEOUT | não é erro de requisição | Sem veredito nos 15 s, a chamada responde 202; a transmissão continua e o resultado chega pelo GET ou pelo webhook. |
CONTINGENCY_REQUIRED | não é erro de requisição | errorCode dentro do payload do webhook DOCUMENT_CONTINGENCY, quando a emissão cai para contingência. |
API_RATE_LIMITED | 429 | Teto de emissões ou leituras por minuto atingido; respeite Retry-After. |
API_CONCURRENCY_LIMIT | 429 | A chave já tem o teto de emissões simultâneas em andamento; aguarde uma terminar. |
RATE_LIMITED | 429 | Muitas tentativas com chave inválida vindas do mesmo IP; aguarde. |
INTERNAL_ERROR | 500 | Erro interno; tente de novo e, se persistir, fale com a gente. |
Versão
O /v1 não quebra: campo novo pode aparecer, campo existente não muda
de forma nem some. Uma mudança incompatível nasce em /v2, com aviso
antes de o /v1 sair do ar.