---
title: "Open an NGN account"
description: "Open a naira account with a 10-digit Nigerian account number for a Nigerian customer, using their BVN."
---
Open a naira account with a 10-digit Nigerian account number for a Nigerian customer. Gravv checks the customer's BVN before it opens the account.

**API version:** v2.

**Who it is for.** A Lagos savings or payroll app that gives each customer a Nigerian bank account number to receive naira.

**Status.** Available for customers in Nigeria. The v2 API opens NGN accounts as fiat-only.

## Money example

Chidi's employer pays his salary of 450,000.00 NGN.

1. The employer sends 450,000.00 NGN by bank transfer to Chidi's 10-digit account number.
2. The bank credits the deposit. Gravv books 450,000.00 NGN and sends `transfer.inflow.completed`.
3. Chidi's balance shows 450,000.00 NGN. NGN deposits carry no deposit fee.

## Before you start

- The customer's `basic` KYC is `completed`, and the customer's address is in Nigeria.
- You have the customer's BVN (Bank Verification Number, 11 digits). Gravv checks it against the national registry, and the names you send must match it.
- Capabilities with `currency=NGN&country=NG` show the NGN option, with `token_wallets: []`.

## Find out what is required

Read requirements with `customer_type=individual&currency=NGN&category=sub_account&country=NG`. A person and a business use the same short form:

| Field | Required | Notes |
| :-- | :-- | :-- |
| `first_name`, `middle_name`, `last_name` | Yes | Exactly as on the BVN record |
| `phone` | Yes | |
| `bank_verification_number` | Yes | Write-only. The API accepts the old name `bvn`. Never send both |
| `phone_daytime` | No | |

The form has no documents and no parties.

## Steps

### 1. Open the account

Always send `category`. If you leave it out on a first NGN account, Gravv stores the account with the NGN default, `multi_currency`, which this option does not list. On a second NGN account, the API refuses a request without `category` or `account_type`.

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v2/accounts \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: 27146fe8-0cd4-400e-8fc0-b27a5e6e509d' \
     --header 'Content-Type: application/json' \
     --data '
{
  "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
  "customer_type": "individual",
  "currency": "NGN",
  "account_type": "operating",
  "category": "sub_account",
  "bank_code": "<bank_code>",
  "label": "Chidi NGN",
  "data": {
    "root": {
      "first_name": "Chidi",
      "middle_name": "Emeka",
      "last_name": "Okafor",
      "phone": "+2348031234567",
      "bank_verification_number": "22123456789"
    }
  }
}
'
```
```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": "27146fe8-0cd4-400e-8fc0-b27a5e6e509d",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
    "customer_type": "individual",
    "currency": "NGN",
    "account_type": "operating",
    "category": "sub_account",
    "bank_code": "<bank_code>",
    "label": "Chidi NGN",
    "data": {
      "root": {
        "first_name": "Chidi",
        "middle_name": "Emeka",
        "last_name": "Okafor",
        "phone": "+2348031234567",
        "bank_verification_number": "22123456789"
      }
    }
  }),
});
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": "27146fe8-0cd4-400e-8fc0-b27a5e6e509d",
        "Content-Type": "application/json",
    },
    json={
        "customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
        "customer_type": "individual",
        "currency": "NGN",
        "account_type": "operating",
        "category": "sub_account",
        "bank_code": "<bank_code>",
        "label": "Chidi NGN",
        "data": {
            "root": {
                "first_name": "Chidi",
                "middle_name": "Emeka",
                "last_name": "Okafor",
                "phone": "+2348031234567",
                "bank_verification_number": "22123456789",
            },
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

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

### 2. Read the account number

Read `GET /v2/accounts/{id}` until the status is `active`. Show `virtual_account_bank_account_number` (10 digits), `virtual_account_bank_name` and the beneficiary name. NGN accounts have no routing number.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `details.bank_verification_number`: `required: is required` | You sent no BVN | Ask the customer for it |
| 400 `details.bank_verification_number`: `alias_conflict: submitted more than once (as "bvn" and "bank_verification_number") — …` | You sent both names | Send only `bank_verification_number` |
| 400 `details.middle_name`: `required: is required` | You sent no middle name | Ask the customer. This bank requires it |
| 400 `the bank verification number does not exist` (`BVN_NOT_FOUND`) | The BVN is not in the registry | Check the 11 digits with the customer |
| 400 `the bank verification number is invalid` (`BVN_INVALID`) | The BVN is malformed | Check it with the customer |
| 400 `data.root.first_name does not match the bank verification number record` (`BVN_IDENTITY_MISMATCH`, also returned for the last name, middle name and date of birth) | A name differs from the record. The check ignores case | Spell the names exactly as on the record |
| 400 `the phone number, date of birth, or name does not match the bank verification number record` (`BVN_NAME_MISMATCH`) | The registry refused the match | Check every identity field |
| 5xx `there was a problem identifying this BVN; please try again later` | The registry lookup failed. Gravv refuses the request rather than skip the check | Retry later |
| 400 `network is only accepted for account options that support wallet integration` | You sent `network` | Remove it |
| 400 `bank_code=<code> does not open accounts for customers resident in GH. …` | The customer is not in Nigeria | Open NGN accounts only for customers in Nigeria |

## Webhooks you will receive

Gravv sends `applications.accounts.pending`, then `applications.accounts.completed`. For each deposit, Gravv sends `transfer.inflow.completed`.

## Testing in sandbox

Sandbox simulates NGN accounts. The account becomes `active` at once with a generated 10-digit number. Sandbox skips the BVN registry check, so any 11 digits work. Simulate a deposit with `"currency": "NGN"`, an amount such as `"50000.00"`, and no `rail`.

## Reference

- [Create an account](/api-reference/accounts-v2/post-v2-accounts)
- [Get an account](/api-reference/accounts-v2/get-v2-accounts-id)
- [Simulate a deposit](/api-reference/accounts-v2/post-v2-accounts-simulate-deposit)
