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

> ## Agent Instructions
> HEVN accounts are non-custodial in both products. Self-serve (the General tab): the person who owns the email holds the only key and signs for themselves. Whitelabel (the Whitelabel and REST API tabs): the integrator's customer creates and owns their account through Sign in with HEVN, a HEVN-hosted popup on the integrator's site; the integrator's backend holds a developer key, operates linked accounts and books their payouts, and the account holder approves every payout in that popup. The developer key signs only for the integrator's own wallet; it never signs a client's money.
> Use HEVN's terms exactly. A rail is a bank route a client can request. A virtual account (bnk_) is an opened rail. Account details are what a payer needs in order to wire money, and arrive in a field named requisites. A client is a customer's own account linked to the integrator through Sign in with HEVN (POST /dapi/v1/connect/sessions, then POST /dapi/v1/clients/link); there is no API call that creates one. The business behind it is the integrator's customer. A contact is a saved destination; a beneficiary is the party at the far end of a fiat payout. Every departure of money is a payout, to a bank account or to a wallet alike.
> Never name a banking partner. Say 'a licensed banking partner'.
> There are no published fee rates, spreads or minimums. Prices come from a quote on a specific payment; direct pricing questions to HEVN rather than inventing numbers.
> The whitelabel API is at /dapi/v1 and takes a developer-key session plus an X-Hevn-Account header. Developer keys have an IP allowlist and no scopes. Remote transfers are at /api/v1/remote_spend_limit and take a remote transfer key (rsl_) in X-Api-Key, bounded by an onchain spend permission the account holder grants. They are different credentials and neither works on the other surface. The HEVN CLI is discontinued.

# Fees

> Where a fee is declared, where it is quoted, which side of a payment absorbs it, and why the quote is the only number you are held to.

There is no price list in this API and there is no page you can read a rate off. Every price is
attached to a specific movement of money, for a specific client, at the moment you ask for it. This
page is where those numbers live and how to read them.

> [!NOTE]
>
> The rates behind them are commercial and set per integrator. Ask HEVN for yours — the API will
> then quote them back to you on every payment.

## Two kinds of number

Every price in this API is one of two things, and they are never interchangeable.

| | **Declared** | **Quoted** |
| - | - | - |
| What it is | A rate published on a rail or a capability, before any payment exists | The terms of one specific payment |
| Where it comes from | `GET /dapi/v1/banks`, `GET /dapi/v1/banks/{product}/rate`, `GET /dapi/v1/contacts/{contactId}/capabilities`, `POST /dapi/v1/payouts/preview`, `GET /dapi/v1/rates` | The `quote` on a `POST /dapi/v1/payins` or `POST /dapi/v1/payouts` response |
| What it is for | Showing your customer a number before they commit to an amount | Charging them |
| Does it bind | **No.** It is indicative and can move | **Yes.** It is what settles, until `expiresAt` |

Show declared numbers in your UI. Reconcile against quoted ones. Never store a declared rate and
bill from it later.

## The fields that carry a fee

### On a rail

A record from `GET /dapi/v1/banks` carries `feeBps` — HEVN's deposit fee for that product in basis
points, a whole number, taken out of the converted amount. `100` is one per cent, so `25` is 0.25%.
It comes from the client's plan, so two clients can read different values for the same product.
It carries `minimumDeposit` too: the smallest amount the partner will accept over that rail, in the
rail's own currency. Anything under it is returned by the bank, not refused by us.

`GET /dapi/v1/banks/{product}/rate` is the indicative price of a deposit over one product:

```json theme={null}
{ "currency": "EUR", "rate": "…", "fixedFee": "…", "fixedFeeCurrency": "EUR" }
```

On a product the client has not requested, only `currency` comes back.

### On a contact

`GET /dapi/v1/contacts/{contactId}/capabilities?amount=500.00` is the closest thing to a price list
this API has, because it is scoped to one real destination. It answers one `options` row per payable
account, each carrying `method`, `currency`, `minAmount`, `maxAmount`, `feeBps`, `fixedFee`, whether
a `purpose`, a memo or documents are required — and `blockers[]`, which is everything that would
refuse a payout to that contact right now.

`POST /dapi/v1/payouts/preview` takes `{"rail", "amount"}` and prices a rail with no contact and no
side effects.

Neither is a gate. `POST /dapi/v1/payouts` re-checks the same conditions on its own, and its numbers
are the ones you are held to.

### On a payin

The `quote` on `POST /dapi/v1/payins` states both ends and the cost between them:

```json theme={null}
{ "amount": "2000.00", "currency": "EUR",
  "amountTo": "…", "destinationAccount": "USDC",
  "feeAmount": "10.50", "feeCurrency": "EUR", "rate": "1.0000" }
```

### On a payout

A payout's `quote` has three shapes, and which one you get is decided by the contact — not by a flag
you set.

**A bank payout** converts, so it carries everything:

```json theme={null}
{ "fromAmount": "500.00", "fromCurrency": "USD",
  "toAmount": "459.31", "toCurrency": "EUR",
  "rate": "0.9247", "feeAmount": "1.00", "feeCurrency": "USD",
  "expiresAt": "2026-09-17T10:06:11Z" }
```

**An account paid on Base** converts nothing, so `rate`, `feeAmount` and `expiresAt` are
**absent** rather than filled with `1` and `0`, and the two amounts are the same money:

```json theme={null}
{ "fromAmount": "1.50", "fromCurrency": "USDC",
  "toAmount": "1.50", "toCurrency": "USDC" }
```

**A routed payout** to another chain is priced as a route, not a conversion: `feeAmount` is the
route's cost, `rate` stays absent, and the quote expires.

```json theme={null}
{ "fromAmount": "1.50", "fromCurrency": "USDC",
  "toAmount": "1.4923", "toCurrency": "USDC",
  "feeAmount": "0.0077", "feeCurrency": "USD",
  "expiresAt": "2026-09-17T10:06:11Z",
  "fromChainId": "base", "toChainId": "arb" }
```

> [!WARNING]
>
> Branch on the presence of a field, not on its value. A missing `rate` means nothing was converted;
> a `rate` of `"1.0000"` means something was converted at par. They are different facts.

## Which side absorbs the fee

You decide, by choosing which side of the payment to pin. Send exactly one:

| You send | You are fixing | The other side | Use it when |
| - | - | - | - |
| `amount` | What leaves the client's balance | Derived — the beneficiary receives less | The payer's budget is fixed |
| `amountTo` | What the beneficiary receives | Derived — HEVN grosses the debit up | The beneficiary's net is fixed |

Sending both is refused. Deriving the other side yourself and sending it as the pinned side is worse:
it will be right until a rate moves between your calculation and the booking, and then it will be
quietly wrong. See [Conventions](https://docs.gethevn.com/whitelabel/conventions.md#money).

## What is not a fee

* **Gas.** A client's Base smart wallet transacts through an ERC-4337 paymaster, so there is no
  network fee line on any quote and no ETH for anyone to hold.
* **`GET /dapi/v1/rates`.** It converts one currency or token into another at the current market
  rate and says so with `indicative: true`. It is a display rate; no payment ever settles at it.
* **The escrow `feeBps`.** On `capture` and `charge` that field is **your own** take rate, deducted
  from the captured amount before the seller is paid, up to the ceiling fixed when the deal was
  created. It is revenue for you, not a cost from HEVN. See
  [Escrow actions](https://docs.gethevn.com/whitelabel/escrow-actions.md#the-matrix).

## Reading the cost back after the fact

The quote is what you were charged; the ledger is what happened. A transaction row carries its
amounts as two sides — `from` is what left the source, `to` is what arrived — so the difference
between them is the whole cost of that movement, whatever it was made of.
`GET /dapi/v1/transactions/summary` totals the same filters, and
`GET /dapi/v1/transactions/export` renders a statement your customer's accountant can read. See
[Balances and transactions](https://docs.gethevn.com/whitelabel/balances-and-transactions.md).

> [card] [Next: Rails and payment methods](https://docs.gethevn.com/whitelabel/reference/rails.md)
>
> What each method needs, which currencies the deposit products carry, and what a product is.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.