# Deposit Funds via a Liquidity Provider

In order to send payouts, you will need to deposit funds to a liquidity provider to exchange fiat to stablecoins (i.e., on-ramp funds).

Tesser treats deposits via a liquidity provider as a special class of payments, so the structure of the deposits API experience will be similar to creating a payment.

Before creating a deposit, review the [Funds Movement Lifecycle and Data Model](/overviews/funds-movement-lifecycle-and-data-model) overview to understand the shared data shape, lifecycle phases, and statuses that apply to deposits and Tesser's other funds-movement resources.

## Prerequisites

Liquidity providers require that funds movement to and from their platforms are "first-party" only. So, your bank accounts (for fiat funds movement to/from the provider) and wallets (if using self-custodial wallets) must be registered with the liquidity provider prior to deposits and withdrawals.

Before beginning a deposit, you also must register the relevant bank account and/or wallet with Tesser. Where possible, Tesser will then register these accounts at your enrolled liquidity providers on your behalf. For more information on account creation, see [Create an account](/how-tos/create-an-account).

## Deposit Workflow

Like a payment, a deposit will execute over multiple steps.

- A `transfer` step indicates funds are moving from one account to another. Accounts can be a bank account, ledger, or wallet. In a `transfer` step, the source and destination currencies (`estimated.from.currency` and `estimated.to.currency`) may be the same or different.
- A `swap` step indicates currencies have been exchanged within the same account (`estimated.from.account_id` and `estimated.to.account_id` are the same). E.g., a trade was performed to sell USD and buy USDC or USDT within your ledger at a liquidity provider.

Each step has a status. For more information on the statuses of a transfer step, see [Step statuses](/overviews/funds-movement-lifecycle-and-data-model#step-statuses).

## Exchange Rates for On-Ramping

Depending on which liquidity provider is being used, there may be variation in the exchange rate between a given fiat and stablecoin pair when you on-ramp. Also, the liquidity provider may or may not offer the ability to guarantee the current rate. At this time, Tesser does not provide guaranteed exchange rates unless the provider does.

| Type of liquidity provider | Example | Behavior |
|---|---|---|
| Stablecoin issuer | Circle | Exchange rate between USD and USDC always 1:1 |
| On/Off ramp | OpenFX | Exchange rate between buy and sell currencies fluctuates; current rates can be guaranteed for a period of time |
| Exchange | Kraken | Exchange rate fluctuates; no guaranteed rate |

## Funding Deposits

Tesser allows you to create "set-it-and-forget-it" deposits for all liquidity providers, where the `desired.from.currency` and `desired.to.currency` are different. In this scenario, Tesser will supply an indicative exchange rate between the two currencies via the `estimated.from.amount` and `estimated.to.amount` fields, and once funds from the `desired.from.currency` land at the liquidity provider, Tesser will attempt to execute the on-ramp into the `desired.to.currency` at the current exchange rate.

Depending on the liquidity provider, you may be able to pre-position funds (pre-fund) at the provider. If pre-funding is supported, Tesser will create a ledger account at the provider to track your pre-funding levels (if any). For liquidity providers that support pre-funding, you can create deposits that transfer only fiat funds from your source bank account to the ledger of the liquidity provider.

You may want to pre-fund a liquidity provider if the provider offers guaranteed rates. Pre-funding at a liquidity provider that offers guaranteed rates can be beneficial because the exchange rate quoted by the liquidity provider can be directly executed because funds are already stored with the liquidity provider.

:::note
If you choose to pre-fund, you will create a deposit for the transfer of fiat to the provider and then a [rebalance](/api/treasury#create-rebalance) to trade from fiat into a stablecoin.
:::

## Deposit Creation

Submit a request to the Deposit API.

- If applicable, you should specify on which `tenant`'s behalf you are requesting the deposit.
- For the deposit, populate the following fields in the `desired` object:
    - `desired.from.account_id`: The identifier of the bank account fiat funds will be sent from (see [above](#prerequisites)).
    - `desired.from.amount`: Fiat amount to deposit.
    - `desired.from.currency`: Fiat currency you are on-ramping from.
    - `desired.to.account_id`: Identifier of the self-custodial wallet or provider ledger account to deposit stablecoins to.

        :::note
        Ensure the `desired.to.account_id` is associated with a liquidity provider that can support your requested `desired.from.currency` and `desired.to.currency`.
        :::

    - `desired.to.currency`: Stablecoin currency you are on-ramping to.
    - `desired.to.network`: Stablecoin network on-ramping to (optional). Not applicable if `desired.to.account_id` has a type of "ledger".

*Note: `desired.to.amount` is not auto-populated. The Deposit's `desired.to.amount` remains `null` throughout the lifecycle; the indicative target amount is supplied in `estimated.to.amount` once the quote is obtained.*

**The examples in this guide show 4 scenarios:**

1. Depositing and on-ramping to a ledger at Circle
2. Depositing fiat to a ledger at OpenFX
3. Depositing and on-ramping into a self-custodial wallet via OpenFX
4. Depositing and on-ramping into a self-custodial wallet via Circle

<Tabs>
  <TabItem label="Scenario 1">

Example request (deposit and on-ramp to a ledger at Circle)

```json
{
  "tenant_id": null,
  "desired": {
    "from": {
      "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
      "amount": "1000",
      "currency": "USD"
    },
    "to": {
      "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
      "currency": "USDC"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 2">

Example request (deposit fiat to a ledger at OpenFX)

```json
{
  "tenant_id": null,
  "desired": {
    "from": {
      "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
      "amount": "1000",
      "currency": "USD"
    },
    "to": {
      "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
      "currency": "USD"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 3">

Example request (deposit and on-ramp to a wallet via OpenFX)

```json
{
  "tenant_id": null,
  "desired": {
    "from": {
      "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
      "amount": "1000",
      "currency": "USD"
    },
    "to": {
      "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
      "currency": "USDT",
      "network": "POLYGON"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 4">

Example request (deposit and on-ramp to a wallet via Circle)

```json
{
  "tenant_id": null,
  "desired": {
    "from": {
      "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
      "amount": "1000",
      "currency": "USD"
    },
    "to": {
      "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
      "currency": "USDC",
      "network": "BASE"
    }
  }
}
```

  </TabItem>
</Tabs>

In the API response, Tesser will create and return an `id` for the deposit request.

<Tabs>
  <TabItem label="Scenario 1">

Example response (deposit and on-ramp to a ledger at Circle):

```json
{
  "data": {
    "id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
    "workspace_id": "b53f6690-3242-4942-9907-885779632832",
    "organization_reference_id": null,
    "direction": "inbound",
    "desired": {
      "from": {
        "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
        "amount": "1000",
        "currency": "USD",
        "network": null
      },
      "to": {
        "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
        "amount": null,
        "currency": "USDC",
        "network": null
      }
    },
    "estimated": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "actual": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "steps": [],
    "created_at": "2025-12-01T10:00:00.000Z",
    "updated_at": "2025-12-01T10:00:00.000Z",
    "expires_at": "2025-12-01T14:00:00.000Z"
  }
}
```

  </TabItem>
  <TabItem label="Scenario 2">

Example response (deposit fiat to a ledger at OpenFX):

```json
{
  "data": {
    "id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
    "workspace_id": "b53f6690-3242-4942-9907-885779632832",
    "organization_reference_id": null,
    "direction": "inbound",
    "desired": {
      "from": {
        "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
        "amount": "1000",
        "currency": "USD",
        "network": null
      },
      "to": {
        "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
        "amount": null,
        "currency": "USD",
        "network": null
      }
    },
    "estimated": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "actual": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "steps": [],
    "created_at": "2025-12-01T10:00:00.000Z",
    "updated_at": "2025-12-01T10:00:00.000Z",
    "expires_at": "2025-12-01T14:00:00.000Z"
  }
}
```

  </TabItem>
  <TabItem label="Scenario 3">

Example response (deposit and on-ramp to a wallet via OpenFX):

```json
{
  "data": {
    "id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
    "workspace_id": "b53f6690-3242-4942-9907-885779632832",
    "organization_reference_id": null,
    "direction": "inbound",
    "desired": {
      "from": {
        "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
        "amount": "1000",
        "currency": "USD",
        "network": null
      },
      "to": {
        "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
        "amount": null,
        "currency": "USDT",
        "network": "POLYGON"
      }
    },
    "estimated": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "actual": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "steps": [],
    "created_at": "2025-12-01T10:00:00.000Z",
    "updated_at": "2025-12-01T10:00:00.000Z",
    "expires_at": "2025-12-01T14:00:00.000Z"
  }
}
```

  </TabItem>
  <TabItem label="Scenario 4">

Example response (deposit and on-ramp to a wallet via Circle):

```json
{
  "data": {
    "id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
    "workspace_id": "b53f6690-3242-4942-9907-885779632832",
    "organization_reference_id": null,
    "direction": "inbound",
    "desired": {
      "from": {
        "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
        "amount": "1000",
        "currency": "USD",
        "network": null
      },
      "to": {
        "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
        "amount": null,
        "currency": "USDC",
        "network": "BASE"
      }
    },
    "estimated": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "actual": {
      "from": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      },
      "to": {
        "account_id": null,
        "amount": null,
        "currency": null,
        "network": null
      }
    },
    "steps": [],
    "created_at": "2025-12-01T10:00:00.000Z",
    "updated_at": "2025-12-01T10:00:00.000Z",
    "expires_at": "2025-12-01T14:00:00.000Z"
  }
}
```

  </TabItem>
</Tabs>

## Deposit Quote Created (`deposit.quote_created`)

After your `POST /deposits` request is accepted, Tesser plans the route the funds will take through the liquidity provider and obtains a reference exchange rate. Tesser then sends a `deposit.quote_created` webhook — the first webhook fired for the deposit. The payload carries the planned `steps[]` array (each step with `status: "created"`) together with the populated `estimated` overlay at both the deposit and step levels. This webhook fires for all liquidity providers, including those with fixed 1:1 rates such as Circle, for consistency across the deposit lifecycle. The ratio of `estimated.from.amount` and `estimated.to.amount` is the indicative exchange rate for the deposit.

<Tabs>
  <TabItem label="Scenario 1">

Example `deposit.quote_created` webhook (deposit and on-ramp to a ledger at Circle):

```json
{
  "id": "b8c4d5e6-2f3a-4b7c-9d8e-1f2a3b4c5d6e",
  "type": "deposit.quote_created",
  "created_at": "2025-12-01T10:00:00.600Z",
  "data": {
    "object": {
      "id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": null,
          "currency": "USDC",
          "network": null
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:00.600Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:00.600Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-01T10:00:00.600Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 2">

Example `deposit.quote_created` webhook (deposit fiat to a ledger at OpenFX):

```json
{
  "id": "e2f3a4b5-6c7d-4e8f-9a0b-1c2d3e4f5a6b",
  "type": "deposit.quote_created",
  "created_at": "2025-12-01T10:00:02.000Z",
  "data": {
    "object": {
      "id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": null,
          "currency": "USD",
          "network": null
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "steps": [
        {
          "id": "4d6f7a8b-1c2d-4e5f-6a7b-8c9d0e1f2a3b",
          "deposit_id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "5e7f8a9b-2c3d-4e5f-6a7b-8c9d0e1f2a3b",
          "deposit_id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-01T10:00:02.000Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 3">

Example `deposit.quote_created` webhook (deposit and on-ramp to a wallet via OpenFX):

```json
{
  "id": "e47a9b21-5c4d-4f82-9a13-7b8e3d1c5f04",
  "type": "deposit.quote_created",
  "created_at": "2025-12-01T10:00:02.000Z",
  "data": {
    "object": {
      "id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": null,
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "5c7a8e4d-1b9f-4c62-a8e3-7d6f3b4a2c9e",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 3,
          "step_type": "swap",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "9d3f6a2c-8e5b-4f17-b0a6-1c4e7d9f3b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 4,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:02.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-01T10:00:02.000Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 4">

Example `deposit.quote_created` webhook (deposit and on-ramp to a wallet via Circle):

```json
{
  "id": "d7c4f1e8-3b9a-4258-9c0e-2f6a8d1b5e3c",
  "type": "deposit.quote_created",
  "created_at": "2025-12-01T10:00:00.700Z",
  "data": {
    "object": {
      "id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": null,
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "steps": [
        {
          "id": "4f8b1a3c-7e2d-4951-a8c5-6d9e3f1b2a4c",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:00.700Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "6c2d5e9a-3f7b-4824-b1e5-8a4c7f9d2e1b",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:00.700Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        },
        {
          "id": "8e1f4b2d-5a6c-4937-a7d8-9b3e5f1c2a4d",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 3,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "created",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T10:00:00.700Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-01T10:00:00.700Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
</Tabs>

## Deposit Instructions for Liquidity Provider

The `estimated.to.account_id` field in the first step will be populated with the Tesser identifier of the provider's bank account. Submit a request to [Get an account by ID](/api/accounts#get-an-account-by-id) with the `to_account_id` as the path parameter.

The response will contain the bank account information you need to deposit funds to the liquidity provider, including the account number, bank identifier code (BIC/SWIFT/Routing number).

Once you have the account information, initiate a push of funds to the liquidity provider from your bank account. This funds transfer happens outside of Tesser's system. The instructions will include the supported payment methods you can use to push funds. For example, some liquidity providers will only accept wires.

:::warning{title="Follow provider instructions carefully"}
Make sure to follow the liquidity provider's deposit instructions carefully. Failing to comply with the instructions can cause delays in deposits or deposits to be rejected.
:::

## Deposit Info After Completion

Tesser will track the receipt of the fiat funds to the liquidity provider, as well as any on-ramping into stablecoins and withdrawal to a self-custodial wallet (if applicable). When a deposit is successful, the `status` of each step will be "completed" and the `actual.*` fields will be populated on the top-level of the deposit and on each step. Tesser emits a `step.completed` event for each step that reaches terminal completion, followed by a `deposit.updated` event carrying the full updated Deposit object with all overlays populated. Tesser-initiated steps (such as a final ledger → self-custodial wallet transfer) also emit `step.submitted` and `step.confirmed` ahead of `step.completed`; see each scenario's [Webhook Events table](#webhook-events-by-scenario) for the exact event sequence.

<Tabs>
  <TabItem label="Scenario 1">

Example `step.completed` webhook (terminal step for deposit and on-ramp to a ledger at Circle):

```json
{
  "id": "f1e2d3c4-5b6a-4798-8e0d-3f4a5b6c7d8e",
  "type": "step.completed",
  "created_at": "2025-12-02T14:30:00.500Z",
  "data": {
    "object": {
      "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
      "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
      "step_sequence": 2,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "circle_mint",
      "status": "completed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:30:00.500Z",
      "submitted_at": null,
      "confirmed_at": "2025-12-02T14:30:00.400Z",
      "completed_at": "2025-12-02T14:30:00.500Z",
      "failed_at": null
    }
  }
}
```

:::note
For deposits into a ledger at Circle, `transaction_hash` is always `null`.
:::

Example `deposit.updated` webhook (deposit and on-ramp to a ledger at Circle complete):

```json
{
  "id": "e2c6d8b1-4f7a-4e93-9b8d-2a5c7f3e1d4b",
  "type": "deposit.updated",
  "created_at": "2025-12-02T14:30:00.700Z",
  "data": {
    "object": {
      "id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": null,
          "currency": "USDC",
          "network": null
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:25:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:25:00.400Z",
          "completed_at": "2025-12-02T14:25:00.500Z",
          "failed_at": null
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:30:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:30:00.400Z",
          "completed_at": "2025-12-02T14:30:00.500Z",
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:30:00.700Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 2">

Example `step.completed` webhook (terminal step for deposit fiat to a ledger at OpenFX):

```json
{
  "id": "f3a4b5c6-7d8e-4f9a-0b1c-2d3e4f5a6b7c",
  "type": "step.completed",
  "created_at": "2025-12-02T14:30:00.500Z",
  "data": {
    "object": {
      "id": "5e7f8a9b-2c3d-4e5f-6a7b-8c9d0e1f2a3b",
      "deposit_id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
      "step_sequence": 2,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "openfx",
      "status": "completed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:30:00.500Z",
      "submitted_at": null,
      "confirmed_at": "2025-12-02T14:30:00.400Z",
      "completed_at": "2025-12-02T14:30:00.500Z",
      "failed_at": null
    }
  }
}
```

Example `deposit.updated` webhook (deposit fiat to a ledger at OpenFX complete):

```json
{
  "id": "a4b5c6d7-8e9f-4a0b-1c2d-3e4f5a6b7c8d",
  "type": "deposit.updated",
  "created_at": "2025-12-02T14:30:00.700Z",
  "data": {
    "object": {
      "id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": null,
          "currency": "USD",
          "network": null
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "steps": [
        {
          "id": "4d6f7a8b-1c2d-4e5f-6a7b-8c9d0e1f2a3b",
          "deposit_id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:25:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:25:00.400Z",
          "completed_at": "2025-12-02T14:25:00.500Z",
          "failed_at": null
        },
        {
          "id": "5e7f8a9b-2c3d-4e5f-6a7b-8c9d0e1f2a3b",
          "deposit_id": "3c5d6f8e-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:30:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:30:00.400Z",
          "completed_at": "2025-12-02T14:30:00.500Z",
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:30:00.700Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 3">

Example `step.completed` webhook (terminal step for deposit and on-ramp to a wallet via OpenFX):

```json
{
  "id": "c2e5f3d1-7b9a-4c48-8e0d-3f4a5b6c7d8e",
  "type": "step.completed",
  "created_at": "2025-12-02T14:36:35.000Z",
  "data": {
    "object": {
      "id": "9d3f6a2c-8e5b-4f17-b0a6-1c4e7d9f3b8a",
      "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "step_sequence": 4,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "actual": {
        "from": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "999.475",
          "currency": "USDT",
          "network": "POLYGON"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.475",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "fees": [],
      "transaction_hash": "0x7e8c3f2a1b4d ... 7c8d9e0f",
      "provider_key": "openfx",
      "status": "completed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:36:35.000Z",
      "submitted_at": "2025-12-02T14:35:05.000Z",
      "confirmed_at": "2025-12-02T14:35:07.500Z",
      "completed_at": "2025-12-02T14:36:35.000Z",
      "failed_at": null
    }
  }
}
```

Example `deposit.updated` webhook (deposit and on-ramp to a wallet via OpenFX complete):

```json
{
  "id": "b8d3a5f7-2c4e-4691-9d3a-8f6b1e7c4d52",
  "type": "deposit.updated",
  "created_at": "2025-12-02T14:36:35.200Z",
  "data": {
    "object": {
      "id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": null,
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "actual": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.475",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:25:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:25:00.400Z",
          "completed_at": "2025-12-02T14:25:00.500Z",
          "failed_at": null
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:30:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:30:00.400Z",
          "completed_at": "2025-12-02T14:30:00.500Z",
          "failed_at": null
        },
        {
          "id": "5c7a8e4d-1b9f-4c62-a8e3-7d6f3b4a2c9e",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 3,
          "step_type": "swap",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.475",
              "currency": "USDT",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:33:00.500Z",
          "submitted_at": "2025-12-02T14:33:00.100Z",
          "confirmed_at": "2025-12-02T14:33:00.300Z",
          "completed_at": "2025-12-02T14:33:00.500Z",
          "failed_at": null
        },
        {
          "id": "9d3f6a2c-8e5b-4f17-b0a6-1c4e7d9f3b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 4,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            }
          },
          "actual": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.475",
              "currency": "USDT",
              "network": "POLYGON"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "999.475",
              "currency": "USDT",
              "network": "POLYGON"
            }
          },
          "fees": [],
          "transaction_hash": "0x7e8c3f2a1b4d ... 7c8d9e0f",
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:36:35.000Z",
          "submitted_at": "2025-12-02T14:35:05.000Z",
          "confirmed_at": "2025-12-02T14:35:07.500Z",
          "completed_at": "2025-12-02T14:36:35.000Z",
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:36:35.200Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Scenario 4">

The final step — Tesser-initiated transfer of USDC from your Circle ledger to your self-custodial wallet — proceeds through three webhook events before `deposit.updated`: `step.submitted`, `step.confirmed`, and `step.completed`.

Example `step.submitted` webhook (Step 3 — Tesser initiates the Circle ledger → wallet transfer):

```json
{
  "id": "a3f7e2c1-5b8d-4926-9c4f-1e6d3b8a5f02",
  "type": "step.submitted",
  "created_at": "2025-12-02T14:32:00.100Z",
  "data": {
    "object": {
      "id": "8e1f4b2d-5a6c-4937-a7d8-9b3e5f1c2a4d",
      "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
      "step_sequence": 3,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "circle_mint",
      "status": "submitted",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:32:00.000Z",
      "submitted_at": "2025-12-02T14:32:00.000Z",
      "confirmed_at": null,
      "completed_at": null,
      "failed_at": null
    }
  }
}
```

Example `step.confirmed` webhook (Step 3 — Circle acknowledges the transfer creation):

```json
{
  "id": "b5e9d3a7-2c8f-4641-a7b3-5f9e2d1c4b8a",
  "type": "step.confirmed",
  "created_at": "2025-12-02T14:32:05.200Z",
  "data": {
    "object": {
      "id": "8e1f4b2d-5a6c-4937-a7d8-9b3e5f1c2a4d",
      "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
      "step_sequence": 3,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "circle_mint",
      "status": "confirmed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:32:05.000Z",
      "submitted_at": "2025-12-02T14:32:00.000Z",
      "confirmed_at": "2025-12-02T14:32:05.000Z",
      "completed_at": null,
      "failed_at": null
    }
  }
}
```

Example `step.completed` webhook (Step 3 — on-chain settlement received from Circle):

```json
{
  "id": "c8f1e4d2-9b3a-4758-b1e7-6d4a8c2f5b9e",
  "type": "step.completed",
  "created_at": "2025-12-02T14:34:30.300Z",
  "data": {
    "object": {
      "id": "8e1f4b2d-5a6c-4937-a7d8-9b3e5f1c2a4d",
      "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
      "step_sequence": 3,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "actual": {
        "from": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "fees": [],
      "transaction_hash": "0x9b2e7f5d3c1a ... 0f9e3a1b",
      "provider_key": "circle_mint",
      "status": "completed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:34:30.000Z",
      "submitted_at": "2025-12-02T14:32:00.000Z",
      "confirmed_at": "2025-12-02T14:32:05.000Z",
      "completed_at": "2025-12-02T14:34:30.000Z",
      "failed_at": null
    }
  }
}
```

:::note
For Circle ledger → self-custodial wallet transfers, Tesser populates `transaction_hash` on the step at `step.completed` — not at `step.confirmed`. Circle initiates the on-chain transfer asynchronously after acknowledging the API call (`step.confirmed`); Tesser receives the transaction hash via SNS once the chain confirms settlement, which coincides with the step reaching `completed`. This timing differs from the OpenFX wallet flow (Scenario 3), where Tesser broadcasts the on-chain transaction itself and populates `transaction_hash` at `step.confirmed`.
:::

Example `deposit.updated` webhook (deposit and on-ramp to a wallet via Circle complete):

```json
{
  "id": "e2f5b8a1-7c3d-4914-9b8e-5d1f2a6c4b7e",
  "type": "deposit.updated",
  "created_at": "2025-12-02T14:34:30.500Z",
  "data": {
    "object": {
      "id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": null,
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "actual": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "1000",
          "currency": "USDC",
          "network": "BASE"
        }
      },
      "steps": [
        {
          "id": "4f8b1a3c-7e2d-4951-a8c5-6d9e3f1b2a4c",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:25:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:25:00.400Z",
          "completed_at": "2025-12-02T14:25:00.500Z",
          "failed_at": null
        },
        {
          "id": "6c2d5e9a-3f7b-4824-b1e5-8a4c7f9d2e1b",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:30:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:30:00.400Z",
          "completed_at": "2025-12-02T14:30:00.500Z",
          "failed_at": null
        },
        {
          "id": "8e1f4b2d-5a6c-4937-a7d8-9b3e5f1c2a4d",
          "deposit_id": "9d2e5f4a-8c3b-4710-b9e6-2f7a1d6c4b5e",
          "step_sequence": 3,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            }
          },
          "actual": {
            "from": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "1000",
              "currency": "USDC",
              "network": "BASE"
            }
          },
          "fees": [],
          "transaction_hash": "0x9b2e7f5d3c1a ... 0f9e3a1b",
          "provider_key": "circle_mint",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:34:30.000Z",
          "submitted_at": "2025-12-02T14:32:00.000Z",
          "confirmed_at": "2025-12-02T14:32:05.000Z",
          "completed_at": "2025-12-02T14:34:30.000Z",
          "failed_at": null
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-02T14:34:30.500Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

  </TabItem>
</Tabs>

## Webhook Events by Scenario

Below are the webhook events you will observe for each of the four deposit scenarios in this guide.

**Scenario 1 — Deposit and on-ramp to a ledger at Circle**

| # | What happens | What you receive / do | Fields populated |
|---|---|---|---|
| 1 | You submit the deposit request | HTTP response with `id` | `desired.from.amount` |
| 2 | Tesser plans the steps and obtains a quote | `deposit.quote_created` webhook fires with 2 steps and the populated `estimated` overlay | Steps array; `estimated.from.amount` and `estimated.to.amount` at deposit and step level (1:1) |
| 3 | You wire USD to Circle's bank account | — | — |
| 4 | Circle receives your wire, mints USDC, and credits your Circle ledger | Two terminal `step.completed` events fire (one per step), followed by a `deposit.updated` event carrying the full Deposit with `actual.*` populated. Tesser observes Circle's single terminal webhook, so no intermediate `step.submitted` or `step.confirmed` events are emitted. If the wire cannot be reconciled, two `step.failed` events fire instead, also followed by `deposit.updated`. | Steps 1 & 2: `actual.from.amount`, `actual.to.amount`, all timestamps. Deposit-level `actual.from.amount` and `actual.to.amount`. Deposit complete. |

:::note
The two `step.completed` events for Steps 1 and 2 arrive in close succession, followed immediately by `deposit.updated`.
:::

**Scenario 2 — Deposit fiat to a ledger at OpenFX**

| # | What happens | What you receive / do | Fields populated |
|---|---|---|---|
| 1 | You submit the deposit request | HTTP response with `id` | `desired.from.amount` |
| 2 | Tesser plans the steps and obtains a quote | `deposit.quote_created` webhook fires with 2 steps and the populated `estimated` overlay | Steps array; `estimated.from.amount` and `estimated.to.amount` at deposit and step level (1:1) |
| 3 | You wire USD to OpenFX's bank account | — | — |
| 4 | OpenFX receives your wire and credits your OpenFX ledger | Two terminal `step.completed` events fire (one per step), followed by a `deposit.updated` event carrying the full Deposit with `actual.*` populated. Tesser only observes OpenFX's terminal reconciliation webhook, so no intermediate `step.submitted` or `step.confirmed` events are emitted. If the wire cannot be reconciled, two `step.failed` events fire instead, also followed by `deposit.updated`. | Steps 1 & 2: `actual.from.amount`, `actual.to.amount`, all timestamps. Deposit-level `actual.from.amount` and `actual.to.amount`. Deposit complete. |

:::note
The two `step.completed` events for Steps 1 and 2 arrive in close succession, followed immediately by `deposit.updated`.
:::

**Scenario 3 — Deposit and on-ramp to a self-custodial wallet via OpenFX**

| # | What happens | What you receive / do | Fields populated |
|---|---|---|---|
| 1 | You submit the deposit request | HTTP response with `id` | `desired.from.amount` |
| 2 | Tesser plans the steps and obtains a quote | `deposit.quote_created` webhook fires with 4 steps and the populated `estimated` overlay | Steps array; `estimated.from.amount` and `estimated.to.amount` at deposit and step level |
| 3 | You initiate a push of funds to the liquidity provider's bank account | — | — |
| 4 | Funds arrive at the liquidity provider and are credited to its ledger | Two terminal `step.completed` events fire for the fiat-transfer steps (steps 1 and 2). Tesser only observes OpenFX's terminal reconciliation webhook, so no intermediate `step.submitted` or `step.confirmed` events are emitted for these steps. | Steps 1 & 2: `actual.from.amount`, `actual.to.amount`, all timestamps. Deposit-level `actual.from.amount`. |
| 5 | Tesser executes the on-ramp trade at the liquidity provider | Step lifecycle events fire for the swap step | Step 3: `actual.from.amount`, `actual.to.amount` (reflects actual fill rate), all timestamps |
| 6 | Withdrawal to your wallet is initiated | `step.submitted` on the wallet-transfer step | Step 4: `submitted_at` |
| 7 | The on-chain transaction is broadcast and accepted into the network's mempool (not yet in a block) | `step.confirmed` on the wallet-transfer step | Step 4: `confirmed_at`, `transaction_hash` |
| 8 | The transfer reaches finality; deposit is complete | `step.completed` on the wallet-transfer step, and a `deposit.updated` event fires with the terminal Deposit object | Step 4: `completed_at`, `actual.to.amount`. Deposit-level `actual.to.amount`. |

:::note
Lifecycle events for Steps 1, 2, and 3 will arrive in close succession.
:::

**Scenario 4 — Deposit and on-ramp to a self-custodial wallet via Circle**

| # | What happens | What you receive / do | Fields populated |
|---|---|---|---|
| 1 | You submit the deposit request | HTTP response with `id` | `desired.from.amount` |
| 2 | Tesser plans the steps and obtains a quote | `deposit.quote_created` webhook fires with 3 steps and the populated `estimated` overlay | Steps array; `estimated.from.amount` and `estimated.to.amount` at deposit and step level (1:1) |
| 3 | You wire USD to Circle's bank account | — | — |
| 4 | Circle receives your wire, mints USDC, and credits your Circle ledger | Two terminal `step.completed` events fire for the fiat-transfer steps (Steps 1 and 2). Tesser observes Circle's terminal webhook for each step, so no intermediate `step.submitted` or `step.confirmed` events are emitted for these steps. | Steps 1 & 2: `actual.from.amount`, `actual.to.amount`, `confirmed_at`, `completed_at`. Deposit-level `actual.from.amount`. |
| 5 | Tesser initiates the on-chain transfer from your Circle ledger to your self-custodial wallet | `step.submitted` on Step 3 | Step 3: `submitted_at` |
| 6 | Circle acknowledges the transfer request (off-chain confirmation; the on-chain transaction has not yet settled) | `step.confirmed` on Step 3 | Step 3: `confirmed_at`. `transaction_hash` remains `null` at this stage. |
| 7 | Circle's on-chain settlement is observed via SNS; the deposit is complete | `step.completed` on Step 3, followed by a `deposit.updated` event with the terminal Deposit object | Step 3: `completed_at`, `transaction_hash`, `actual.from.amount`, `actual.to.amount`. Deposit-level `actual.to.amount`. Deposit complete. |

:::note
For the Circle ledger → wallet step, `transaction_hash` populates at `step.completed` — not at `step.confirmed`. This timing differs from the OpenFX wallet flow (Scenario 3), where Tesser broadcasts the on-chain transaction itself and populates `transaction_hash` at `step.confirmed`.
:::

:::note
Lifecycle events for Steps 1 and 2 will arrive in close succession.
:::

## Failure Modes for Deposits

If a deposit fails, the top-level `actual.*` fields populate only when at least one step has reached `step.status = completed`. With one or more completed steps, the top-level `actual.from` matches the first completed step's `actual.from`, and the top-level `actual.to` matches the last completed step's `actual.to`. With no completed step, the top-level `actual.*` stays all-null — `desired.*` and `estimated.*` describe the originally requested and quoted state. Failed steps always have all-null `actual.*`. Any steps subsequent to the failure step also transition to `failed`. Step-level `status_reasons` carries the failure cause only for steps that started (transitioned past `created`); never-started steps — including subsequent steps after a failure — show `status_reasons: []`.

### Example: Trade Fails to Complete at an Exchange or Ramp

If Tesser attempts the on-ramp trade at the liquidity provider and cannot get the trade to succeed before the deposit's `expires_at` timestamp, the deposit terminates as a fiat-only deposit. This means the source fiat remains at the liquidity provider, but the conversion into the target stablecoin did not happen. This situation can occur in scenario 3 (OpenFX with on-ramp).

What you will observe:

- `step.failed` on the swap step (step 3 in scenario 3). Step-level `actual.*` is null; `status_reasons` carries the failure detail.
- `step.failed` on the subsequent wallet-transfer step (step 4 in scenario 3). This step never entered `submitted` because there were no stablecoins to withdraw; step-level `actual.*` is null, and `status_reasons` is `[]` because the step never started — the failure cause lives at the resource level (the swap step failed, which terminated the deposit before this step could start).
- The deposit's top-level `actual.from` matches the first completed step's `actual.from` (the original fiat source), and `actual.to` matches the last completed step's `actual.to` — the OpenFX ledger holding the source USD. `desired.to.currency` stays as the originally requested stablecoin (client intent is never overwritten). For a USD→USDT deposit, the terminal top-level shows `actual.to.currency: "USD"` and `actual.to.amount` equal to `actual.from.amount`.
- The fiat balance at the ledger with the liquidity provider is available to use for a rebalance.
- A `deposit.updated` webhook fires alongside the terminal `step.failed` events, carrying the full updated Deposit object with the populated `actual.*` overlay. You can use this webhook instead of GETting the deposit to observe the terminal state.

:::note
The JSON examples below show steps 3 and 4 from scenario 3.
:::

<Tabs>
  <TabItem label="Step 3 (swap)">

Example webhook schema for `step.failed` on step 3 (swap):

```json
{
  "id": "d8a4f2c1-6e3b-4f59-a7c0-1d2e3f4a5b6c",
  "type": "step.failed",
  "created_at": "2025-12-03T04:00:00.000Z",
  "data": {
    "object": {
      "id": "5c7a8e4d-1b9f-4c62-a8e3-7d6f3b4a2c9e",
      "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "step_sequence": 3,
      "step_type": "swap",
      "estimated": {
        "from": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "999.525",
          "currency": "USDT",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "openfx",
      "status": "failed",
      "status_reasons": [
        {
          "error_code": "transfers-9304",
          "error_message": "The currency conversion trade failed"
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-03T04:00:00.000Z",
      "submitted_at": "2025-12-02T14:32:18.000Z",
      "confirmed_at": null,
      "completed_at": null,
      "failed_at": "2025-12-03T04:00:00.000Z"
    }
  }
}
```

  </TabItem>
  <TabItem label="Step 4 (wallet transfer)">

Example webhook schema for `step.failed` on step 4 (wallet transfer, never submitted):

```json
{
  "id": "e4b5f3d2-8c91-4a7b-b3e5-0d1f2a3b4c5d",
  "type": "step.failed",
  "created_at": "2025-12-03T04:00:00.100Z",
  "data": {
    "object": {
      "id": "9d3f6a2c-8e5b-4f17-b0a6-1c4e7d9f3b8a",
      "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "step_sequence": 4,
      "step_type": "transfer",
      "estimated": {
        "from": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "fees": [],
      "transaction_hash": null,
      "provider_key": "openfx",
      "status": "failed",
      "status_reasons": [],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-03T04:00:00.100Z",
      "submitted_at": null,
      "confirmed_at": null,
      "completed_at": null,
      "failed_at": "2025-12-03T04:00:00.100Z"
    }
  }
}
```

  </TabItem>
</Tabs>

Example `deposit.updated` webhook (deposit terminated as fiat after trade give-up):

```json
{
  "id": "c5f3a2d8-7b4e-4192-9d6c-3e8a1f2b5c7d",
  "type": "deposit.updated",
  "created_at": "2025-12-03T04:00:00.300Z",
  "data": {
    "object": {
      "id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": null,
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
          "amount": "999.525",
          "currency": "USDT",
          "network": "POLYGON"
        }
      },
      "actual": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
          "amount": "1000",
          "currency": "USD",
          "network": null
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:25:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:25:00.400Z",
          "completed_at": "2025-12-02T14:25:00.500Z",
          "failed_at": null
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "completed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-02T14:30:00.500Z",
          "submitted_at": null,
          "confirmed_at": "2025-12-02T14:30:00.400Z",
          "completed_at": "2025-12-02T14:30:00.500Z",
          "failed_at": null
        },
        {
          "id": "5c7a8e4d-1b9f-4c62-a8e3-7d6f3b4a2c9e",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 3,
          "step_type": "swap",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "failed",
          "status_reasons": [
            {
              "error_code": "transfers-9304",
              "error_message": "The currency conversion trade failed"
            }
          ],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-03T04:00:00.000Z",
          "submitted_at": "2025-12-02T14:32:18.000Z",
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": "2025-12-03T04:00:00.000Z"
        },
        {
          "id": "9d3f6a2c-8e5b-4f17-b0a6-1c4e7d9f3b8a",
          "deposit_id": "2b4c5e7a-9f3d-41b8-8c6a-7e5f9d2a1c3b",
          "step_sequence": 4,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "2e8f4c6b-3a1d-48e7-9b5c-0f4d2c9a7e3b",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            },
            "to": {
              "account_id": "7f3e9c2a-8d5b-4a1e-9f6c-3b8e1d4a7c5f",
              "amount": "999.525",
              "currency": "USDT",
              "network": "POLYGON"
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "openfx",
          "status": "failed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-03T04:00:00.100Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": "2025-12-03T04:00:00.100Z"
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-03T04:00:00.300Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```

### Example: Fiat Deposit Never Arrives or Is Not Credited

Tesser relies on the liquidity provider for notification of when your fiat funds have been received and credited. If that notification never arrives within the deposit's `expires_at` window — e.g., the wire was not sent, was returned, is stuck at an intermediary bank, or was received but could not be reconciled to your account at the liquidity provider — Tesser will time the deposit out. The same pattern applies in scenarios 1, 2, 3, and 4.

What you will observe:

- `step.failed` on every step that was still in `created` status when the deposit expired. Step-level `actual.*` is null; `status_reasons` is `[]` because the step never started — the failure cause lives at the resource level (the deposit reached `expires_at` while waiting for the customer's wire to arrive).
- The deposit's top-level `actual.*` is all null because no step reached `step.status = completed` — no funds ever moved.
- A `deposit.updated` webhook fires alongside the terminal `step.failed` events, carrying the full updated Deposit object reflecting the terminal state. You can use this webhook instead of GETting the deposit to observe the terminal state.

The example below illustrates scenario 1 (Circle, two steps); the shape of the payload is the same in scenarios 2, 3, and 4, with one `failed` step entry per never-started step.

Example `deposit.updated` webhook (Circle deposit, scenario 1, fiat never landed):

```json
{
  "id": "f6a8c4e2-3b9d-4f15-a7c8-5d2e9b1f3a4c",
  "type": "deposit.updated",
  "created_at": "2025-12-01T14:00:00.500Z",
  "data": {
    "object": {
      "id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
      "workspace_id": "b53f6690-3242-4942-9907-885779632832",
      "organization_reference_id": null,
      "direction": "inbound",
      "desired": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": null,
          "currency": "USDC",
          "network": null
        }
      },
      "estimated": {
        "from": {
          "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
          "amount": "1000",
          "currency": "USD",
          "network": null
        },
        "to": {
          "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
          "amount": "1000",
          "currency": "USDC",
          "network": null
        }
      },
      "actual": {
        "from": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        },
        "to": {
          "account_id": null,
          "amount": null,
          "currency": null,
          "network": null
        }
      },
      "steps": [
        {
          "id": "8a4f2c1e-9b6d-4e35-b7a0-3c5d1e9f2b8a",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 1,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "failed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T14:00:00.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": "2025-12-01T14:00:00.000Z"
        },
        {
          "id": "3b7e9d2f-1c4a-4f68-a5b0-6e8c1d3f9a2b",
          "deposit_id": "1c8e4a6f-9b2d-4f53-a0e7-5d3c1b9f2a8e",
          "step_sequence": 2,
          "step_type": "transfer",
          "estimated": {
            "from": {
              "account_id": "a81bc1f4-7e3d-4926-b04f-3d2e8a9c5f17",
              "amount": "1000",
              "currency": "USD",
              "network": null
            },
            "to": {
              "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
              "amount": "1000",
              "currency": "USDC",
              "network": null
            }
          },
          "actual": {
            "from": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            },
            "to": {
              "account_id": null,
              "amount": null,
              "currency": null,
              "network": null
            }
          },
          "fees": [],
          "transaction_hash": null,
          "provider_key": "circle_mint",
          "status": "failed",
          "status_reasons": [],
          "created_at": "2025-12-01T10:00:00.000Z",
          "updated_at": "2025-12-01T14:00:00.000Z",
          "submitted_at": null,
          "confirmed_at": null,
          "completed_at": null,
          "failed_at": "2025-12-01T14:00:00.000Z"
        }
      ],
      "created_at": "2025-12-01T10:00:00.000Z",
      "updated_at": "2025-12-01T14:00:00.500Z",
      "expires_at": "2025-12-01T14:00:00.000Z"
    }
  }
}
```
