Prévia: a API abre junto com o painel.
Emitir a primeira nota
Em cinco minutos, no ambiente de teste: sem certificado digital e sem valor fiscal.
1. Pegue a chave de teste
Crie a conta e copie a chave nfs_test_... no painel. Deixe numa variável de ambiente:
export NFSEIA_CHAVE="nfs_test_sua_chave"Confira se ela funciona e veja os padrões da nota da sua empresa (código de serviço, descrição, impostos):
curl https://api.nfseia.com.br/v1/empresa \
-H "Authorization: Bearer $NFSEIA_CHAVE"2. Emita
O mínimo é a referência do pedido, o tomador e o valor. O que você não mandar de serviço e impostos vem dos padrões da empresa. Se o tomador ainda não estiver salvo, mande também o nome.
curl -X POST https://api.nfseia.com.br/v1/notas \
-H "Authorization: Bearer $NFSEIA_CHAVE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7d4f8c2a-1b3e-4f6a-9c0d-2e5b8a1f3c7d" \
-d '{
"referencia_externa": "pedido-1042",
"tomador": {
"documento": "12345678000195",
"nome": "Padaria Pão Quente Ltda",
"email": "[email protected]"
},
"servico": { "descricao": "Manutenção do site, novembro de 2026" },
"valores": { "valor_servico": "1500.00" }
}'Em Node (18 ou mais novo, sem biblioteca):
import { randomUUID } from 'node:crypto';
const resposta = await fetch('https://api.nfseia.com.br/v1/notas', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NFSEIA_CHAVE}`,
'Content-Type': 'application/json',
// Gere uma vez por tentativa e reutilize se precisar repetir a mesma chamada.
'Idempotency-Key': randomUUID(),
},
body: JSON.stringify({
referencia_externa: 'pedido-1042',
tomador: {
documento: '12345678000195',
nome: 'Padaria Pão Quente Ltda',
email: '[email protected]',
},
servico: { descricao: 'Manutenção do site, novembro de 2026' },
valores: { valor_servico: '1500.00' },
}),
signal: AbortSignal.timeout(35_000),
});
const corpo = await resposta.json();
if (resposta.status === 201 || resposta.status === 200) {
console.log(`Nota ${corpo.numero} ${corpo.status}`, corpo.links.pdf);
} else if (resposta.status === 202) {
console.log('Nota pendente; o webhook avisa quando sair.', corpo.id);
} else {
console.error(corpo.erro.mensagem, corpo.erro.como_resolver, corpo.erro.detalhes);
}Em Python (com requests):
import os
import uuid
import requests
resposta = requests.post(
"https://api.nfseia.com.br/v1/notas",
headers={
"Authorization": f"Bearer {os.environ['NFSEIA_CHAVE']}",
# Gere uma vez por tentativa e reutilize se precisar repetir a mesma chamada.
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"referencia_externa": "pedido-1042",
"tomador": {
"documento": "12345678000195",
"nome": "Padaria Pão Quente Ltda",
"email": "[email protected]",
},
"servico": {"descricao": "Manutenção do site, novembro de 2026"},
"valores": {"valor_servico": "1500.00"},
},
timeout=35,
)
corpo = resposta.json()
if resposta.status_code in (200, 201):
print(f"Nota {corpo['numero']} {corpo['status']}", corpo["links"]["pdf"])
elif resposta.status_code == 202:
print("Nota pendente; o webhook avisa quando sair.", corpo["id"])
else:
print(corpo["erro"]["mensagem"], corpo["erro"]["como_resolver"], corpo["erro"]["detalhes"])3. Entenda a resposta
| Status | O que aconteceu | O que fazer |
|---|---|---|
201 |
Nota autorizada. | Guarde id, numero e chave_acesso. |
200 |
Já havia nota com essa referencia_externa. |
Trate como sucesso: é a mesma nota. |
202 |
Nota pendente, com o motivo em pendencia.motivo (por exemplo, a SEFIN não respondeu a tempo). |
Espere o webhook nota.pendente_resolvida ou consulte depois. Não emita de novo com outra referência. |
400 |
Dados recusados antes do envio. | Corrija os campos de erro.detalhes. |
422 |
A SEFIN recusou a nota de forma definitiva. | Corrija conforme erro.detalhes e emita de novo com a mesma referência e uma Idempotency-Key nova. |
429 ou 5xx |
Limite ou falha temporária. | Repita com a mesma Idempotency-Key, depois do Retry-After. |
Os códigos e o formato dos erros estão em Erros e limites.
4. Teste os caminhos difíceis
No ambiente de teste, um marcador na descrição do serviço força o resultado:
[simular:rejeitada]: a SEFIN simulada recusa a nota (422 nota_rejeitada).[simular:pendente]: a nota ficapendente(202) e vira autorizada em cerca de 1 minuto, com os eventosnota.pendente_resolvidaenota.autorizada.
Exemplo: "descricao": "Manutenção do site [simular:pendente]".
5. Baixe o PDF e o XML
curl https://api.nfseia.com.br/v1/notas/nota_01JC8Z4M3QK7T2V9X5B6N1R0PD/pdf \
-H "Authorization: Bearer $NFSEIA_CHAVE" -o nota.pdfO XML oficial fica em /xml, guardado por 5 anos. No teste, o PDF sai com a marca "sem valor
fiscal".
6. Vá para a produção
- Envie o certificado digital A1 (e-CNPJ) da empresa pelo link de envio do painel. O arquivo vai direto para o cofre; nem o painel nem a API veem o certificado aberto.
- Libere a produção no painel e confirme pelo e-mail da empresa.
- Crie a chave
nfs_live_...e troque no seu sistema. O código é o mesmo.
O teste grátis vale 5 notas reais ou 7 dias, o que vier primeiro. O ambiente de teste continua de graça depois.