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

# One-off bank deposit

> POST /v1/bank/deposit - take a bank transfer without opening a virtual account.

Takes a single incoming bank transfer and settles stablecoins to a wallet,
**without opening a virtual account**. Use it where a user pays once, or where the
country supports it but you would rather not issue permanent bank details.

The difference from [Bank transfers](/api-reference/bank-transfer): those issue
details the user keeps and reuses; this returns details for one payment, valid
until they expire.

<Note>
  Needs the **bank permission** on your API key. See
  [Authentication](/api-reference/authentication).
</Note>

<Warning>
  **Not every country offers this.** Where a local rail requires an account in the
  payer's own name, the virtual account route is the only one open. Check
  [GET /v1/payment-methods](/api-reference/reference/payment-methods) for the
  country before offering it - `bank_deposit` in the response is what tells you it
  is available.
</Warning>

## Request

<ParamField body="accountId" type="string" required>
  The user paying. Onboard them first - see
  [Bank transfers](/api-reference/bank-transfer) and [Rheon ID](/rheon-id).
</ParamField>

<ParamField body="walletId" type="string" required>
  The registered wallet the settled stablecoin is delivered to.
</ParamField>

<ParamField body="fiatCurrency" type="string" required>
  ISO 4217 code the user is paying in.
</ParamField>

<ParamField body="fiatAmount" type="string" required>
  What the user will send. The details returned are for this amount - a transfer
  that differs is handled as described below.
</ParamField>

<ParamField body="reference" type="string">
  Your idempotency key, up to 64 characters. A retry with the same value returns
  the original deposit rather than issuing a second set of details.
</ParamField>

## Response

<ResponseField name="id" type="string">
  The deposit id. Poll with
  [POST /v1/bank/deposit/status](/api-reference/bank-deposit-status).
</ResponseField>

<ResponseField name="details" type="object">
  The bank details to display, plus the payment reference. The shape follows the
  rail - an IBAN and BIC for SEPA, an account and sort code for UK rails, a CLABE
  for SPEI, a QR payload or key for PIX. Render what comes back rather than
  assuming a shape.
</ResponseField>

<ResponseField name="rail" type="string">
  The rail these details are on.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  ISO 8601. After this the details stop accepting money; money already in flight
  still settles.
</ResponseField>

<ResponseField name="status" type="string">
  `awaiting_funds` on creation.
</ResponseField>

<Warning>
  **The reference is what attributes the money.** A transfer sent without it, or
  with it edited, has to be matched by hand and can take days. Show it exactly as
  returned and where the user cannot miss it.
</Warning>

<Note>
  An amount that differs from the one quoted still settles: what arrives is
  converted at the rate on arrival and delivered. An amount below the rail's
  minimum is returned to the sending account instead, minus the rail's own cost.
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "$RHEON_API/v1/bank/deposit" \
    -H "Authorization: Bearer $RHEON_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "accountId": "acct_8f2c91d0a4",
      "walletId": "wlt_5b71e0c3",
      "fiatCurrency": "EUR",
      "fiatAmount": "500.00",
      "reference": "deposit-2026-09-02-77"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "bdp_3a71f0c9e4",
    "details": {
      "iban": "IE25XXXX99035504017602",
      "bic": "XXXXIE2D",
      "beneficiary": "Rheon Payments",
      "reference": "RHN-77310"
    },
    "rail": "sepa_instant",
    "expiresAt": "2026-09-09T17:30:00Z",
    "status": "awaiting_funds"
  }
  ```
</ResponseExample>

## Errors

| HTTP | `code`              | When                                                               |
| ---- | ------------------- | ------------------------------------------------------------------ |
| 400  | `invalid_request`   | A field is missing or malformed.                                   |
| 401  | `unauthorized`      | Missing, malformed, or unknown API key.                            |
| 403  | `permission_denied` | Your key does not carry the bank permission.                       |
| 404  | `account_not_found` | No such `accountId` or `walletId` under your key.                  |
| 422  | `no_route`          | This currency has no one-off rail; open a virtual account instead. |
| 422  | `requires_action`   | The user needs a higher verification tier first.                   |
| 429  | `rate_limited`      | Over your key's rate limit.                                        |
| 502  | `upstream_error`    | The banking partner is unavailable.                                |
| 500  | `internal`          | Unexpected server error.                                           |
