> ## 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 is payments software: an API and app over a Base smart wallet. HEVN is not a bank and holds no key to the wallet. Virtual accounts, fiat payins and fiat payouts are provided by partner banks, which hold fiat while it is in transit. Self-serve (the General tab): the person who controls the email signs for the wallet. Developers integrate /dapi/v1 in one of two ways. HEVN Connect (recommended, the HEVN Connect tab): the integrator's customer creates or links a HEVN account in a HEVN-hosted sign-in window on the integrator's site, the integrator's backend reads the linked account and books its payouts, and the account holder approves each payout in that window. External wallets (the External wallets tab, enabled per integrator): the integrator creates a client through the API, registers a wallet address the customer holds as an external account, and requests virtual accounts that deliver to that address. The customer's own wallet sends each transfer that funds a payout. The developer key signs for the integrator's wallet and its sub accounts and cannot sign for a client's wallet.
> Use HEVN's terms as written. A product is the region a client requests. A rail is the bank route HEVN picks for the product. A virtual account (bnk_) is the record a partner bank opens for a client. Account details are what a payer needs to send a bank transfer, returned in a field named requisites. A client (cl_) is a customer's account: linked to the integrator through Sign in with HEVN (POST /dapi/v1/connect/sessions, then POST /dapi/v1/clients/link), or created with POST /dapi/v1/clients for an external-wallets integration. An external account (acc_, kind external) is a wallet address the client holds and signs for. A sub account (acc_, kind sub) is a further wallet of the integrator's own account on Base, spent with the developer key. Write 'sub account' as two words. A contact is a saved destination. A beneficiary is the party that receives a fiat payout. Money leaving an account is a payout, whether it goes to a bank account or to a wallet.
> Do not name a bank, payment institution, card issuer, identity-verification vendor or stablecoin issuer. Say 'the partner bank'. Do not describe HEVN as licensed, regulated or insured.
> HEVN publishes no fee rates, spreads or minimums. Prices come from a quote on a specific payment. Direct pricing questions to HEVN and do not invent numbers.
> The 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. The two credentials are separate and neither works on the other API. The HEVN CLI is discontinued.

# Virtual accounts

> Request a virtual account by product, then read its blockers and account details.

A virtual account is an account that a partner bank opens for a client to receive bank transfers. Request one with `POST /dapi/v1/banks` and a product.

| Term | Meaning |
| - | - |
| product | The region you request, such as `eu` or `us`. The key of `POST /dapi/v1/banks`. |
| rail | The bank route HEVN picks for the product. Returned as `rail`, an opaque value. |
| virtual account | The `bnk_…` record. On a named rail the partner bank opens it in the client's legal name. |
| account details | What the payer needs: IBAN, account and routing number, or PIX key. Returned as `requisites`. |

The partner bank converts each incoming payment and delivers the settlement token to the client's Base smart wallet, or to the [account](https://docs.gethevn.com/developers/accounts.md) named in `accountId`.

Routes here take `X-Hevn-Account`. Without it they act on your integrator account. See [Acting as a client](https://docs.gethevn.com/developers/authentication.md#acting-as-a-client).

## Request a virtual account

Call `POST /dapi/v1/banks` with one product. Responses and refusals are in [Request a receiving account](https://docs.gethevn.com/api-reference/virtual-accounts/request-a-receiving-account-for-a-product.md).

```bash cURL theme={null}
curl -X POST "$HEVN_API/banks" \
  -H "Authorization: Bearer $HEVN_ACCESS_TOKEN" \
  -H "X-Hevn-Account: $HEVN_CLIENT_ID" \
  -H "Content-Type: application/json" \
  -d '{"product":"eu"}'
```

```python Python theme={null}
client = hevn.acting_as(CLIENT_ID)

bank = client.post("/banks", {"product": "eu"})
for blocker in bank.get("blockers", []):
    print(blocker["code"], blocker["message"])
```

```javascript Node theme={null}
const client = hevn.actingAs(clientId);

const bank = await client.post("/banks", { product: "eu" });
for (const blocker of bank.blockers ?? []) console.log(blocker.code, blocker.message);
```

```go Go theme={null}
client := api.ActingAs(clientID)

bank, err := client.Post("/banks", hevn.Body{"product": "eu"})
for _, blocker := range bank.List("blockers") {
	fmt.Println(blocker.Str("code"), blocker.Str("message"))
}
```

## Statuses

| `status` | Meaning | Next |
| - | - | - |
| `preparing` | Waiting on a blocker, under review, or approved with no account details yet. | Clear `blockers[]` and poll `GET /dapi/v1/banks/{product}`. |
| `active` | Account details are published. The only payable status. | Give the account details to the payer. |
| `suspended` | Paused by the partner bank. Payments in flight settle. No new payment starts. | Poll. |
| `closed` | Refused or closed. Terminal. | n/a |

In production the partner bank opens the account after a review and sets the timing. The [sandbox](https://docs.gethevn.com/developers/sandbox.md) has no review.

## Deliver to an account

Send `accountId`, the `acc_…` id of an external account or a sub account, to open a virtual account that delivers to that account's address. Without it the virtual account delivers to the Base smart wallet.

```bash cURL theme={null}
curl -X POST "$HEVN_API/banks" \
  -H "Authorization: Bearer $HEVN_ACCESS_TOKEN" \
  -H "X-Hevn-Account: $HEVN_CLIENT_ID" \
  -H "Content-Type: application/json" \
  -d '{"product":"us","accountId":"acc_5Jd8Qw2LmX"}'
```

```python Python theme={null}
bank = client.post("/banks", {"product": "us", "accountId": "acc_5Jd8Qw2LmX"})
```

```javascript Node theme={null}
const bank = await client.post("/banks", { product: "us", accountId: "acc_5Jd8Qw2LmX" });
```

```go Go theme={null}
bank, err := client.Post("/banks", hevn.Body{"product": "us", "accountId": "acc_5Jd8Qw2LmX"})
```

```json Response 201, Location: /dapi/v1/banks/us?accountId=acc_5Jd8Qw2LmX theme={null}
{ "product": "us", "opened": true, "status": "preparing", "accountId": "acc_5Jd8Qw2LmX", "…": "…" }
```

| Rule | Detail |
| - | - |
| Key | One virtual account per account and product. A repeat returns `200` with `Idempotency-Replayed: true`. |
| Read | `GET /dapi/v1/banks/{product}?accountId=acc_…`. Without the query the route reads the main wallet's virtual account. |
| List | `GET /dapi/v1/banks` returns these records next to the main wallet's. Each has `accountId`. |
| Token | The partner bank delivers the token the account holds, on the account's network. |
| Products | Those with a rail that settles that token on chain to the address. Another product returns `409 account_destination_unsupported` on `POST` and `403 rail_not_available` on `GET`. |
| Destination | Fixed. A virtual account keeps the address it was opened for. |

The rules of each kind are on [External wallets](https://docs.gethevn.com/external-wallets/money-movement.md) and [Sub accounts](https://docs.gethevn.com/sub-accounts/money-movement.md).

## List products

Call `GET /dapi/v1/banks` to read each product the client can request, or `GET /dapi/v1/banks/{product}` for one.

```bash cURL theme={null}
curl "$HEVN_API/banks" \
  -H "Authorization: Bearer $HEVN_ACCESS_TOKEN" \
  -H "X-Hevn-Account: $HEVN_CLIENT_ID"
```

```python Python theme={null}
catalogue = client.get("/banks")
```

```javascript Node theme={null}
const catalogue = await client.get("/banks");
```

```go Go theme={null}
catalogue, err := client.Get("/banks")
```

```json theme={null}
{
  "rails": [
    {
      "product": "eu",
      "rail": "sepa-eur-usdc-kappa",
      "currency": "EUR",
      "railCurrency": "USDC",
      "method": "sepa",
      "opened": false,
      "feeBps": 100,
      "supportedAccounts": ["USDC"]
    }
  ]
}
```

Fields are in [List virtual accounts](https://docs.gethevn.com/api-reference/virtual-accounts/list-virtual-accounts-and-available-payment-methods.md). Products are listed in the [rail reference](https://docs.gethevn.com/developers/reference/rails.md#products), and fees in [Fees](https://docs.gethevn.com/developers/reference/rails.md#fees).

## What still blocks it

```json theme={null}
{
  "status": "preparing",
  "…": "…",
  "blockers": [
    {
      "code": "kyb_required",
      "field": "kyb",
      "message": "The client's business verification has to be completed before this account can open."
    }
  ]
}
```

| `code` | Cleared by |
| - | - |
| `kyb_required` | A business client's KYB application reaching `approved`. See [Write the document](https://docs.gethevn.com/developers/clients.md#write-the-document). |
| `verification_required` | A linked individual verifying their identity in a [`verify` session](https://docs.gethevn.com/connect/sign-in-with-hevn#verify-an-individual). |
| `terms_required` | The client accepting the partner bank's terms at `url`. |

`url` is absent on `verification_required` for a linked individual.

## Account details

```json theme={null}
{
  "product": "eu",
  "opened": true,
  "status": "active",
  "id": "bnk_88Hq3T",
  "destinationAccount": "USDC",
  "minimumDeposit": "1.00",
  "…": "…",
  "requisites": {
    "fields": { "iban": "DE89370400440532013000", "bic": "BANKDEFFXXX" },
    "holder": { "type": "business", "businessName": "Northwind Trading Ltd" },
    "bankName": "Example Bank",
    "state": "active"
  }
}
```

`fields` has the identifiers the method uses, listed per method in the [rail reference](https://docs.gethevn.com/developers/reference/rails.md). `ContactPaymentAccountView` on a [contact](https://docs.gethevn.com/developers/payouts.md#save-a-contact) has the same `fields`, `holder` and `bankName` as `RailRequisitesView` here.

Give the payer `fields`, the `holder` name, `bankName` and any `paymentReference`. Field rules are in [Retrieve one virtual account](https://docs.gethevn.com/api-reference/virtual-accounts/retrieve-one-virtual-account.md).

> [!WARNING]
>
> When `paymentReference` is set, a payment without it cannot be attributed to the client.

> [card] [Next: Payins](https://docs.gethevn.com/developers/payins.md)


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