---
title: "Integração via REST — NFS-e Inbound"
description: "Tutorial completo de integração com a API NFS-e Inbound: autenticação por API Key, ativação, listagem com filtros, downloads, paginação incremental e tratamento de erros."
source_url: https://nfe.io/docs/distribuicao-nfse-inbound-integracao-rest/
last_updated: 2026-07-30
---

# Integração via REST — NFS-e Inbound

Este guia mostra como integrar um sistema cliente com a **API REST do NFS-e Inbound**, do cadastro inicial até o consumo contínuo dos documentos capturados. Tempo estimado: **30 a 60 minutos** para o primeiro fluxo funcional.

Para **desenvolvedores** que vão construir a camada de integração entre o ERP/sistema fiscal interno e a NFE.io. Para uma primeira chamada rápida em ~10 minutos, comece pelo [Quickstart](../00-quickstart.md).

## Sumário

- [Pré-requisitos](#pré-requisitos)
- [Passo 1 — Autenticação](#passo-1--autenticação)
- [Passo 2 — Ativar a captura](#passo-2--ativar-a-captura)
- [Passo 3 — Listar e detalhar documentos](#passo-3--listar-e-detalhar-documentos)
- [Passo 4 — Baixar XML, PDF ou JSON](#passo-4--baixar-xml-pdf-ou-json)
- [Passo 5 — Sincronização incremental (paginação)](#passo-5--sincronização-incremental-paginação)
- [Passo 6 — Tratamento de erros e reativação](#passo-6--tratamento-de-erros-e-reativação)
- [Verificar o resultado](#verificar-o-resultado)

## Pré-requisitos

- Conta NFE.io ativa com a empresa (CNPJ) cadastrada.
- API Key gerada no painel com descrição **"Nota Fiscal (api.nfe.io)"** e status **Ativa**.
- `company_id` da empresa (visível no painel ou via `GET /v2/companies`).
- Cliente HTTP (cURL, Postman, ou SDK na sua linguagem — exemplos abaixo em `bash`).
- Conhecimento básico de JSON e HTTP.
- Para receber notificações em tempo real: endpoint HTTPS público.

## Passo 1 — Autenticação

Todas as chamadas exigem o header `Authorization` com a API Key (string crua, **sem prefixo `Bearer`**).

```bash
export NFEIO_API_KEY="<sua-chave>"
export COMPANY_ID="<id-da-empresa>"
export BASE="https://api.nfse.io"

curl "$BASE/v2/companies/inbound/nfse" \
  -H "Authorization: $NFEIO_API_KEY"
```

O retorno `200 OK` confirma que a chave tem o papel necessário (`Nota Fiscal (api.nfe.io)` ou `NFSeDist (dfe.nfe.io)`). Se você receber `401`, a chave está inativa ou inválida; `403` indica que a chave não tem o papel certo — use uma chave com papel `Nota Fiscal (api.nfe.io)` ou `NFSeDist (dfe.nfe.io)`.

> **SDKs:** o mesmo header funciona em qualquer cliente HTTP. Em Python (`requests`), Node (`axios`), C# (`HttpClient`) ou PHP (`Guzzle`), passe `Authorization: <chave>` no objeto de headers padrão.

## Passo 2 — Ativar a captura

Faça `POST /v2/companies/inbound/nfse` com o `companyId`, `initialNsu` (use `0` para histórico desde o início disponível no ADN), `webhookUrl` e configuração opcional de manifestação automática.

```bash
curl -X POST "$BASE/v2/companies/inbound/nfse" \
  -H "Authorization: $NFEIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "companyId": "'$COMPANY_ID'",
    "initialNsu": 0,
    "webhookUrl": "https://meu-sistema.com/webhook/nfse",
    "isAutomaticManifestationEnabled": true,
    "automaticManifestationDelaySeconds": 3600
  }'
```

> **Campo `environment` (opcional):** define o ambiente da ADN para esta empresa — `"Production"`, `"Development"` ou `"Homologation"` (case-insensitive). Quando informado, tem precedência. Quando omitido no corpo, herda o ambiente da Inscrição Municipal/empresa (TaxPayers); se ausente em ambos, a empresa fica sem ambiente definido e o sistema resolve `"Production"` por padrão em tempo de execução.

Resposta `201 Created` retorna o objeto `NFSeCompanyResource` com `isActive: true`, `currentNsu`, `maxAvailableNsu` e demais campos operacionais. A partir deste momento a NFE.io passa a fazer **polling no ADN a cada ~30 segundos** em nome do seu CNPJ.

Para atualizar a configuração depois, use `PUT /v2/companies/{companyId}/inbound/nfse/details`. Para desativar (sem perder documentos), `DELETE /v2/companies/{companyId}/inbound/nfse/details`.

## Passo 3 — Listar e detalhar documentos

A listagem aceita **filtros amplos**: por tipo (`type=Nfse` para apenas notas, omitido para tudo), status, CNPJ do prestador ou tomador, intervalo de NSU, intervalo de datas de emissão ou criação, e estado do webhook.

```bash
# Listar NFS-e do mês de abril/2026, ordenadas por NSU crescente
curl "$BASE/v2/companies/$COMPANY_ID/inbound/nfse?type=Nfse&issuedBegin=2026-04-01&issuedEnd=2026-04-30&pageCount=100&hasTotals=true" \
  -H "Authorization: $NFEIO_API_KEY"

# Obter o detalhe completo de um documento por ID ou pela chave (50 dígitos)
curl "$BASE/v2/companies/$COMPANY_ID/inbound/nfse/66b2c3d4e5f6a7890bcdef12" \
  -H "Authorization: $NFEIO_API_KEY"
```

O endpoint unificado `GET /{id}` aceita tanto o `id` interno (`ObjectId`) quanto a chave de acesso de 50 dígitos — o servidor detecta automaticamente. Use `hasTotals=true` apenas quando precisar exibir totais (UI paginada) — é mais lento porque faz `count` no banco.

## Passo 4 — Baixar XML, PDF ou JSON

Cada documento expõe três downloads. **XML** e **PDF** retornam **HTTP 302** redirecionando para uma URL HMAC pré-assinada (TTL 30 min). **JSON** retorna **200 inline** com o XML convertido em JSON literal.

```bash
# XML — segue o redirect automaticamente
curl -L "$BASE/v2/companies/$COMPANY_ID/inbound/nfse/{id}/xml" \
  -H "Authorization: $NFEIO_API_KEY" -o nfse.xml

# PDF — pode retornar 202 se ainda em geração; nesse caso retry em 5–30s
curl -L "$BASE/v2/companies/$COMPANY_ID/inbound/nfse/{id}/pdf" \
  -H "Authorization: $NFEIO_API_KEY" -o nfse.pdf

# JSON literal do XML (atributos viram `@attr`, texto inline vira `#text`)
curl "$BASE/v2/companies/$COMPANY_ID/inbound/nfse/{id}/json" \
  -H "Authorization: $NFEIO_API_KEY"
```

Configure seu cliente HTTP para **seguir redirects (302) automaticamente** (`-L` em cURL, `allow_redirects=True` em `requests`, `redirect: 'follow'` em `fetch`). Não cacheie URLs assinadas — elas expiram em 30 minutos; se precisar de acesso recorrente, baixe e armazene localmente.

## Passo 5 — Sincronização incremental (paginação)

A paginação é **REST clássica** com `pageIndex` (1-based) e `pageCount` (máx 100). Como cada documento recebe um NSU incremental e único por CNPJ, você pode sincronizar de forma resiliente usando `nsuBegin` em vez de `pageIndex`.

```bash
# Sincronizar tudo a partir do último NSU processado pelo seu sistema
LAST_NSU=12345
PAGE=1

while true; do
  RESP=$(curl -s "$BASE/v2/companies/$COMPANY_ID/inbound/nfse?nsuBegin=$((LAST_NSU+1))&pageIndex=$PAGE&pageCount=100" \
    -H "Authorization: $NFEIO_API_KEY")

  COUNT=$(echo "$RESP" | jq '.documents | length')
  [ "$COUNT" -eq 0 ] && break

  # Persistir cada documento localmente
  echo "$RESP" | jq -c '.documents[]' | while read doc; do
    # ... seu processamento aqui
    LAST_NSU=$(echo "$doc" | jq -r '.nsu')
  done

  PAGE=$((PAGE+1))
done
```

**Não use `pageIndex` puro para sync** — se chegarem documentos novos durante a iteração, as páginas mudam de tamanho e você duplica ou pula registros. **Sempre filtre por `nsuBegin`** e use o último `nsu` processado como ponto de retomada.

## Passo 6 — Tratamento de erros e reativação

A API segue convenções HTTP padronizadas. Os códigos relevantes:

| HTTP | Quando |
|---|---|
| `401` | API Key ausente ou inválida |
| `403` | API Key sem papel `Nota Fiscal`/`NFSeDist` ou role `Management` (endpoints `/maintenance/*`) |
| `404` | Recurso não encontrado ou pertence a outra conta |
| `409` | Duplicidade (companyId já cadastrado, manifestação em flight) |
| `422` | Regra de negócio violada (`eventCode=203206` sem `reasonCode`, NSU regressivo) |
| `503` | Dependência indisponível (`Retry-After` no header) |

Empresas podem ser **desativadas automaticamente** por circuit breaker (5 falhas consecutivas no poll, certificado expirado, rate limit persistente). Quando isso ocorre, o campo `isActive` vira `false` e `deactivationReason` traz o motivo. Após sanar a causa, reative:

```bash
# Endpoint de manutenção — exige role Management na API Key
curl -X POST "$BASE/v2/companies/$COMPANY_ID/inbound/nfse/maintenance/reactivate" \
  -H "Authorization: $NFEIO_API_KEY"
```

Para diagnosticar problemas em documentos individuais (status `Failed`, `PdfPending`, etc.), use `POST .../inbound/nfse/{id}/reprocess`. Para reentregar webhooks que falharam definitivamente, `POST .../inbound/nfse/{id}/resend-webhook`.

## Verificar o resultado

Sua integração está saudável quando, simultaneamente:

- `GET /v2/companies/{companyId}/inbound/nfse/details` retorna `isActive: true`, `deactivationReason: null` e `lastExecutedAt` atualizado nos últimos minutos.
- A listagem `GET .../inbound/nfse?type=Nfse` retorna documentos com `status: "Processed"` e `webhookStatus: "Delivered"`.
- Seu endpoint de webhook recebe POSTs com payload `inbound.serviceInvoice.received` quando novas NFS-es chegam.
- O `currentNsu` da empresa avança em direção ao `maxAvailableNsu`.

Em produção, monitore documentos com `webhookStatus=DefinitivelyFailed` via `GET .../inbound/nfse?webhookStatus=DefinitivelyFailed&pageCount=100` e dispare `resend-webhook` periodicamente para recuperá-los.

## Referência completa da API

Para a especificação interativa de todos os endpoints, filtros, schemas de request/response e códigos de erro:

**[📖 API Reference — NFS-e Inbound](/desenvolvedores/rest-api/nfse-inbound-v2)**

A referência é gerada automaticamente a partir do contrato OpenAPI canônico do produto. Cada endpoint pode ser testado diretamente da página de documentação ("Try it" inline).

## Veja também

- [Catálogo de eventos do webhook](../reference/webhook-events.md) — contrato completo do payload `document`, validação HMAC, política de retry e idempotência
- [Manifestação do tomador](./manifestacao-tomador.md) — fluxo assíncrono de Ciência (203202) e Rejeição (203206) com auditoria
- [Bulk Export (XML, PDF, CSV)](./bulk-export.md) — geração de arquivos consolidados para fechamento contábil
- [Troubleshooting](../reference/troubleshooting.md) — `deactivationReason` e `cStat` SEFIN
- [Arquitetura](../explanation/arquitetura.md) — visão sistêmica para contexto adicional
