Endpoints
Todos os endpoints são prefixados com https://platform.notaas.com.br/api/v1 e requerem o header x-api-key.
Emissão NFS-e
/emitir🔑 x-api-keyEnfileira uma NFS-e para emissão assíncrona. Retorna 202 com invoiceId para polling.
Body (JSON)
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| tomador.cnpj | string | sim | CNPJ do tomador (14 dígitos, sem formatação). Obrigatório pelo XSD — use CNPJ ou CPF. |
| tomador.cpf | string | não | CPF do tomador (11 dígitos). Alternativo ao CNPJ. |
| tomador.nome | string | sim | Nome ou razão social do tomador. Obrigatório pelo XSD (TCInfoPessoa.xNome). |
| tomador.email | string | não | E-mail do tomador para envio da nota |
| tomador.telefone | string | não | Telefone do tomador (apenas dígitos) |
| tomador.endereco.logradouro | string | não | Logradouro do tomador |
| tomador.endereco.numero | string | não | Número do endereço |
| tomador.endereco.complemento | string | não | Complemento do endereço |
| tomador.endereco.bairro | string | não | Bairro do tomador |
| tomador.endereco.cidade | string | não | Nome da cidade — resolvido para código IBGE automaticamente. Obrigatório se endereco for informado. |
| tomador.endereco.uf | string | não | Sigla do estado (ex: "SP"). Obrigatório se endereco for informado. |
| tomador.endereco.cep | string | não | CEP do tomador (apenas dígitos). Recomendado — XSD exige CEP no endereço nacional. |
| servico.descricao | string | sim | Descrição do serviço prestado |
| servico.codigo | string | não | cTribNac LC 116/2003 — 6 dígitos numéricos (ex: "010700"). Opcional: usa o Código de Tributação padrão do projeto se omitido. ❌ "1.07" → ✅ "010700". Não aplicável para São Paulo. Códigos do Item 99 (ex: "990101" — sem incidência de ISSQN/ICMS): informar aliquotaIss: 0. |
| servico.codigoServico | string | não | Código de serviço SP (4–5 dígitos, ex: "07498"). Opcional para projetos em SP — usa padrão do projeto se omitido. |
| servico.localPrestacao | string | não | Código IBGE 7 dígitos do local de prestação. Opcional — padrão: município do projeto. |
| servico.nbs | string | não | Código NBS — Nomenclatura Brasileira de Serviços (9 dígitos numéricos, ex: "100401000"). Opcional — aplicável apenas para SNNFSE federal (ignorado para SP e ABRASF). Retorna 400 se informado com formato inválido. |
| valores.total | number | sim | Valor bruto do serviço em reais (ex: 1500.00) |
| valores.aliquotaIss | number | sim | Alíquota ISS em % (ex: 2.0 para 2%). Para serviços sem incidência de ISSQN/ICMS (cTribNac do Item 99, ex: "990101"), informar 0. Ignorado automaticamente quando a tributação ISSQN do projeto está configurada como Não Incidência, Imunidade ou Exportação (Settings → Tributação ISSQN). |
| valores.issRetido | boolean | não | ISS retido pelo tomador (padrão: false) |
| valores.totaisTributosAproximados | object | não | Totais aproximados de tributos por esfera — Lei 12.741/2012 (Transparência Fiscal). Campo opcional. Exclusivo para SNNFSE federal. Envie percentuais OU valores em R$, nunca ambos (retorna 400 se misturado). Omitido: Simples Nacional usa alíquota DAS do projeto; demais regimes omitem o campo no XML. |
| ↳ percentualTributacaoFederal | number | não | Opção A (percentual): tributos federais aproximados em % (ex: 4.50). Requer também percentualTributacaoEstadual e percentualTributacaoMunicipal. |
| ↳ percentualTributacaoEstadual | number | não | Opção A (percentual): tributos estaduais aproximados em % (ex: 0.00 — serviços geralmente sem tributo estadual). |
| ↳ percentualTributacaoMunicipal | number | não | Opção A (percentual): tributos municipais (ISS) aproximados em % (ex: 2.00). |
| ↳ valorTributacaoFederal | number | não | Opção B (valor R$): tributos federais em reais (ex: 45.00). Requer também valorTributacaoEstadual e valorTributacaoMunicipal. |
| ↳ valorTributacaoEstadual | number | não | Opção B (valor R$): tributos estaduais em reais (ex: 0.00). |
| ↳ valorTributacaoMunicipal | number | não | Opção B (valor R$): tributos municipais (ISS) em reais (ex: 20.00). |
| competencia | string | não | Competência no formato YYYY-MM (padrão: mês atual) |
| referencia | string | não | Identificador externo opcional (seu sistema) |
{
"tomador": {
"nome": "Empresa Tomadora Ltda",
"cnpj": "12345678000195",
"email": "[email protected]",
"endereco": {
"logradouro": "Rua das Flores",
"numero": "100",
"bairro": "Centro",
"cidade": "Londrina",
"uf": "PR",
"cep": "86010010"
}
},
"servico": {
"descricao": "Desenvolvimento de software sob demanda",
"codigo": "010302"
},
"valores": {
"total": 1000.00,
"aliquotaIss": 2.0,
"issRetido": false,
"totaisTributosAproximados": {
"percentualTributacaoFederal": 6.00,
"percentualTributacaoEstadual": 0.00,
"percentualTributacaoMunicipal": 2.00
}
},
"competencia": "2026-04",
"referencia": "OS-2026-001"
}{
"queued": true,
"invoiceId": "inv_abc123",
"status": "queued",
"pollUrl": "/api/v1/invoices/inv_abc123/status"
}/cancelar🔑 x-api-keySolicita o cancelamento assíncrono de uma NFS-e já emitida (status issued).
Body (JSON)
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| invoiceId | string | sim | ID da nota a cancelar |
| motivo | string | não | Motivo do cancelamento (texto livre, max 255 chars) |
Status & Polling
/invoices/{id}/status🔑 x-api-keyRetorna o status atual de uma NFS-e individual.
Resposta
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| status | string | não | queued | processing | issued | error | cancelled |
| chNFSe | string | não | Chave/código de verificação da NFS-e (disponível quando status=issued) |
| numeroNfe | string | não | Número da NFS-e (disponível quando status=issued) |
| emittedAt | string (ISO 8601) | não | Timestamp de emissão (disponível quando status=issued) |
| ambiente | string | não | "producao" ou "homologacao" (disponível quando status=issued) |
| pdfUrl | string (URL) | não | URL pública CDN do PDF (disponível quando documentsCached=true). Acesso direto, sem autenticação. |
| xmlUrl | string (URL) | não | URL pública CDN do XML (disponível quando documentsCached=true). Acesso direto, sem autenticação. |
| documentsCached | boolean | não | true quando XML e PDF foram armazenados no CDN. URLs disponíveis em pdfUrl e xmlUrl. |
| errorCode | string | não | Código do erro (disponível quando status=error) |
| errorMessage | string | não | Mensagem de erro legível (disponível quando status=error) |
| errors | array | não | Array detalhado de erros da SEFAZ [{Codigo, Descricao, Complemento}] (disponível quando status=error) |
| cancelledAt | string (ISO 8601) | não | Timestamp do cancelamento (disponível quando status=cancelled) |
| cancelXmlUrl | string (URL) | não | URL pública CDN do XML de cancelamento (disponível quando status=cancelled e documentsCached=true) |
Documentos da NFS-e
/invoices/{id}/xml🔑 x-api-keyRetorna o XML da NFS-e. Sem parâmetros, retorna o XML de emissão. Com ?type=cancel, retorna o XML de cancelamento.
Query Parameters
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| type | string | não | Tipo de XML: "emission" (default) ou "cancel". O tipo "cancel" retorna o XML de cancelamento — disponível apenas para notas com status cancelled. |
Comportamento
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| Cache R2 (302) | redirect | não | Quando cacheado no CDN, redireciona para URL pública (cache immutable). |
| Fallback (200) | application/xml | não | Quando não cacheado, retorna o XML do banco com Content-Type application/xml. |
Erros
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| 409 | Conflict | não | Invoice ainda não emitida (status ≠ issued ou cancelled) |
| 409 | Conflict | não | ?type=cancel: nota não está cancelada |
| 404 | Not Found | não | XML não disponível para esta nota |
/invoices/{id}/pdf🔑 x-api-keyRetorna o PDF (DANFSE) da NFS-e. Se cacheado no R2, redireciona (302) para a URL pública CDN. Caso contrário, busca ao vivo no portal municipal.
Comportamento
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| Cache R2 (302) | redirect | não | Quando documentsCached=true, redireciona para URL pública CDN (cache immutable). |
| SNNFSE federal | 200 PDF | não | Fallback: proxy mTLS → ADN Federal (adn.nfse.gov.br) → PDF inline. |
| Pronim (Cidade360) | 200 PDF | não | Fallback: consulta portal Cidade360 e retorna PDF inline. |
| São Paulo (SP) | 302 redirect | não | Fallback: redireciona para o portal da Prefeitura SP. |
| WebISS | 200 PDF / 302 | não | Fallback: GET no portal WebISS (público ou mTLS). |
Erros
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| 409 | Conflict | não | Invoice ainda não emitida (status ≠ issued) |
| 422 | Unprocessable | não | Dados insuficientes: certificado A1 ausente, chave de acesso inválida |
| 501 | Not Implemented | não | Sistema municipal não suporta download de PDF (DSF, Centi) |
| 502 | Bad Gateway | não | Portal externo retornou erro |
Lote (Batch)
/emitir/batch🔑 x-api-keyEmite múltiplas NFS-e de forma assíncrona. Retorna batchId para acompanhamento.
Body (JSON)
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| items | array | sim | Array de objetos com o mesmo formato do POST /emitir |
/invoices/batch/{batchId}/status🔑 x-api-keyRetorna o progresso de um lote: total, processados, emitidos, erros.
Resposta
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| batchId | string | não | ID do lote |
| status | string | não | processing | completed | partial | failed |
| total | number | não | Total de itens no lote |
| processed | number | não | Itens já processados |
| issued | number | não | Itens emitidos com sucesso |
| errors | number | não | Itens com erro |
| items[].invoiceId | string | não | ID da invoice |
| items[].status | string | não | Status individual do item |
| items[].pdfUrl | string (URL) | não | URL para download do PDF (disponível quando status=issued) |
| items[].chNFSe | string | não | Chave/código de verificação (disponível quando status=issued) |
| items[].errorCode | string | não | Código do erro (disponível quando status=error) |
Endpoints de Webhook
/webhooks/endpoints🔑 x-api-keyCadastra um novo endpoint de webhook para a organização/projeto.
Body (JSON)
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| url | string | sim | URL HTTPS que receberá o POST |
| events | string[] | sim | Ex: ["nfse.issued", "nfse.error", "nfse.cancelled", "nfse.documents_ready", "batch.completed"] |
| secret | string | não | Secret para assinatura HMAC-SHA256 via X-Notaas-Signature (opcional) |
/webhooks/endpoints🔑 x-api-keyLista todos os endpoints de webhook configurados.
/webhooks/endpoints/{id}🔑 x-api-keyAtualiza URL, eventos ou status ativo/inativo de um endpoint.
/webhooks/endpoints/{id}🔑 x-api-keyRemove um endpoint de webhook.
/webhooks/endpoints/{id}/test🔑 x-api-keyEnvia um payload de teste para validar a configuração do endpoint.
/webhooks/deliveries🔑 x-api-keyLista o histórico de entregas de webhook com status e tentativas.
Eventos Suportados
Eventos
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| nfse.issued | event | não | NFS-e emitida com sucesso. Payload inclui número da nota e código de verificação. |
| nfse.error | event | não | Falha na emissão. Payload inclui código e mensagem de erro. |
| nfse.cancelled | event | não | NFS-e cancelada com sucesso. Payload inclui invoiceId, numeroNfse e cancelledAt. |
| nfse.documents_ready | event | não | Documentos cacheados no CDN. Payload inclui xmlUrl, pdfUrl, cancelXmlUrl (para notas canceladas) e documentStatus. |
| batch.completed | event | não | Todos os itens de um lote foram processados. |
⚠️ nfse.documents_ready — comportamento de entrega
Este evento pode ser disparado até 2 vezes para a mesma invoice:
- 1ª chamada:
documentStatus: "partial"— XML pronto, PDF pode estar indisponível (pdfUrl: null) - 2ª chamada (até 10 min depois):
documentStatus: "complete"— XML e PDF prontos. Se o retry esgotar sem sucesso, nenhum webhook adicional é enviado.
Use o campo documentStatus para determinar se todos os documentos estão disponíveis.
Para notas canceladas, o payload inclui o campo adicional cancelXmlUrl com a URL do XML de cancelamento. cancelXmlUrl é null para notas emitidas.
Em engines que não emitem PDF (ex.: dsf, centi), o evento chega uma única vez com pdfUrl: null e documentStatus: "complete".
ℹ️ Compatibilidade de Webhook
Campos adicionais podem ser incluídos nos payloads de webhook sem aviso prévio. Seu código deve ignorar campos desconhecidos para manter compatibilidade futura (Postel's Law).