---
title: "Open an account held in Kenya"
description: "Open a KES, TZS, UGX, USD, EUR or GBP account at a Kenyan bank for a customer resident or incorporated in Kenya."
---
Open a KES, TZS, UGX, USD, EUR or GBP account at a Kenyan bank for a customer who is resident or incorporated in Kenya.

**API version:** v2.

**Who it is for.** A Nairobi import business that wants a KES operating account and a USD account at a Kenyan bank to pay suppliers.

**Status.** Available for customers in Kenya in KES, TZS, UGX, USD, EUR and GBP. CNY and RWF are Not yet available. These accounts are fiat-only and have no wallet.

## Money example

Savanna Traders Ltd receives 650,000.00 KES from a buyer.

1. The buyer transfers 650,000.00 KES to the account number at the named bank.
2. The bank credits the deposit. Gravv sends `transfer.inflow.completed` with `currency` `KES`.

## Before you start

- The customer's `basic` KYC is `completed`, and the customer is resident or incorporated in Kenya. Sandbox lists this option for other countries too, so check the country yourself.
- Capabilities with `country=KE&currency=KES` list the option. Its `rails` can be `[]`. If so, ask support which local rails payers can use before you promise them.

## Find out what is required

Read requirements with `country=KE`. The form is short:

| | A person | A business |
| :-- | :-- | :-- |
| Fields | `first_name` and `last_name`. Gravv fills both from the customer if you leave them out | `legal_name`. Gravv fills it from the customer if you leave it out |
| Parties, documents | None | None |

## Steps

### 1. Open the account

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v2/accounts \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: 2de0aa93-f75b-4ed4-a486-010cf885aca7' \
     --header 'Content-Type: application/json' \
     --data '
{
  "customer_id": "8e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
  "customer_type": "business",
  "currency": "KES",
  "account_type": "operating",
  "category": "sub_account",
  "bank_code": "<bank_code>",
  "label": "Savanna KES",
  "data": {
    "root": {
      "legal_name": "Savanna Traders Ltd",
      "incorporation_country": "KE"
    }
  }
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v2/accounts", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Idempotency-Key": "2de0aa93-f75b-4ed4-a486-010cf885aca7",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "customer_id": "8e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
    "customer_type": "business",
    "currency": "KES",
    "account_type": "operating",
    "category": "sub_account",
    "bank_code": "<bank_code>",
    "label": "Savanna KES",
    "data": {
      "root": {
        "legal_name": "Savanna Traders Ltd",
        "incorporation_country": "KE"
      }
    }
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v2/accounts",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Idempotency-Key": "2de0aa93-f75b-4ed4-a486-010cf885aca7",
        "Content-Type": "application/json",
    },
    json={
        "customer_id": "8e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
        "customer_type": "business",
        "currency": "KES",
        "account_type": "operating",
        "category": "sub_account",
        "bank_code": "<bank_code>",
        "label": "Savanna KES",
        "data": {
            "root": {
                "legal_name": "Savanna Traders Ltd",
                "incorporation_country": "KE",
            },
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

The API returns `{"account_id": "…", "status": "pending"}`.

### 2. Read the account

Read `GET /v2/accounts/{id}` until the status is `active`. The payer needs `virtual_account_bank_name` and `virtual_account_bank_account_number`. These accounts have no routing number.

### 3. Add another currency

For a USD account at the same bank, send the same body with `"currency": "USD"` and a new key.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `bank_code=<code> does not open accounts for customers resident in UG. …` | The customer is not in Kenya | Use this option only for customers in Kenya |
| 400 `network is only accepted for account options that support wallet integration` | You sent `network` | Remove it |
| 400 `details.<key>`: `unknown_field: is not a recognized field` | You misspelled a key | Fix the key name |
| The option shows `rails: []` | Gravv publishes no incoming rails for it | Ask support before you promise a rail |

## Webhooks you will receive

Gravv sends `applications.accounts.*` events until the account is active. For each deposit, Gravv sends `transfer.inflow.completed`.

## Testing in sandbox

Sandbox has no simulator that opens this account. Sandbox calls the bank's test system, so activation is not instant. You can still simulate a deposit. Send no `rail` in the simulator request.

## Reference

- [Create an account](/api-reference/accounts-v2/post-v2-accounts)
- [Get account capabilities](/api-reference/accounts-v2/get-v1-accounts-capabilities)
