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

# Deposit lifecycle

> State machine, detection mechanics per rail, and the reconciliation pattern for incoming funds.

A deposit starts as `PENDING` the moment OpenFX observes incoming funds (a stablecoin transfer to your address, a wire from your customer's bank) and transitions to `COMPLETED` once those funds are cleared and credited to your balance, or `ERROR` if they don't clear.

<Note title="Why this matters">
  You don't initiate a deposit — funds arrive via your customer's wire or
  on-chain transfer, and you find out about them after the fact. That makes
  detection a notification problem. Webhooks (`type: "deposits"`, `eventType:
      "deposit.completed"`, with a top-level `data` object) are the primary channel
  because they fire the instant funds become spendable; polling `GET
      /v3/fx/deposits` with cursor pagination is the fallback when webhooks miss or
  your handler is down.
</Note>

## State machine

```mermaid theme={null}
%%{init: {'theme':'base','themeVariables':{'fontFamily':'Inter, system-ui, sans-serif','fontSize':'13px','lineColor':'#299f68','primaryColor':'#fef3c7','primaryTextColor':'#78350f','primaryBorderColor':'#d97706'}}}%%
stateDiagram-v2
  direction LR
  [*] --> PENDING: OpenFX observes incoming funds
  PENDING --> COMPLETED: Funds cleared, balance credited
  PENDING --> ERROR: Detected funds reversed or rejected
  COMPLETED --> [*]
  ERROR --> [*]

  classDef pendingStyle fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e
  classDef successStyle fill:#d7f4e1,stroke:#299f68,stroke-width:2px,color:#114330
  classDef failedStyle fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d

  class PENDING pendingStyle
  class COMPLETED successStyle
  class ERROR failedStyle
```

Status values are summarized in the [Status enums reference](/v3/references/glossary#status-enums).

## State semantics

| Status      | Meaning                                            |
| ----------- | -------------------------------------------------- |
| `PENDING`   | Funds observed but not yet credited to balance     |
| `COMPLETED` | Funds credited; reflected in `GET /v3/fx/balances` |
| `ERROR`     | Funds did not clear (e.g. reversed wire)           |

## How OpenFX detects deposits

| Rail                                                                               | Detection mechanism                              |
| ---------------------------------------------------------------------------------- | ------------------------------------------------ |
| Stablecoin (see [Supported networks](/v3/supported-networks) for the chain matrix) | On-chain monitoring of OpenFX's wallet addresses |
| Wire (Fedwire)                                                                     | Bank notification webhook from partner           |
| ACH                                                                                | Bank file processing                             |

You don't initiate a deposit through the API; funds arrive via your customer's wire or on-chain transfer to addresses configured on your account. You **observe** deposits via [`GET /v3/fx/deposits`](/v3/api-reference/trade-settlement/list-deposits) (or [`GET /v3/fx/deposits/{id}`](/v3/api-reference/trade-settlement/get-deposit) to fetch a single deposit) or the [Deposits webhook](/v3/webhooks/deposits). Webhook payloads share the API's convention — `type: "deposits"` (the resource), the dotted `eventType` (e.g. `deposit.completed`), a top-level `data` object holding the Deposit, camelCase keys, and string amounts; see [Webhook authentication](/v3/webhooks/authentication) for the envelope.

## Listing recent deposits

```bash theme={null}
curl "https://api.openfx.com/v3/fx/deposits?limit=25" \
  -H "Authorization: Bearer $OPENFX_JWT"
```

Cursor pagination (`startingAfter` / `endingBefore`); see [Pagination](/v3/pagination). To reconcile incremental new deposits since your last check, use `endingBefore` with the most recent ID you've processed.

## Field reference

* `id`: permanent deposit ID (readable, `dpt_`-prefixed)
* `depositAmount`, `currency`: what was deposited
* `network`: settlement network (e.g. `ETHEREUM` for a stablecoin deposit, `FIAT` for a bank-rail deposit)
* `transactionHash`: on-chain transaction hash for crypto deposits, `null` otherwise
* `referenceId`: external reference id supplied by the customer, if any
* `comments`, `memo`: free-text notes and an optional memo line captured at deposit time
* `paymentDetails`: rail-specific reference data for fiat deposits (e.g. FEDWIRE `imad`/`omad`), keyed by transfer type; `null` for crypto deposits or without rail metadata
* `createdAt`: when OpenFX first observed the deposit

Full schema in the [API reference](/v3/api-reference/trade-settlement/list-deposits).

## Common mistakes

* **Ignoring `network` for stablecoin reconciliation.** A USDC deposit on Ethereum and a USDC deposit on Polygon are both `USDC` but different on-chain rails — read `network` to tell them apart.
* **Reaching for `transactionHash` on a fiat deposit.** It's `null` for fiat — match fiat deposits on `referenceId` and `paymentDetails` instead.
* **Assuming `status` has more than three values.** Deposit's `status` is a closed enum: `PENDING`, `COMPLETED`, `ERROR`.

## What's next

<CardGroup cols={2}>
  <Card title="Trade Settlement" icon="wallet" href="/v3/trade-settlement">
    How deposits flow into balances and out as withdrawals.
  </Card>

  <Card title="Withdrawal lifecycle" icon="arrow-up-from-bracket" href="/v3/withdrawal-lifecycle">
    The companion state machine.
  </Card>

  <Card title="Pagination" icon="layer-group" href="/v3/pagination">
    Cursor-based reconciliation patterns.
  </Card>
</CardGroup>
