---
title: "Payloads dos webhooks de documentos recebidos (inbound)"
description: "Referência do corpo entregue nos eventos de NF-e, CT-e e NFS-e capturadas de terceiros: campos, resumo vs documento completo e exemplos reais anonimizados."
source_url: https://nfe.io/docs/documentacao/webhooks/payloads-de-entrada
last_updated: 2026-07-30
---

# Payloads dos webhooks de documentos recebidos

Os eventos **inbound** notificam documentos emitidos **por terceiros contra a sua empresa**, capturados automaticamente pela NFE.io nos fiscos (SEFAZ para NF-e/CT-e e ambientes municipais/nacionais para NFS-e). Você não precisa consultar nada: recebe a notificação quando o documento aparece.

Para os webhooks das notas que **você emite**, veja [Payloads de emissão](./payloads-de-emissao.md).

:::info Fonte dos exemplos
Entregas reais de produção, com CNPJ e chaves de acesso substituídos por valores fictícios de **dígito verificador válido**. Estrutura, datas e códigos são fiéis ao original.
:::

## 1. Tipos de evento

| `eventType` | Documento | Quando dispara |
|---|---|---|
| `product_invoice_inbound` | NF-e completa | NF-e autorizada contra seu CNPJ, com XML disponível |
| `product_invoice_inbound_summary` | **Resumo** de NF-e | Só metadados — XML completo ainda não liberado |
| `transportation_invoice_inbound` | CT-e | CT-e em que sua empresa é destinatário, tomador ou remetente |
| `service_invoice_inbound` | NFS-e recebida | NFS-e capturada contra seu CNPJ |

Ações observadas: `issued_successfully`, `event_raised_successfully`, `input_event_raised_successfully` (manifestação do destinatário) e `outbound_successfully`.

:::tip Resumo vs documento completo
A SEFAZ entrega parte dos documentos apenas como **resumo**. Nesse caso você recebe `*_inbound_summary` com metadados, sem XML completo. Para obter o documento inteiro, faça a **manifestação do destinatário** ou consulte o XML pela API.
:::

## 2. Envelope: achatado na raiz

Diferente da NFS-e de emissão, **todos** os eventos inbound entregam os campos direto na raiz do corpo — sem `{"payload": {...}}`.

```javascript
const chave = body.accessKey;   // inbound: direto na raiz
```

## 3. CT-e recebido — `transportation_invoice_inbound`

```json
{
  "id": "495e19ab-65b5-9cae-8221-446ea118f37f",
  "type": "transportationInvoice",
  "accessKey": "29260739425723000178570010000012681998653070",
  "parentAccessKey": "",
  "nsu": 6381,
  "direction": "Received",
  "description": "Autorizado o uso do CT-e",
  "issuedOn": "2026-07-27T14:54:00+00:00",
  "createdOn": "2026-07-27T20:08:28.1671889Z",
  "totalAmount": "100.00",
  "company": {
    "id": "5cdd21a911f635bd26a5fbe8139ccdc6",
    "federalTaxNumber": "71400294000197"
  },
  "recipient": {
    "federalTaxNumber": "71400294000197",
    "name": "MODELO SERVICOS LTDA"
  },
  "sender": {
    "federalTaxNumber": "01434044000192",
    "name": "AMOSTRA VAREJO LTDA"
  },
  "taker": {
    "federalTaxNumber": "71400294000197",
    "name": "MODELO SERVICOS LTDA"
  },
  "dispatcher": {},
  "productInvoices": [
    { "accessKey": "31260739425723000178550010011421491166299040" },
    { "accessKey": "31260739425723000178550010011421501170096915" }
  ],
  "xmlUrl": "https://api.nfse.io/v2/companies/5cdd21a911f635bd26a5fbe8139ccdc6/inbound/29260739425723000178570010000012681998653070/xml"
}
```

### Campos principais

| Campo | Tipo | Observação |
|---|---|---|
| `accessKey` | string | Chave do CT-e (44 dígitos). Use como chave natural do documento. |
| `nsu` | number | Número sequencial da SEFAZ. **Atenção:** aqui é número; em NF-e inbound costuma vir string. |
| `company` | objeto | **A sua** empresa (a que recebeu). `company.id` é o id na NFE.io. |
| `recipient` / `sender` / `taker` / `dispatcher` | objeto | Participantes do transporte. Podem vir **vazios (`{}`)** — veja §5. |
| `productInvoices[]` | array | Chaves das NF-e transportadas por este CT-e. |
| `direction` | string | `Received` para documentos recebidos. |
| `xmlUrl` | string | URL autenticada do XML. Requer sua API key. |

:::tip Ligue o CT-e às suas notas
`productInvoices[].accessKey` traz as chaves das NF-e cobertas pelo frete — é por aí que se casa o custo de transporte com os pedidos.
:::

## 4. NF-e recebida — `product_invoice_inbound`

Mesmo envelope achatado, com participantes fiscais em vez de transporte:

```json
{
  "accessKey": "35260739425723000178550010011320981999999997",
  "createdOn": "2026-05-19T11:41:44.695Z",
  "parentAccessKey": "",
  "company": {
    "id": "5cdd21a911f635bd26a5fbe8139ccdc6",
    "federalTaxNumber": "71400294000197"
  },
  "issuer": {
    "federalTaxNumber": "01434044000192",
    "name": "AMOSTRA VAREJO LTDA"
  },
  "buyer": {
    "federalTaxNumber": "71400294000197",
    "name": "MODELO SERVICOS LTDA"
  },
  "type": "productInvoice",
  "nsu": "34691",
  "nfeNumber": "1132098",
  "nfeSerialNumber": "1",
  "issuedOn": "2026-05-18T04:08:27Z",
  "description": "Autorizado o uso da NF-e",
  "totalInvoiceAmount": "980.72",
  "operationType": "Incoming",
  "links": {
    "xml": "https://api.nfse.io/v2/companies/5cdd21a911f635bd26a5fbe8139ccdc6/inbound/35260739425723000178550010011320981999999997/xml",
    "pdf": "https://api.nfse.io/v2/companies/5cdd21a911f635bd26a5fbe8139ccdc6/inbound/35260739425723000178550010011320981999999997/pdf"
  }
}
```

### Discrimine pelo par `type` + ação

O `eventType` fica na rota interna e **não é propagado no corpo**. Para saber o que chegou, use `type` (no corpo) com o cabeçalho `X-Hook-Event`:

| `type` | Significa |
|---|---|
| `productInvoice` | NF-e completa |
| `productInvoiceEvent` | Evento de NF-e (cancelamento, CC-e, EPEC…) |
| `productInvoiceSummary` | Resumo de NF-e |
| `productInvoiceEventSummary` | Resumo de evento |
| `transportationInvoice` | CT-e |
| `transportationInvoiceEvent` | Evento de CT-e |

### Eventos de NF-e (`event_raised_successfully`)

Quando o documento é um **evento** e não a nota:

- `accessKey` tem **51 dígitos** (`{tpEvento}{chaveNFe}{sequência}`), não 44.
- `parentAccessKey` traz a chave da NF-e referenciada (44 dígitos).
- `links.pdf` vem **string vazia** — eventos não geram PDF.
- Campos da nota-pai (`nfeNumber`, `issuer`, `buyer`, `totalInvoiceAmount`) só vêm preenchidos **se a NF-e já estiver indexada**. O evento pode chegar antes do documento.

:::caution `operationType` pode enganar em eventos
`operationType` é sempre serializado, mas se a NF-e pai não estiver indexada o servidor não determina a operação real e emite `Outgoing` por padrão. Só confie nele quando os demais campos condicionais também vierem preenchidos.
:::

## 5. Regras de serialização

1. **Campos nulos são omitidos.** A chave não vem. Use acesso seguro.
2. **Objeto com todas as propriedades nulas vira `{}`.** No exemplo do CT-e, `dispatcher` chega vazio — o container existe, as chaves internas não. **Não trate `{}` como erro.**
3. **Container nunca instanciado desaparece.** Em resumos, o objeto pai não vem nem como `null`.
4. **`nsu` varia de tipo**: número no CT-e, string na NF-e inbound. Normalize.
5. **Datas com precisão variável** (`.695Z`, `.1671889Z`, ou sem fração).

:::warning Não use "chave presente" como sinal de negócio
Como nulos são omitidos, a ausência de um campo não significa "não existe" — significa "estava nulo neste documento". Ausência não distingue "não informado" de "não aplicável".
:::

## 6. Como baixar o XML

Os campos `xmlUrl` / `links.xml` apontam para a API da NFE.io e **exigem autenticação** — não são links públicos.

```bash
curl -H "Authorization: $NFE_API_KEY" \
  "https://api.nfse.io/v2/companies/{companyId}/inbound/{accessKey}/xml"
```

Se você recebeu um **resumo**, o XML completo só fica disponível após a manifestação do destinatário.

## 7. Checklist de integração

- [ ] Lê os campos da **raiz** (inbound nunca envelopa em `payload`).
- [ ] Discrimina pelo campo `type` do corpo, não pelo `eventType`.
- [ ] Trata `{}` (objeto vazio) como participante não informado, sem quebrar.
- [ ] Normaliza `nsu` para string.
- [ ] Aceita `accessKey` de **44 dígitos** (documento) e **51** (evento de NF-e).
- [ ] Trata resumos (`*_summary`) como documento parcial, sem XML.
- [ ] Deduplica por `X-Hook-Id` — e por `accessKey` + `nsu` no seu domínio.
- [ ] Autentica ao baixar XML/PDF.
- [ ] Tolera evento que chega antes da nota-pai (campos condicionais vazios).

## Próximos passos

- [Payloads de emissão](./payloads-de-emissao.md) — NFS-e, NF-e e NFC-e que você emite.
- [Dúvidas frequentes](./duvidas-frequentes.md) — validação de assinatura.
- [IPs de origem](./ips-de-origem.md) — allowlist.
