> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Receive (TED IN)

> Receive TED transfers automatically — the plugin polls SPB, validates recipient Accounts, and credits funds with no manual intervention.

TED IN lets your institution receive transfers from any Brazilian bank automatically. Your team takes no action — the plugin detects, validates, and credits each transfer. When a customer at another bank sends a TED to your institution, the funds reach the recipient's account within minutes.

## How it works

***

1. A customer at another bank starts a TED transfer to one of your institution's accounts
2. Every 60 seconds (default `JD_POLL_INTERVAL_SECONDS`), the plugin polls the JD SPB network for new incoming transfers
3. The plugin looks up the recipient account in your CRM by the document number in the transfer message
4. The plugin credits the recipient account automatically, minus the cashin fee if you configured one

<img src="https://mintcdn.com/lerian-49cb71fc/SEOef3JqTInYAAau/images/en/d2/ted-how-it-works-ted-in.svg?fit=max&auto=format&n=SEOef3JqTInYAAau&q=85&s=1a7c0e824237ad3701b5f5fe48454974" alt="TED IN flow diagram" width="1069" height="426" data-path="images/en/d2/ted-how-it-works-ted-in.svg" />

## Detection and processing timeline

***

The stages below show what happens after the origin bank sends the transfer:

| Stage        | What happens                                                                      |
| ------------ | --------------------------------------------------------------------------------- |
| Submission   | The origin bank submits the transfer to the SPB network                           |
| Detection    | The plugin fetches the transfer on its next poll cycle. Status becomes `RECEIVED` |
| Validation   | The plugin confirms the recipient account. Status becomes `PROCESSING`            |
| Credit       | The plugin credits the recipient account. Status becomes `COMPLETED`              |
| Notification | The plugin sends the webhook to your system                                       |

**Typical time:** The credit completes within one poll cycle. With the default 60-second poll interval, the funds land in about a minute.

## Transfer states

***

| State        | What it means for the recipient                                                                                     |
| ------------ | ------------------------------------------------------------------------------------------------------------------- |
| `RECEIVED`   | The plugin detected the transfer on the network and started processing                                              |
| `PROCESSING` | The plugin confirmed the recipient account and applies the credit                                                   |
| `COMPLETED`  | The funds reached the recipient's account                                                                           |
| `FAILED`     | The plugin could not apply the credit (for example, a Midaz rejection), or a chargeback reversed a completed credit |

## Receiving fee (cashin)

***

Your organization can charge a fee on incoming transfers. When you enable it, the plugin deducts the fee from the amount before it credits the recipient. The recipient receives the net amount. You set the fee amount and configuration per organization through the Fees Engine.

Formula: `credited amount = transfer amount − fee`

Example: a R$1,000.00 transfer with a R$2.50 fee credits R\$997.50 to the recipient's account. This is the opposite of TED OUT, where the plugin adds the fee on top and the sender pays more.

## What happens when a recipient isn't found

***

If the plugin cannot match the document number in the incoming transfer to an account in your CRM, it returns the transfer to the origin bank automatically. The sending customer gets their money back. Your team takes no action, and no funds go unaccounted for.

The plugin records the inbound message as an undeliverable incoming transfer in the `undeliverable_incoming_transfers` store. It then dispatches a devolução (STR0010 return) to the origin bank. This path does not create a credited transfer record set to `FAILED`.

## Querying received transfers

***

Use the [List Transfers](/en/reference/midaz/plugins/ted/list-transfers) endpoint to retrieve all incoming transfers. Filter by `type=TED_IN` to view only received transfers.

**Endpoint:** GET /v1/transfers

**Response (key fields):**

```json theme={null}
{
  "items": [
    {
      "transferId": "019c96a0-ab20-7def-a1b2-1f2a3b4c5d6e",
      "type": "TED_IN",
      "status": "COMPLETED",
      "amount": 5000.00,
      "feeAmount": 0.00,
      "totalAmount": 5000.00,
      "createdAt": "2026-01-21T10:15:00-03:00",
      "updatedAt": "2026-01-21T10:15:30-03:00"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "returned": 1,
    "totalCount": 150,
    "hasNextPage": true
  }
}
```

For full query parameter options, see the [List Transfers](/en/reference/midaz/plugins/ted/list-transfers) reference.

## Operational endpoints

***

Three operator endpoints control the TED IN polling loop. They target scripts and runbooks, not end-user traffic.

| Endpoint                           | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /v1/transfers/ted-in/poll`   | Manually trigger the JD poller that normally runs on a 60s cron. Use it after an incident window or to validate JD connectivity. The route is tenant-scoped but does not require `X-Organization-Id`, because it resolves the tenant from the authenticated context. It requires `X-Idempotency` for safe retries. A same-key retry replays the cached response instead of reading JD's destructive queue again.                                                                                                                                                                                                                                                                                                                                    |
| `POST /v1/transfers/ted-in/replay` | Replay persisted, unprocessed TED IN backlog rows that the plugin already fetched from JD. This route does not read JD again. It requires `X-Organization-Id` for Midaz organization scope and `X-Idempotency` for safe retries. It still resolves the tenant from the authenticated context.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `POST /v1/transfers/ted-in/resume` | Clear the fail-closed receive latch and re-arm a poller that auto-recovery cannot revive — a panicked multi-tenant child or a single-tenant poller past the panic hard-cap. Higher-privilege than `/poll` because it re-opens JD destructive-read consumption. Resume never bypasses the money-path gate: if the current latch has no durable reconciliation gap yet, the request is refused with `409`. Verify pending gaps with [List TED IN Reconciliation Gaps](/en/reference/midaz/plugins/ted/list-ted-in-reconciliation-gaps) first, then optionally pass `{ "acknowledge": true, "note": "..." }` to mark the gap resolved in the same call. A healthy, not-latched poller returns `resumed: false` — the route is a safe idempotent no-op. |

For request body, response, status codes, and error codes, see the [TED OpenAPI specification](/en/openapi/v3-current/ted.yaml) (operations `triggerTEDInPoller`, `replayTEDInPoller`, and `resumeTEDInPoller`).

## Three distinct dead-letter paths

***

The plugin uses three separate failure stores. They are not interchangeable, and you must monitor each one independently:

<Note>
  * **JD parse failures** — the plugin stores these in `jd_incoming_parse_failures`. The message arrived from JD, but the plugin could not interpret it (malformed XML, unknown message type). This store needs manual triage.
  * **Undeliverable inbound transfers** — the plugin stores these in `undeliverable_incoming_transfers`. Parsing succeeded, but the plugin could not apply the credit (for example, it did not find the recipient account). This path can trigger an automatic devolução to the origin bank.
  * **Webhook DLQ** — the retry queue for failed outbound webhook deliveries, at `/v1/webhooks/dlq`. It does not relate to TED IN ingestion. This is the outbound event channel to integrating clients.
</Note>

## Webhooks

***

Configure a webhook to get real-time notifications when transfers arrive. The `transfer_incoming.completed` event fires as soon as the plugin credits a transfer. See [Webhooks](/en/rails/ted/jd/ted-webhooks) for setup and event payload details.

## Reconciliation

***

For accounting and finance reconciliation, each transfer record includes these fields:

| Field           | Usage                                                                          |
| --------------- | ------------------------------------------------------------------------------ |
| `controlNumber` | JD SPB control number — unique per transfer, used for interbank reconciliation |
| `transferId`    | Lerian internal identifier                                                     |
| `createdAt`     | Timestamp when the plugin detected the transfer                                |
| `completedAt`   | Timestamp when the plugin credited the funds                                   |

The plugin persists transfer records for reconciliation and audit.

## Processing guarantees

***

The plugin makes sure that it never loses a transfer and never credits one twice:

* **No duplicate credits** — each transfer message carries a unique sequence number. The plugin rejects any attempt to process the same message twice.
* **Automatic retry on failure** — the plugin retries transient errors (such as a momentary service interruption) with exponential backoff before it records any failure state.
* **Dead-letter queue for unresolvable issues** — if the plugin cannot process a transfer after all retries, it moves the transfer to a dead-letter queue for manual review. The plugin never drops a transfer silently.
