API Pública IntegroBR: NFS-e, NF-e e CT-e (1.0)

Download OpenAPI specification:

API para consultar e gerenciar, de forma programática, as NFS-e (notas de serviço) monitoradas pela sua conta IntegroBR: os mesmos dados que aparecem no painel, disponíveis para integração com o seu ERP, sistema contábil ou automação interna.

Autenticação

Toda chamada exige uma chave de API no cabeçalho Authorization:

Authorization: Bearer ibr_live_xxxxxxxxxxxxxxxxxxxxxxxx

Gere uma chave em Painel → Chaves de API (/painel/chaves-api). Ela é exibida uma única vez no momento da criação — se perder, revogue e crie outra.

Existem dois ambientes de chave, e eles nunca se misturam:

Prefixo Ambiente O que você vê
ibr_test_... Sandbox Só empresas cadastradas como SANDBOX — dados de teste, nunca reais, nunca geram cobrança.
ibr_live_... Produção Só empresas cadastradas como PRODUCAO — dados fiscais reais da sua conta.

Tentar acessar um recurso do ambiente errado com uma chave (ex.: pedir o detalhe de uma empresa de produção usando uma chave sandbox) devolve 404 — nunca 403 — pra não revelar se o recurso existe no outro ambiente.

SDKs oficiais

Clientes oficiais, de código aberto, cobrindo todas as rotas desta página (incluindo paginação por cursor e verificação de assinatura de webhook).

Linguagem Instalação Repositório
Node.js / TypeScript npm install @integrobr/nfse-sdk github.com/integrobr/integrobr-sdk-node
PHP composer require integrobr/nfse-sdk github.com/integrobr/integrobr-sdk-php
Ruby gem install integrobr-nfse-sdk github.com/integrobr/integrobr-sdk-ruby

Não usa Node, PHP ou Ruby? Qualquer cliente HTTP serve — a API é REST simples, sem exigir nenhum SDK.

Servidor MCP: use a IntegroBR direto do seu assistente de IA

O MCP (Model Context Protocol) é o padrão aberto que permite a um assistente de IA consultar sistemas externos. Com o servidor MCP da IntegroBR instalado, você pergunta em português no Claude, no ChatGPT ou em qualquer cliente compatível, e ele responde com os seus dados reais:

  • "Quanto entrou de nota esse mês?"
  • "Algum fornecedor parou de faturar pra gente?"
  • "Me mostra as notas acima de R$ 5.000 de agosto"
  • "Quanto já usei da franquia do plano?"

Instalação

Gere uma chave em Painel → Chaves de API e adicione ao arquivo de configuração do seu cliente MCP. No Claude Desktop, é o claude_desktop_config.json:

{
  "mcpServers": {
    "integrobr": {
      "command": "npx",
      "args": ["-y", "@integrobr/mcp-server"],
      "env": { "INTEGROBR_API_KEY": "ibr_live_..." }
    }
  }
}

Pacote no npm: @integrobr/mcp-server, código aberto sob licença MIT. Uma chave de sandbox (ibr_test_...) funciona igual e não toca em dado de produção: é o jeito seguro de experimentar antes de apontar pra conta real.

Ferramentas disponíveis

Ferramenta O que faz
consultar_conta Nome, status e ambiente da conta ligada à chave
consultar_consumo Franquia usada no ciclo, saldo e excedente
listar_empresas CNPJs monitorados e o estado de cada um
detalhar_empresa Detalhe de um CNPJ, incluindo certificado
listar_documentos NFS-e, NF-e e CT-e capturadas, com filtro de período, fornecedor, valor, tipo e papel
detalhar_documento Documento completo, com prestador, tomador, valores e tributos

Valores em listar_documentos são filtrados em centavos: R$ 1.500,00 é 150000. A própria descrição da ferramenta avisa isso ao modelo.

Somente leitura, e isso é uma decisão de projeto

O servidor MCP da IntegroBR não emite nota, não cancela, não cria empresa e não remove nada. Ele só lê. Os endpoints de escrita desta API existem e funcionam, mas nenhum deles é exposto ao agente.

O motivo é o modelo de ameaça do MCP. Um servidor MCP entrega as ferramentas a um modelo que decide sozinho quando chamá-las, a partir de texto que pode ter vindo de qualquer lugar, inclusive do conteúdo de um documento fiscal que a própria ferramenta acabou de trazer. A descrição do serviço de uma nota é texto livre que qualquer fornecedor escreve. Num servidor que sabe emitir nota, esse texto passa a ser uma superfície de injeção com consequência fiscal real.

Quem precisa automatizar emissão usa a API REST direto, com código que passa por revisão e por um deploy, e não por um modelo decidindo no meio de uma conversa.

Internamente, todo acesso do servidor MCP passa por uma única função que só faz GET. Expor escrita exigiria mudar essa função de propósito, e isso é o atrito que se quer.

Como se compara com o MCP da NFE.io

A NFE.io também publica um servidor MCP, e as duas escolhas de arquitetura são opostas. Vale entender a diferença antes de decidir, porque ela não é de tamanho, é de modelo de confiança. Dados públicos consultados em 2 de setembro de 2026.

IntegroBR NFE.io
Onde roda Local, na sua máquina, por stdio Servidor remoto deles (mcp.nfe.io)
Para onde vai sua chave de API Não sai da sua máquina Trafega até o servidor deles, que a usa em seu nome
O agente pode escrever? Não. Somente leitura Sim. Emite NFS-e e cria empresas
Dá pra auditar o código? Sim, MIT no npm Não. O servidor é fechado
Notas recebidas de fornecedor Sim, NFS-e, NF-e e CT-e Não é o escopo do produto deles
Quantidade de ferramentas 6, todas sobre os seus dados fiscais 21, incluindo consultas públicas (IBGE, CNAE, Selic)

Onde eles são mais convenientes, e é justo dizer: por ser remoto, o deles não exige Node instalado, e boa parte das ferramentas responde sem autenticação nenhuma, o que torna o teste inicial mais rápido.

Onde nós somos mais seguros, e é o que importa quando o agente toca dado fiscal de verdade: sua chave de API nunca sai da sua máquina, e nenhum agente consegue emitir uma nota fiscal em nome da sua empresa através do nosso servidor. Um servidor MCP remoto que emite nota concentra as duas coisas ao mesmo tempo: recebe a sua credencial e tem permissão de escrita com ela.

E, na parte que é a razão de existir da IntegroBR, não há sobreposição: o monitoramento das notas que a sua empresa recebe de fornecedores, incluindo NFS-e, que costuma ser justamente a que fica descoberta.

Paginação

GET /documents usa paginação por cursor (é a única lista que pode crescer sem limite prático). A resposta sempre traz:

{ "itens": [ /* ... */ ], "proximoCursor": "id-do-ultimo-item-ou-null" }

Passe o valor de proximoCursor de volta no parâmetro cursor da próxima chamada — ele é o id do último item da página anterior, não um token opaco. proximoCursor: null significa que não há mais páginas. Um cursor que não existe mais (nunca existiu, ou o item foi removido entre uma chamada e outra) não gera erro — a resposta vem com itens: [] e proximoCursor: null, como se a paginação tivesse chegado ao fim.

GET /companies não é paginado — devolve um array direto com todas as empresas da conta (o volume esperado é baixo o suficiente pra não precisar).

Limite de requisições

120 requisições por minuto, por chave de API (janela fixa de 60s). Passar do limite devolve 429 Too Many Requests:

{ "message": "Limite de requisições excedido. Tente novamente em instantes.", "code": "RATE_LIMITED" }

Erros

Erros seguem sempre o mesmo formato:

{ "statusCode": 404, "message": "Empresa não encontrada nesta conta.", "error": "Not Found" }

message pode ser uma string única ou uma lista de strings (erro de validação de campos, um item por campo inválido).

Webhooks

Configure webhooks pelo painel (Painel → Webhooks) para ser avisado em tempo real, sem precisar ficar consultando GET /documents. Dois eventos existem hoje:

  • NOTA_RECEBIDA — uma nota nova foi capturada.
  • EVENTO_FISCAL_RECEBIDO — um evento (cancelamento, substituição etc.) foi capturado para uma nota já conhecida.

Toda entrega é um POST com o corpo:

{ "tipo": "NOTA_RECEBIDA", "dados": { /* mesmo formato de um item de GET /documents */ } }

E dois cabeçalhos:

Cabeçalho Conteúdo
X-IntegroBR-Event O mesmo valor de tipo do corpo.
X-IntegroBR-Signature HMAC-SHA256 (hex) do corpo bruto da requisição, usando o segredo do seu webhook como chave.

Verifique a assinatura antes de confiar no payload (exemplo em Node.js):

const crypto = require("crypto");

function assinaturaValida(corpoBruto, assinaturaRecebida, segredo) {
  const esperada = crypto.createHmac("sha256", segredo).update(corpoBruto).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(esperada), Buffer.from(assinaturaRecebida));
}

Entregas com falha (timeout, conexão recusada, resposta não-2xx) são reenviadas com backoff exponencial. O segredo do webhook só é exibido uma vez, na criação (ou ao rotacionar) — guarde com o mesmo cuidado de uma senha.

Conta

Informações da sua conta e do seu consumo no ciclo atual.

Dados da conta atual

Identifica a conta dona da chave de API usada na requisição.

Authorizations:
chaveApi

Responses

Response samples

Content type
application/json
{
  • "id": "5f9a1c2e-7b3d-4e11-9c2a-1a2b3c4d5e6f",
  • "nome": "Empresa Exemplo LTDA",
  • "status": "ATIVA",
  • "ambiente": "PRODUCAO",
  • "criadaEm": "2026-03-10T13:22:00.000Z"
}

Consumo do ciclo de cobrança atual

Franquia, consumo e excedente do ciclo em andamento. Com uma chave SANDBOX, sempre devolve { "temCicloAtivo": false, "ambiente": "SANDBOX" } — sandbox nunca gera cobrança.

Authorizations:
chaveApi

Responses

Response samples

Content type
application/json
{
  • "temCicloAtivo": true,
  • "ciclo": {
    },
  • "franquiaEventos": 2000,
  • "eventosIncluidos": 340,
  • "eventosExcedentes": 0,
  • "saldoExcedenteAberto": 0,
  • "limiteExcedenteAberto": 174.5,
  • "porEmpresa": [
    ],
  • "pausadaPorExcedente": false,
  • "destravaDisponivel": false
}

Empresas

CNPJs monitorados pela sua conta.

Lista as empresas da conta

Só devolve empresas do mesmo ambiente da chave usada (sandbox ou produção).

Authorizations:
chaveApi

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Cadastra uma empresa (CNPJ) para monitoramento

Cadastra o CNPJ na conta. Ele nasce em estado DRAFT (produção) — o próximo passo é enviar o certificado A1 em POST /companies/{id}/certificate. Com chave sandbox, a empresa já nasce ACTIVE, sem certificado.

Authorizations:
chaveApi
Request Body schema: application/json
required
cnpj
required
string >= 11 characters

Só dígitos.

nomeExibicao
string
nsuInicial
integer >= 0

Avançado — de onde retomar a consulta ao ADN, se este CNPJ já era monitorado por outro sistema. Ausência = 0 (histórico completo).

Responses

Request samples

Content type
application/json
{
  • "cnpj": "12345678000195",
  • "nomeExibicao": "Filial São Paulo"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "cnpj": "string",
  • "ambiente": "SANDBOX",
  • "ambienteAdn": "HOMOLOGACAO",
  • "escopoMonitoramento": "RECEBIDAS",
  • "nomeExibicao": "string",
  • "razaoSocial": "string",
  • "estado": "DRAFT",
  • "nsuInicial": "string",
  • "nsuUltimoConfirmado": "string",
  • "ultimaConsultaEm": "2019-08-24T14:15:22Z",
  • "monitorarDesde": "2019-08-24T14:15:22Z",
  • "certificadoValidoAte": "2019-08-24T14:15:22Z",
  • "criadaEm": "2019-08-24T14:15:22Z",
  • "atualizadaEm": "2019-08-24T14:15:22Z"
}

Detalhe de uma empresa

Authorizations:
chaveApi
path Parameters
id
required
string

Id da empresa (o mesmo devolvido em GET /companies).

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "cnpj": "string",
  • "ambiente": "SANDBOX",
  • "ambienteAdn": "HOMOLOGACAO",
  • "escopoMonitoramento": "RECEBIDAS",
  • "nomeExibicao": "string",
  • "razaoSocial": "string",
  • "estado": "DRAFT",
  • "nsuInicial": "string",
  • "nsuUltimoConfirmado": "string",
  • "ultimaConsultaEm": "2019-08-24T14:15:22Z",
  • "monitorarDesde": "2019-08-24T14:15:22Z",
  • "certificadoValidoAte": "2019-08-24T14:15:22Z",
  • "criadaEm": "2019-08-24T14:15:22Z",
  • "atualizadaEm": "2019-08-24T14:15:22Z"
}

Solicita a remoção da empresa

Inicia a remoção definitiva da empresa. Uma vez que ela já foi monitorada de verdade (passou por ACTIVE), a remoção é um processo de dois passos com um período de segurança entre eles, pra preservar o histórico fiscal — o segundo passo (confirmação) é feito pelo painel, não pela API pública.

Authorizations:
chaveApi
path Parameters
id
required
string

Id da empresa (o mesmo devolvido em GET /companies).

Responses

Response samples

Content type
application/json
{
  • "statusCode": 401,
  • "message": "Chave de API inválida ou revogada.",
  • "error": "Unauthorized"
}

Envia (ou troca) o certificado digital A1 da empresa

Multipart/form-data com o arquivo .pfx/.p12 no campo certificado e a senha no campo senha. O certificado precisa ser o e-CNPJ da própria empresa cadastrada — certificados de outro CNPJ são rejeitados. Não disponível para empresas SANDBOX (nunca usam certificado real).

Se a empresa já estiver ativa e monitorando (certificado vencendo ou revogado), enviar um novo aqui só troca o material — o monitoramento continua de onde parou, sem reiniciar a análise de histórico.

Authorizations:
chaveApi
path Parameters
id
required
string

Id da empresa (o mesmo devolvido em GET /companies).

Request Body schema: multipart/form-data
required
certificado
required
string <binary>

Arquivo do certificado A1 (.pfx ou .p12), até 10MB.

senha
required
string

Senha do certificado.

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "cnpj": "string",
  • "ambiente": "SANDBOX",
  • "ambienteAdn": "HOMOLOGACAO",
  • "escopoMonitoramento": "RECEBIDAS",
  • "nomeExibicao": "string",
  • "razaoSocial": "string",
  • "estado": "DRAFT",
  • "nsuInicial": "string",
  • "nsuUltimoConfirmado": "string",
  • "ultimaConsultaEm": "2019-08-24T14:15:22Z",
  • "monitorarDesde": "2019-08-24T14:15:22Z",
  • "certificadoValidoAte": "2019-08-24T14:15:22Z",
  • "criadaEm": "2019-08-24T14:15:22Z",
  • "atualizadaEm": "2019-08-24T14:15:22Z"
}

Pausa o monitoramento da empresa

Nenhuma consulta nova é feita ao Ambiente de Dados Nacional até reativar.

Authorizations:
chaveApi
path Parameters
id
required
string

Id da empresa (o mesmo devolvido em GET /companies).

Responses

Response samples

Content type
application/json
{
  • "pausada": true
}

Retoma o monitoramento da empresa

Volta a consultar o Ambiente de Dados Nacional a partir do último NSU confirmado — nunca reprocessa notas já vistas.

Authorizations:
chaveApi
path Parameters
id
required
string

Id da empresa (o mesmo devolvido em GET /companies).

Responses

Response samples

Content type
application/json
{
  • "retomada": true
}

Documentos

Notas fiscais e seus eventos (cancelamento, substituição etc.).

Lista notas fiscais

Lista paginada por cursor, com filtros combináveis.

Authorizations:
chaveApi
query Parameters
cnpjs
string
Example: cnpjs=12345678000190,98765432000110

Um ou vários CNPJs separados por vírgula. Ausente = todos os CNPJs da conta.

situacao
string (SituacaoNota)
Enum: "AUTORIZADA" "CANCELADA" "SUBSTITUIDA"
papel
string (PapelNota)
Enum: "RECEBIDA" "EMITIDA"

Ausente = respeita o escopo de monitoramento configurado em cada empresa.

prestador
string

Filtra por CNPJ/CPF ou nome do prestador (contém, sem diferenciar maiúsculas).

numero
string

Número da nota (contém).

chaveAcesso
string
valorMinCentavos
integer >= 0
valorMaxCentavos
integer >= 0
dataInicio
string <date-time>

Filtra por data de emissão (ISO 8601), início do intervalo.

dataFim
string <date-time>

Filtra por data de emissão (ISO 8601), fim do intervalo.

cursor
string

Id do último item da página anterior.

limite
integer [ 1 .. 100 ]
Default: 20

Responses

Response samples

Content type
application/json
{
  • "itens": [
    ],
  • "proximoCursor": null
}

Detalhe de uma nota fiscal

Inclui o XML original e a linha do tempo de eventos (cancelamento, substituição etc.).

Authorizations:
chaveApi
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "empresaId": "string",
  • "chaveAcesso": "string",
  • "cnpjTomador": "string",
  • "papel": "RECEBIDA",
  • "prestador": {
    },
  • "numero": "string",
  • "serie": "string",
  • "dataEmissao": "2019-08-24T14:15:22Z",
  • "municipio": "string",
  • "descricaoServico": "string",
  • "valorServicos": "string",
  • "situacao": "AUTORIZADA",
  • "nsu": "string",
  • "recebidaEm": "2019-08-24T14:15:22Z",
  • "xmlOriginal": "string",
  • "eventos": [
    ]
}