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

# Lifecycle & idempotency

> Understand transfer states, how to read them, and how to use idempotency keys to safely retry requests.

## Lifecycle

Tesouro tracks accepted transfers through two states:

| State       | Meaning                                                                                                                                      |
| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| `PENDING`   | Accepted by Tesouro; awaiting upstream confirmation. ACH, RTP, and FedNow start here.                                                        |
| `COMPLETED` | Book transfers are written `COMPLETED` synchronously at acceptance. ACH transitions here when the upstream banking core confirms settlement. |

Hard failures at initial submission return a `4xx` and no transfer record is created — the caller never sees a "failed transfer" object in the list.

A transfer's state is what Tesouro has observed from the upstream banking core. Because ACH returns can land days after a transfer first appears `COMPLETED`, surface `SUBMITTED` rather than `COMPLETED` to the business customer until the return window for ACH has closed. Tesouro does not currently surface ACH returns as a separate status — partners that need return-level visibility must reconcile against statements externally.

### Reading transfer state

Read transfer state by listing the source account's transfers:

```http lines theme={null}
GET /embedded-banking/v1/bank-accounts/{bankAccountId}/transfers
```

This list call drives reconciliation. Any `PENDING` transfer is checked against the upstream banking core, and ACH transfers the core reports as settled are updated to `COMPLETED` as part of the read. RTP and FedNow transfers go through the same check, but the upstream source has no record of them, so they stay in the state they were written at acceptance. Poll the list endpoint on a cadence appropriate to the rail — same-day for ACH; every few minutes is more than enough for the real-time rails.

## Idempotency

<Warning>
  Treat the `idempotencyKey` as required in production. Without it, a request that times out and is
  retried creates a second transfer, and on RTP and FedNow that duplicate is irrevocable.
</Warning>

Every money-movement endpoint accepts an `idempotencyKey`. Submitting the same key twice with the same parameters returns the original transfer (`201 Created` with the original body) — useful for retrying a request after a timeout without creating a duplicate. Submitting the same key with different parameters returns `409 Conflict` with `errorCode: MONEY_MOVEMENT_IDEMPOTENCY_KEY_CONFLICT`.

Generate the key once per logical transfer attempt and reuse it across any retries for the same attempt.
