---
title: "Accounts v2"
description: "Open a bank account for a customer at the bank option you choose, follow it until it has bank details, and receive deposits."
---
**API version:** v2.

Use Accounts v2 to open a bank account for a customer. You choose the bank option, read what that bank needs, open the account in one call, and follow it until it has bank details. Each step has its own page, linked below.

**A money example.** Ada, a UK freelancer, wants to be paid 1,200.00 USD by a US client.

1. [Capabilities](/platform/accounts/find-an-account-option) says which USD options a GB individual can open. You pick a wallet-backed one.
2. [Requirements](/platform/accounts/read-account-requirements) lists the fields and documents that option needs.
3. [`POST /v2/accounts`](/platform/accounts/open-an-account) returns `{"account_id": "…", "status": "pending"}`.
4. You wait for `applications.accounts.completed` ([Track activation](/platform/accounts/track-account-activation)), then [read the account](/platform/accounts/list-and-read-accounts) for its account and routing numbers.
5. The client sends 1,200.00 USD by ACH, and you see it with the deposit webhooks ([Receive deposits](/platform/accounts/receive-deposits)).

## The flow

```mermaid title="Opening a v2 account"
flowchart LR
    A[Customer KYC completed] --> B[GET /v1/accounts/capabilities]
    B --> C[GET /v2/accounts/requirements]
    C --> D[POST /v2/accounts]
    D --> E{Account status}
    E -- active --> F[Show bank details]
    E -- pending, requires_user_action --> G[PATCH the application]
    G --> E
    E -- rejected or failed --> H[Choose another option]
```

## Account and application

Opening a v2 account creates two records:

- The **account** (`id`), which payers send money to once it is `active`.
- The **application** (`application_id`), which tracks the bank's review. The create response does not include its id, so read it from [`GET /v2/accounts/{id}`](/api-reference/accounts-v2/get-v2-accounts-id).

Account statuses:

```mermaid title="v2 account status"
flowchart LR
    pending --> active
    pending --> rejected
    pending --> failed
    pending --> frozen
    active --> frozen
    frozen --> active
    active --> closed
```

Application statuses:

| Status | Meaning |
| :-- | :-- |
| `processing` | The bank is working on the application |
| `blocked` | The application waits on you or the customer |
| `manual_review` | Gravv holds the application |
| `approved`, `rejected` | The final outcome, after the statuses above |
| `expired`, `cancelled` | These also end an application |
| `draft`, `submitted` | These appear only on applications not made with `POST /v2/accounts` |

## What you can open

For any one customer, [capabilities](/platform/accounts/find-an-account-option) gives the current answer. Today, the options are:

| Currency | Wallet-backed (USDC behind the account) | Fiat-only (money stays in the currency) |
| :-- | :-- | :-- |
| USD | Available for individuals and businesses | Available for US residents and US companies, and for Kenya residents |
| EUR | Available | Available. One IBAN per customer, EUR or GBP |
| GBP | Available | Available. One IBAN per customer, EUR or GBP |
| NGN | Not supported | Available for Nigeria |
| KES, TZS, UGX | Not supported | Available for Kenya residents |
| CNY, RWF | Not supported | Not yet available |
| MXN, BRL, COP and others | Not supported | Not supported |

Each option excludes some countries. The lists change, so read `excluded_countries` from capabilities for each customer rather than storing them.

For a wallet-backed account, Gravv supports `stellar`, `polygon`, `ethereum`, `avalanche_c_chain` and `solana`. Send one of these that the option's `token_options` in requirements also lists. An option can list other networks too. Treat those as not supported. If in doubt, use `polygon`, which every wallet-backed option offers.

## Before you start

- A customer whose `basic` KYC is `completed`. Otherwise the API refuses the create call with `CUSTOMER_KYC_INCOMPLETE`.
- If you use a scoped API key, it needs `account:create` for create and PATCH.
- A webhook URL for `applications.accounts.*` events, or a plan to poll `GET /v2/accounts/{id}`.

## Pages

<CardGroup cols={2}>
  <Card title="Find an account option" href="/platform/accounts/find-an-account-option">
    Read which banks, currencies, networks and rails a customer can have.
  </Card>
  <Card title="Read account requirements" href="/platform/accounts/read-account-requirements">
    Get the fields and documents a bank needs, and turn them into a request.
  </Card>
  <Card title="Open an account" href="/platform/accounts/open-an-account">
    Send one POST /v2/accounts and read the errors it can return.
  </Card>
  <Card title="Track activation" href="/platform/accounts/track-account-activation">
    Follow the application with webhooks or by reading the account.
  </Card>
  <Card title="Fix a blocked application" href="/platform/accounts/fix-a-blocked-application">
    Send the documents or data the bank asked for, or the customer's link.
  </Card>
  <Card title="List and read accounts" href="/platform/accounts/list-and-read-accounts">
    List accounts with filters, and read balances and the bank details to give payers.
  </Card>
  <Card title="Receive deposits" href="/platform/accounts/receive-deposits">
    Read the deposit webhooks for fiat-only and wallet-backed accounts.
  </Card>
  <Card title="Test accounts in sandbox" href="/platform/accounts/test-accounts-in-sandbox">
    Simulate a deposit and learn what sandbox cannot do.
  </Card>
</CardGroup>
