Notanexo
Entrar Começar grátis →

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

Ver o documento OpenAPI (fonte de verdade)

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.

PlanoEmissões/minLeituras/minEmissões simultâneas
Grátis e EssencialSem API
Profissional201203
Multiempresa301805

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

StatusO que significa
PROCESSINGDocumento criado, transmissão em andamento; ainda sem veredito da SEFAZ.
AUTHORIZEDAutorizado. XML e DANFE já disponíveis.
REJECTEDRejeitado pela SEFAZ; o motivo vem em sefaz.cStat e sefaz.xMotivo.
CANCELLEDCancelado, dentro ou fora do prazo (com acknowledgeDeadline).
CONTINGENCY_PENDINGEmitido 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
01dinheiro, cash
02cheque
03credito, credit_card
04debito, debit_card
15boleto
17pix

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ódigoHTTPO que fazer
SCHEMA_VALIDATION_ERROR400Corpo ou parâmetros fora do schema; details.issues traz o caminho de cada campo.
VALIDATION_ERROR400, 409 ou 422Regra 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_REQUIRED400Cabeçalho Idempotency-Key ausente, ou fora do formato (1 a 255 caracteres ASCII visíveis).
API_KEY_INVALID401Confira o cabeçalho Authorization: Bearer nx_….
API_KEY_REVOKED401Chave revogada no painel; crie outra.
API_SCOPE_INSUFFICIENT403A chave é READ e a rota exige WRITE.
PLAN_LIMIT_REACHED403Causa 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_INACTIVE403Organização cancelada (só consulta), ou emissão em produção sem assinatura ativa; regularize o plano.
NOT_FOUND404Documento não existe para esta chave (empresa ou ambiente diferente contam como inexistente).
IDEMPOTENCY_KEY_REUSED409Mesma Idempotency-Key com corpo diferente; use uma chave nova.
IDEMPOTENCY_IN_PROGRESS409Já existe uma requisição em andamento com esta chave; aguarde.
SERIES_MISSING409Série não configurada no ambiente; configure em Minha empresa → Séries.
EXTERNAL_ID_TAKEN409Já 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_READY400 ou 409Empresa 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_ENABLED400Empresa não habilitada para o modelo solicitado (NF-e, NFC-e ou NFS-e).
CERTIFICATE_EXPIRED400Certificado da empresa venceu; renove no painel.
CSC_MISSING400NFC-e sem CSC configurado (ou incompleto); configure em Minha empresa → NFC-e.
SEFAZ_REJECTIONnão é erro de requisiçãoA chamada responde 201/202 normalmente; o motivo da rejeição vem em sefaz.cStat/sefaz.xMotivo, dentro do documento.
SEFAZ_TIMEOUTnão é erro de requisiçãoSem veredito nos 15 s, a chamada responde 202; a transmissão continua e o resultado chega pelo GET ou pelo webhook.
CONTINGENCY_REQUIREDnão é erro de requisiçãoerrorCode dentro do payload do webhook DOCUMENT_CONTINGENCY, quando a emissão cai para contingência.
API_RATE_LIMITED429Teto de emissões ou leituras por minuto atingido; respeite Retry-After.
API_CONCURRENCY_LIMIT429A chave já tem o teto de emissões simultâneas em andamento; aguarde uma terminar.
RATE_LIMITED429Muitas tentativas com chave inválida vindas do mesmo IP; aguarde.
INTERNAL_ERROR500Erro 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.

Dúvida que não está aqui? Fale no WhatsApp →