Nota Plena · API
Documentação da API
Com a API da Nota Plena, o sistema da sua empresa emite, cancela e consulta as próprias NFS-e (notas de serviço), baixa o PDF de cada nota e recebe webhooks quando o resultado sai na prefeitura.
Para quem é
- Uma clínica que emite a nota assim que a consulta é paga no sistema de agendamento e guarda o PDF no prontuário financeiro.
- Uma consultoria que fecha as horas do mês na planilha ou no ERP e emite as notas de todos os clientes de uma vez, com conciliação automática pela lista de notas.
- Um SaaS que emite em nome dos seus clientes (por exemplo, um sistema de gestão para prestadores de serviço). Esse modelo usa a API para plataformas, liberada por acordo comercial. Veja como solicitar.
Acesso e cobertura
Chave de API: incluída no plano Negócio. Os planos e o que cada um inclui estão em notaplena.com.br/precos.
Cobertura. A emissão está em produção em São Paulo (capital), Bertioga e Itupeva. Nas demais cidades, a Nota Plena está pronta para as 2.886 cidades do padrão nacional. Antes de integrar, confira a sua cidade em notaplena.com.br/nfse ou consulte GET /api/v1/integrations/tenant/readiness com a sua chave.
Contador. A Nota Plena exporta as notas e os XMLs do período (em Histórico, no painel) para você enviar ao seu contador. Não há integração direta com sistemas contábeis: a troca é por exportação de XML.
Autenticação
Toda requisição usa uma chave de empresa, que só acessa a empresa que a criou. O dono da empresa cria a chave no painel, em Configurações → Integrações → Nova chave. A chave aparece uma única vez; guarde-a em um cofre de segredos.
Envie a chave no header de toda requisição:
Authorization: Bearer np_live_xxxxxxxx403. É a opção indicada para assistentes de IA, planilhas e ferramentas financeiras.Limite de uso
Cada chave é limitada a 120 requisições por minuto (janela deslizante) nas rotas de emissão e cancelamento. Acima disso, a resposta é 429.
URL base
https://api.notaplena.com.brTodos os endpoints abaixo usam essa origem. As respostas são JSON, e o corpo de erro segue o formato:
{ "detail": "Mensagem em português explicando o erro" }Especificação OpenAPI das rotas da chave de empresa, sem autenticação: api.notaplena.com.br/api/v1/integrations/tenant/openapi.json (só as rotas de leitura: ?scope=read).
Consultar a empresa e as notas
Qual empresa é esta chave
/api/v1/integrations/tenantcurl https://api.notaplena.com.br/api/v1/integrations/tenant \
-H "Authorization: Bearer np_live_xxxxxxxx"Devolve id, cnpj, razao_social, nome_fantasia, a cidade (ibge_city_code) e o regime. Serve como teste de conexão.
O que falta para emitir
/api/v1/integrations/tenant/readiness{
"can_emit": false,
"blocks": [
{
"code": "no_cert",
"message": "Você ainda não pode emitir: falta o certificado digital A1 da empresa. ...",
"action_label": "Enviar certificado",
"action_url": "https://notaplena.com.br/settings#certificado"
}
],
"default_codigo_servico": "02684",
"default_descricao": "Consultoria",
"servicos_usados": [
{
"codigo_servico": "02684",
"aliquota_iss": "0.0200",
"exemplo_discriminacao": "Consultoria de outubro",
"notas": 41,
"ultima_em": "2026-10-20T14:00:00Z"
}
]
}- Cada item de
blocksé um passo que só a pessoa faz (certificado A1, inscrição municipal, plano), com o link da tela que resolve. Certificado e senha nunca passam pela API. servicos_usados: os pares de código de serviço e alíquota com que a empresa já emitiu (até 10, os mais usados primeiro). Use-os na emissão em vez de adivinhar.
Listar as notas
/api/v1/integrations/tenant/emissionscurl "https://api.notaplena.com.br/api/v1/integrations/tenant/emissions?status=success,imported&period_start=2026-10-01T00:00:00-03:00&period_end=2026-10-31T23:59:59-03:00&limit=200&offset=0" \
-H "Authorization: Bearer np_live_xxxxxxxx"Resposta 200
{
"items": [
{
"id": "9c1fa402-3c29-4bbb-9210-baf4cc2a4231",
"created_at": "2026-10-14T13:02:11-03:00",
"status": "success",
"source": "emitted",
"numero_nfse": "1023",
"codigo_verificacao": "NMTBGWKL",
"tomador_nome": "Ana Maria Pereira",
"tomador_documento": "12345678901",
"valor_servicos": "650.00",
"discriminacao": "Consulta de fisioterapia — 4 sessões",
"codigo_servico": "04.08",
"aliquota_iss": "0.02",
"error_message": null,
"cancelled_at": null
}
],
"total": 1,
"limit": 200,
"offset": 0
}- As mais novas vêm primeiro.
limitvai até 200; avance ooffsetaté passar detotal. status:success(emitida),imported(emitida fora da Nota Plena e importada),erroroupending. Para vários, separe por vírgula; sem o filtro, vem tudo.- Nota cancelada:
cancelled_atpreenchido. period_starteperiod_endfiltram pela data de registro da nota (ISO 8601 com fuso).
Emitir NFS-e
/api/v1/integrations/tenant/nfseEmite uma NFS-e do CNPJ da sua chave. A Nota Plena escolhe o caminho (sistema da prefeitura ou padrão nacional), assina com o certificado A1 da empresa e devolve a nota.
curl -X POST https://api.notaplena.com.br/api/v1/integrations/tenant/nfse \
-H "Authorization: Bearer np_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: fatura-2026-10-0042" \
-d '{
"valor_servicos": "4800.00",
"discriminacao": "Consultoria financeira — outubro/2026",
"codigo_servico": "17.01",
"aliquota_iss": "0.02",
"tomador_nome": "Comercial Exemplo LTDA",
"tomador_documento": "11222333000181",
"tomador_email": "financeiro@exemplo.com.br",
"tomador_cep": "04023-062"
}'Resposta 200
{
"emission_id": "9c1fa402-3c29-4bbb-9210-baf4cc2a4231",
"status": "success",
"numero_nfse": "1023",
"codigo_verificacao": "NMTBGWKL",
"numero_rps": "88",
"serie_rps": "A",
"valor_servicos": "4800.00",
"error_message": null,
"error": null
}status: success (emitida na prefeitura), error (recusada; error_message e o objeto error trazem o motivo) ou pending (em processamento; a nota ainda não tem número. Aguarde o webhook nfse.emitted ou nfse.failed e não reenvie).
Uma recusa da prefeitura (dados fiscais errados, por exemplo) chega como HTTP 200 com status: "error", e não como erro HTTP. Use o objeto estruturado error ({ code, field, hint }) para decidir o que fazer no seu código; error_message é o texto original da prefeitura. Veja Erros e retentativas.
Opcional, só para tomador com CNPJ: tomador_inscricao_municipal (inscrição municipal do tomador, só números, de 1 a 12 dígitos). Envie apenas se o cliente pediu.
Idempotência
O header Idempotency-Key (até 80 caracteres) é obrigatório na emissão: sem ele, a resposta é 422 IDEMPOTENCY_KEY_REQUIRED e nada é emitido. Reenviar a mesma chave devolve a mesma nota, nunca uma segunda. Use uma referência única do seu sistema, como o número da fatura ou do atendimento.
Idempotency-Key só devolve aquele desfecho. Para retentar de verdade, mande a mesma raiz com um sufixo: <chave>-r2, -r3… A Nota Plena reconhece que é a mesma venda e, se a tentativa anterior já tiver virado nota, devolve a nota existente.Bloqueio de cobrança (402)
Se a assinatura estiver em atraso ou suspensa, a emissão é negada com 402 e a mensagem explica o que fazer:
HTTP/1.1 402 Payment Required
{
"detail": "Conta suspensa por atraso de pagamento. Regularize em notaplena.com.br/billing."
}Se a empresa não está mais no plano Negócio, a resposta é 402 com error.code = "PLAN_NOT_ELIGIBLE". A chave continua existindo (é possível ler e revogar), mas não emite nem cancela.
Cancelar NFS-e
/api/v1/integrations/tenant/nfse/{emission_id}/cancelCancela na prefeitura uma NFS-e da sua empresa. As regras são as mesmas do cancelamento pelo painel: o prazo de 180 dias e a confirmação para nota de mês anterior não podem ser contornados pela API. Quando o cancelamento é concluído, o webhook nfse.cancelled é enviado.
curl -X POST https://api.notaplena.com.br/api/v1/integrations/tenant/nfse/9c1fa402-3c29-4bbb-9210-baf4cc2a4231/cancel \
-H "Authorization: Bearer np_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"reason": "Consulta desmarcada — pagamento estornado",
"confirm_outside_window": false
}'Resposta 200
{
"success": true,
"error_message": null,
"requires_extra_confirmation": false,
"days_since_emission": 0
}reasoné obrigatório (mínimo de 3 caracteres) e vai para a prefeitura como motivo. Vazio responde422.- Nota de um mês anterior, ainda dentro de 180 dias: a primeira chamada volta
success: falsecomrequires_extra_confirmation: true. Repita comconfirm_outside_window: truepara confirmar. - Nota com mais de 180 dias: o cancelamento comum não é mais permitido. A resposta é
success: falsee oerror_messageexplica o caminho (nota de substituição ou processo na prefeitura). 409: a nota já estava cancelada.502: o pedido foi enviado, mas a prefeitura não respondeu. Repita a chamada: ela confere o estado antes de pedir de novo.404: a nota não existe ou não é da sua empresa.
Ler uma NFS-e
/api/v1/integrations/emissions/{emission_id}Retorna os dados de uma NFS-e. O emission_id é o UUID devolvido na emissão ou na lista de notas.
curl https://api.notaplena.com.br/api/v1/integrations/emissions/9c1fa402-3c29-4bbb-9210-baf4cc2a4231 \
-H "Authorization: Bearer np_live_xxxxxxxx"Resposta 200
{
"id": "9c1fa402-3c29-4bbb-9210-baf4cc2a4231",
"created_at": "2026-10-14T13:02:11-03:00",
"status": "success",
"numero_nfse": "1023",
"codigo_verificacao": "NMTBGWKL",
"tomador_nome": "Comercial Exemplo LTDA",
"tomador_documento": "11222333000181",
"valor_servicos": "4800.00",
"discriminacao": "Consultoria financeira — outubro/2026",
"pdf_url": null
}pdf_url é o link de impressão no site da prefeitura e só existe para São Paulo (nas outras cidades vem null). Para o PDF de qualquer cidade, use Baixar o PDF. Uma emissão com status: "error" traz também error_message e error.
Baixar o PDF da NFS-e
/api/v1/integrations/emissions/{emission_id}/pdfDevolve o PDF da nota (DANFSe), pronto para mostrar ou anexar, em todas as cidades em que a nota foi emitida.
curl https://api.notaplena.com.br/api/v1/integrations/emissions/9c1fa402-3c29-4bbb-9210-baf4cc2a4231/pdf \
-H "Authorization: Bearer np_live_xxxxxxxx" \
-o NF-1023.pdf200comContent-Type: application/pdfe nome de arquivoNF-<número>.pdf.409: a nota ainda não foi emitida com sucesso.502: não foi possível gerar o PDF agora; tente de novo em instantes.
Webhooks
Cada chave tem as próprias assinaturas. Cada assinatura recebe um secret que assina o corpo do evento (HMAC-SHA256); o secret aparece uma única vez, na criação.
Eventos
nfse.emitted: NFS-e emitida com sucesso.nfse.failed: emissão recusada pela prefeitura.nfse.cancelled: NFS-e cancelada.
Garantias de entrega
- Cada desfecho chega. Se o envio de um evento se perder, uma varredura periódica percebe a falta e envia o evento com o mesmo conteúdo.
- Uma vez por nota. O mesmo evento sobre a mesma nota é enfileirado no máximo uma vez por assinatura. Ainda assim, trate o receptor como idempotente por
emission_id: uma entrega cuja confirmação HTTP se perdeu é reenviada. - "failed" só quando há certeza. Quando o desfecho é incerto (o pedido pode ter chegado à prefeitura e a resposta se perdeu), nenhum webhook é enviado até a confirmação.
Criar, listar e revogar
/api/v1/integrations/tenant/webhooks/api/v1/integrations/tenant/webhooks/api/v1/integrations/tenant/webhooks/{subscription_id}curl -X POST https://api.notaplena.com.br/api/v1/integrations/tenant/webhooks \
-H "Authorization: Bearer np_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seu-sistema.com.br/webhooks/nota-plena",
"events": ["nfse.emitted", "nfse.failed"]
}'events vazio ([]) assina todos os eventos. Evento desconhecido responde 422. O secret não volta na listagem; se perdê-lo, revogue a assinatura e crie outra.
Erros e retentativas
A regra geral: o status HTTP diz de quem é o problema. Retentar do jeito errado ou repete o mesmo erro ou arrisca uma nota duplicada. Abaixo, cada desfecho e a ação indicada.
Prefeitura fora do ar — 503 PREFEITURA_UNAVAILABLE
A prefeitura não respondeu. O seu pedido está correto e é seguro retentar, com a mesma raiz e o sufixo -r2, -r3… (a mesma chave só devolve este erro). Esta resposta não traz Retry-After: aguarde alguns minutos antes de retentar.
HTTP/1.1 503 Service Unavailable
{
"detail": {
"message": "O servidor da prefeitura está offline. Tente novamente mais tarde com uma Idempotency-Key de RETENTATIVA — a mesma raiz com sufixo -r2, -r3 …",
"error": { "code": "PREFEITURA_UNAVAILABLE", "retriable": true }
}
}Emissão pausada no município — 503 EMISSAO_PAUSADA_MUNICIPIO
A prefeitura recusou várias emissões seguidas desta empresa por um motivo que não está na nota (por exemplo, o cadastro municipal), e as emissões foram pausadas para não gastar RPS. Nenhuma nota nem Idempotency-Key foi consumida: respeite o header Retry-After (em segundos) e reenvie o mesmo pedido com a mesma chave.
Duplicidade não verificável — 422 DUPLICATE_RISK_UNVERIFIABLE
Uma tentativa anterior desta mesma venda pode ter chegado à prefeitura sem confirmação. Não retente às cegas. Confira no portal da prefeitura ou em notaplena.com.br/problemas e, se a nota de fato não existir, emita novamente.
Chave reusada para outra venda — 422 IDEMPOTENCY_KEY_REUSED
A Idempotency-Key já pertence a outra nota, com dados diferentes. Nenhuma nota nova foi emitida. Use uma chave nova para esta venda.
Validação — 422
Recusado antes de ir à prefeitura: campo obrigatório ausente, tipo errado, certificado ausente ou vencido (NO_CERT / CERT_EXPIRED), inscrição municipal faltando (NO_INSCRICAO_MUNICIPAL), cidade ainda não atendida (CITY_UNSUPPORTED) ou código de tributação nacional ausente ou inválido (CTRIBNAC_MISSING / CTRIBNAC_INVALID). Corrija o pedido; repetir igual não muda o resultado.
Resumo
| Desfecho | Retentar? | Como |
|---|---|---|
503 PREFEITURA_UNAVAILABLE | Sim | Mesma raiz + -rN |
503 EMISSAO_PAUSADA_MUNICIPIO | Sim, após Retry-After | Mesma chave, mesmo pedido |
422 DUPLICATE_RISK_UNVERIFIABLE | Só após conferir | Confira no portal ou em /problemas |
422 IDEMPOTENCY_KEY_REUSED | Sim, com chave nova | Chave nova para a venda nova |
| 422 validação, certificado ou cidade | Só após corrigir | Ajuste o pedido conforme o hint |
200 status: "error" | Só após corrigir os dados | Corrija conforme error.hint; chave nova ou -rN |
| 402 cobrança | Não, até regularizar | Mostre a mensagem de detail a quem administra a conta |
status: "pending" | Não | Aguarde o webhook |
| 429 | Sim | Espere alguns segundos; limite de 120 req/min por chave |
Códigos de status
| Status | Significado |
|---|---|
400 | Requisição inválida (JSON malformado, header faltando) |
401 | Chave ausente, mal formada ou revogada |
402 | Emissão bloqueada por cobrança ou por plano sem API |
403 | Chave só de leitura em rota de escrita, ou link de visualização que não é desta nota |
404 | O recurso não existe ou não é da sua empresa |
409 | Conflito de estado (nota já cancelada, PDF de nota não emitida) |
422 | Validação falhou; o detail diz o campo |
429 | Limite de 120 requisições por minuto por chave |
502 / 503 | Prefeitura sem resposta ou emissão pausada; veja Erros e retentativas |
Para plataformas: emitir em nome dos seus clientes
Se o seu produto é um SaaS ou ERP e você quer emitir as notas dos seus clientes (cada um com o próprio CNPJ e certificado), use a API para plataformas. Ela é liberada por acordo comercial, com condições definidas caso a caso. Fale com o nosso time comercial para avaliar a integração.
Como começar
- Assine o plano Negócio e cadastre a empresa, com o certificado A1, pelo painel.
- Crie a chave em Configurações → Integrações e confira
GET /integrations/tenant/readiness. - Emita com uma
Idempotency-Keyderivada da sua fatura ou atendimento e assine os webhooks.