API · Emite.Ai

A nota fiscal, por API.

Uma chamada REST cria a nota; a emissão acontece de forma automática e você recebe o resultado por webhook. Feita para volume, com idempotência, sandbox e documentação direta ao ponto.

Visão geral

Emissão fiscal como API

A API da Emite.Ai emite notas fiscais eletrônicas de serviço (NFS-e) e de produto (NF-e) de forma programática. O modelo é assíncrono: você cria a nota com um POST, recebe imediatamente o identificador, e o resultado da emissão chega no seu endpoint por webhook. Sem polling, sem filas do seu lado.

  • Base URL: https://emitenota.ai/api/v1
  • Autenticação: chave de API no header Authorization: Bearer
  • Formato: JSON em requisição e resposta; valores monetários em reais na entrada (150.00) e em centavos na resposta (15000)
Começar

Como funciona

A divisão de responsabilidade é simples: você orquestra do seu lado, a Emite faz toda a máquina fiscal do dela. Você nunca lida com XML, certificado, SEFAZ ou regra de município — envia dados de negócio, recebe uma nota fiscal válida.

No seu lado

Decide quando emitir, manda os dados de cada nota (comprador, valor, serviço) e o CNPJ emissor, e recebe o resultado por webhook para guardar/entregar no seu sistema.

No lado da Emite

Guarda a configuração fiscal do emissor (CNPJ, certificado A1, regime, município) e faz a emissão: monta e assina o XML, transmite ao órgão, gera o PDF, arquiva e reenvia em falha.

O formato da nota é padronizado por lei (o XML é do governo). O que varia por nota — código de serviço, descrição, valores, imposto — você controla em cada chamada. Você consome o resultado como JSON (resposta) + XML + PDF (via webhook/links).

Começar

Guia de integração

O caminho completo, do zero à emissão em produção.

  1. Pegue sua chave. Em Minhas chaves, gere uma chave de sandbox (emite_test_) para desenvolver e uma de produção (emite_live_) para o go-live.
  2. Cadastre a(s) empresa(s) emissora(s). Uma vez por CNPJ: POST /v1/companies e depois envie o certificado A1 em /v1/companies/:id/certificate. Uma empresa só? A que já está na conta serve.
  3. Emita. POST /v1/invoices com os dados da nota (e companyId/cnpj se você tem vários). Use Idempotency-Key — sempre. Para volume, use /batch.
  4. Receba o resultado. Cadastre um webhook e trate invoice.emitted / invoice.failed — sem polling. Valide a assinatura HMAC.
  5. Valide no sandbox. Rode o fluxo inteiro com a chave de teste (sandbox) — sem gerar documento real.
  6. Vá a produção. Troque a chave de teste pela de produção. A mesma requisição funciona nos dois ambientes.
Começar

Início rápido

Da chave à primeira nota em três passos.

1. Pegue sua chave de API

No painel, em Minhas chaves, gere uma chave. Ela começa com emite_live_ (produção) ou emite_test_ (sandbox) e é exibida uma única vez — guarde com segurança.

2. Emita uma nota

cURL
curl -X POST https://emitenota.ai/api/v1/invoices \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Idempotency-Key: pedido-8823" \
  -H "Content-Type: application/json" \
  -d '{
    "buyerName": "João da Silva",
    "buyerDocument": "123.456.789-01",
    "buyerDocType": "CPF",
    "buyerEmail": "joao@exemplo.com",
    "valorNF": 150.00,
    "descricaoServico": "Assinatura mensal — plano Pro",
    "codigoServico": "01.05",
    "aliquotaISS": 5
  }'

3. Receba o resultado por webhook

Cadastre um endpoint de webhook e a Emite avisa quando a nota é emitida, falha ou é cancelada — com o número, o PDF e o XML. Veja Webhooks.

Começar

Autenticação

Toda requisição é autenticada por uma chave de API enviada no header Authorization como Bearer token. Cada chave pertence a uma empresa e só enxerga os dados dela.

cURL
curl https://emitenota.ai/api/v1/organization \
  -H "Authorization: Bearer emite_live_sua_chave"

As chaves têm escopos (ex.: invoices:write, invoices:read), podem ter expiração e são revogáveis a qualquer momento. Nunca exponha a chave no front-end — use-a apenas do seu servidor.

Emissão

Emitir uma nota POST /v1/invoices

Cria e dispara a emissão de uma nota. Responde 201 imediatamente com a nota em PENDING; a emissão prossegue em segundo plano.

Corpo da requisição

CampoTipoDescrição
buyerNamestringobrigatórioNome do tomador
buyerDocumentstringobrigatórioCPF ou CNPJ (com ou sem máscara)
buyerDocType"CPF" | "CNPJ"opcionalPadrão: CPF
buyerEmailstringobrigatórioE-mail para envio da nota
valorNFnumberobrigatórioValor em reais (ex.: 150.00)
descricaoServicostringobrigatórioDescrição do serviço
codigoServicostringobrigatórioCódigo do serviço (LC 116)
aliquotaISSnumberopcionalAlíquota de ISS em % (ex.: 5)
issRetidobooleanopcionalISS retido na fonte. Padrão: false
companyIdstringopcionalEmpresa emissora (multi-CNPJ). Ver Empresas
cnpjstringopcionalCNPJ emissor (alternativa a companyId)

Cada nota carrega seu próprio serviço — codigoServico, descricaoServico, aliquotaISS e issRetido valem por nota, então você pode emitir serviços diferentes na mesma integração.

Exemplo — Node.js

Node.js
const res = await fetch("https://emitenota.ai/api/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.EMITE_API_KEY}`,
    "Idempotency-Key": pedidoId,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    buyerName: "João da Silva",
    buyerDocument: "12345678901",
    buyerDocType: "CPF",
    buyerEmail: "joao@exemplo.com",
    valorNF: 150.0,
    descricaoServico: "Assinatura mensal — plano Pro",
    codigoServico: "01.05",
    aliquotaISS: 5,
  }),
});

const nota = await res.json();
// { id: "inv_a1b2c3d4", status: "PENDING", ... }

Resposta — 201

JSON
{
  "id": "inv_a1b2c3d4",
  "status": "PENDING",
  "valorNF": 15000,
  "buyerName": "João da Silva",
  "buyerDocument": "12345678901",
  "createdAt": "2026-07-10T13:20:41.000Z",
  "message": "NF criada e emissao iniciada"
}
Emissão

Empresas (multi-CNPJ) GET /v1/companies

Uma conta pode ter várias empresas emissoras (CNPJs). Para escolher por qual empresa emitir, envie companyId ou cnpj no corpo da emissão. Sem esses campos, emitimos pela empresa primária da conta.

Liste as empresas disponíveis e seus ids:

cURL
curl https://emitenota.ai/api/v1/companies \
  -H "Authorization: Bearer emite_live_sua_chave"
JSON
{
  "data": [
    { "id": "co_a1b2", "cnpj": "11222333000144", "razaoSocial": "ACME LTDA",
      "isPrimary": true, "municipio": "São Paulo", "uf": "SP" },
    { "id": "co_c3d4", "cnpj": "55666777000188", "razaoSocial": "ACME FILIAL LTDA",
      "isPrimary": false, "municipio": "Rio de Janeiro", "uf": "RJ" }
  ]
}

Emitindo por uma empresa específica

cURL
curl -X POST https://emitenota.ai/api/v1/invoices \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "companyId": "co_c3d4",
    "buyerName": "João da Silva",
    "buyerDocument": "12345678901",
    "buyerEmail": "joao@exemplo.com",
    "valorNF": 150.00,
    "descricaoServico": "Assinatura",
    "codigoServico": "01.05",
    "aliquotaISS": 5
  }'
Cada empresa emissora precisa estar configurada na conta (CNPJ, certificado digital, regime, município). Um companyId/cnpj que não existe na conta retorna 422.

Cadastrar empresa POST /v1/companies

Para onboarding de muitos CNPJs, cadastre empresas pela API. Depois envie o certificado A1 de cada uma.

cURL
curl -X POST https://emitenota.ai/api/v1/companies \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "cnpj": "11.222.333/0001-44",
    "razaoSocial": "ACME LTDA",
    "regimeTributario": "SIMPLES_NACIONAL",
    "inscricaoMunicipal": "1234567",
    "municipio": "São Paulo",
    "uf": "SP",
    "codigoMunicipio": "3550308",
    "cep": "01001-000",
    "logradouro": "Praça da Sé", "numero": "100", "bairro": "Sé"
  }'

Enviar certificado A1 POST /v1/companies/:id/certificate

O certificado .pfx vai em base64 no corpo JSON. Validamos o PFX, a senha e conferimos que o CNPJ do certificado bate com o da empresa.

cURL
curl -X POST https://emitenota.ai/api/v1/companies/co_a1b2/certificate \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "certificateBase64": "<conteúdo do .pfx em base64>",
    "password": "senha-do-certificado"
  }'
JSON
{
  "id": "cert_9x8y",
  "commonName": "ACME LTDA:11222333000144",
  "issuer": "AC Certificadora",
  "expiresAt": "2027-01-15T12:00:00.000Z",
  "status": "VALID"
}
O certificado é criptografado em repouso (AES-256-GCM) e nunca é retornado pela API — só os metadados (validade, titular). CNPJ do cert diferente do da empresa retorna 422.
Emissão

Emissão em lote POST /v1/invoices/batch

Para alto volume, envie até 500 notas numa única requisição. Cada item é independente — um erro em um não derruba os demais. Cada item aceita um idempotencyKey próprio (mesma garantia da emissão avulsa).

cURL
curl -X POST https://emitenota.ai/api/v1/invoices/batch \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "invoices": [
      { "idempotencyKey": "pedido-1", "buyerName": "João", "buyerDocument": "12345678901",
        "buyerEmail": "joao@exemplo.com", "valorNF": 150.0,
        "descricaoServico": "Assinatura", "codigoServico": "01.05", "aliquotaISS": 5 },
      { "idempotencyKey": "pedido-2", "buyerName": "Maria", "buyerDocument": "98765432100",
        "buyerEmail": "maria@exemplo.com", "valorNF": 90.0,
        "descricaoServico": "Assinatura", "codigoServico": "01.05", "aliquotaISS": 5 }
    ]
  }'

Resposta — 200 (ou 207 com falhas parciais)

JSON
{
  "results": [
    { "index": 0, "status": "created", "id": "inv_a1b2", "invoiceStatus": "PENDING" },
    { "index": 1, "status": "error", "error": "Campos obrigatorios: ..." }
  ],
  "summary": { "total": 2, "created": 1, "replayed": 0, "failed": 1 }
}
O status HTTP é 207 quando há falhas parciais — verifique cada item em results. Acompanhe a emissão de cada nota pelos webhooks.
Emissão

Consultar status GET /v1/invoices/:id

Retorna o estado atual da nota, com número, links de PDF e XML quando emitida.

cURL
curl https://emitenota.ai/api/v1/invoices/inv_a1b2c3d4 \
  -H "Authorization: Bearer emite_live_sua_chave"

Estados possíveis: PENDINGPROCESSING EMITTED · FAILED · CANCELLED. Em vez de consultar em loop, prefira os webhooks.

Emissão

Listar notas GET /v1/invoices

Lista paginada, com filtros. Máximo de 100 por página.

ParâmetroDescrição
pagePágina (padrão 1)
limitItens por página (padrão 20, máx 100)
statusFiltra por estado (EMITTED, FAILED, …)
buyerDocumentCPF/CNPJ do tomador
startDate · endDateIntervalo (ISO 8601)
cURL
curl "https://emitenota.ai/api/v1/invoices?status=EMITTED&limit=50" \
  -H "Authorization: Bearer emite_live_sua_chave"
Emissão

Cancelar POST /v1/invoices/:id/cancel

Cancela uma nota. Para notas já emitidas, informe a justificativa (15 a 255 caracteres); o cancelamento é processado junto ao órgão e confirmado por webhook.

cURL
curl -X POST https://emitenota.ai/api/v1/invoices/inv_a1b2c3d4/cancel \
  -H "Authorization: Bearer emite_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{ "justificativa": "Cancelamento a pedido do cliente" }'
Confiabilidade

Idempotência

Envie o header Idempotency-Key com um valor único por operação (ex.: o id do pedido no seu sistema). Se a mesma requisição for reenviada — por timeout, retry ou falha de rede — a Emite devolve a nota original em vez de emitir uma segunda.

Em alto volume, use sempre. É a garantia de que um retry nunca gera nota duplicada. A chave é válida por 72 horas. Reenviar a mesma chave com um corpo diferente retorna 409 Conflict.
HTTP
POST /api/v1/invoices
Authorization: Bearer emite_live_sua_chave
Idempotency-Key: pedido-8823
Confiabilidade

Webhooks

Cadastre uma URL e a Emite envia um POST a cada mudança de estado terminal da nota. Assim você não precisa consultar status em loop.

EventoQuando dispara
invoice.emittedNota emitida com sucesso
invoice.failedEmissão falhou (com a causa)
invoice.cancelledNota cancelada

Payload

JSON
{
  "event": "invoice.emitted",
  "id": "inv_a1b2c3d4",
  "status": "EMITTED",
  "nfseNumero": "123456",
  "nfsePdfUrl": "https://emitenota.ai/.../danfse.pdf",
  "emittedAt": "2026-07-10T13:20:57.000Z"
}

Verificando a assinatura

Cada entrega inclui o header X-Emite-Signature — um HMAC-SHA256 do corpo com o segredo do seu webhook. Valide antes de confiar no payload.

Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

function verificarAssinatura(rawBody, signature, secret) {
  const esperado =
    "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(signature);
  const b = Buffer.from(esperado);
  return a.length === b.length && timingSafeEqual(a, b);
}

Responda 2xx em até alguns segundos. Entregas que falham são reenviadas com backoff.

Confiabilidade

Sandbox

Gere uma chave que começa com emite_test_ em Minhas chaves. Requisições com chave de teste são validadas normalmente e retornam uma resposta simulada de emissão — sem gerar documento fiscal real, sem tocar o órgão fiscal e sem consumir cota. A resposta inclui "sandbox": true.

A mesma requisição funciona em sandbox e produção — só muda a chave. Use o sandbox para validar autenticação, formato da requisição e o shape da resposta antes de ir a produção.
Confiabilidade

Rate limits

Cada resposta traz os headers X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Ao exceder, a API responde 429 com Retry-After. Limites são ajustados conforme o volume contratado — fale com a gente para operações de alto volume.

Confiabilidade

Erros

Respostas de erro usam o status HTTP adequado e trazem error + message legíveis no corpo.

JSON
// 422 — CNPJ do certificado não bate com a empresa
{
  "error": "COMPANY_NOT_FOUND",
  "message": "companyId 'co_x' não encontrado nesta conta."
}
CódigoSignificado
400Requisição inválida (campo faltando ou mal formado)
401Chave ausente, inválida ou expirada
403Sem permissão (scope) ou limite do plano atingido
404Recurso não encontrado
409Conflito de idempotência (ou empresa/CNPJ já existe)
422Dados válidos mas não processáveis (ex: companyId/CNPJ inexistente)
429Rate limit excedido
5xxErro interno — pode retentar (com Idempotency-Key)
Referência

Endpoints

POST/v1/invoicesCria e emite uma nota
POST/v1/invoices/batchEmite até 500 notas em lote
GET/v1/invoicesLista notas
GET/v1/invoices/:idConsulta uma nota
POST/v1/invoices/:id/cancelCancela uma nota
GET/v1/companiesLista empresas emissoras (multi-CNPJ)
POST/v1/companiesCadastra uma empresa emissora
POST/v1/companies/:id/certificateEnvia o certificado A1 (base64)
GET/v1/productsLista produtos
GET/v1/organizationDados fiscais da empresa

Pronto para começar? Gere sua chave de API e emita a primeira nota.