Onboard your first customer
Create your Gravv account, get your API key and create your first customer with one API request.
This guide shows how to create your Gravv account, get your API key and create your first customer with the API. A customer is either a business or an individual.
The guide has three parts:
Create an account on Gravv
You need a Gravv account to use the API. If you don't have an account, follow these steps:
- Visit the registration page.
- Enter your
First name,Last name,Email address, andBusiness name.
You can create an account only with a business email address.
- Check the box to agree to the Terms of use and Privacy policy.
- Click Sign up.

- Check your email for a verification message and open the link to complete your registration.
Obtain your API key
Every request to the Gravv API requires an Api-Key header that carries your Secret Key. There is one Secret Key for each environment, sandbox and live. A sandbox key starts with grvSec_sandbox_. The Dashboard also shows a Public Key, but no API endpoint uses it. Keep the Secret Key on your server.
To get your Secret Key:
- Sign in to your Gravv Dashboard with your registered business email address.
- Click
Managein the side navigation.

- Click
Configureunder theManagesection.

- Click
API keys, then click the copy button underSecret Keyto copy yourSecret Key.

Make your first request
With your Secret Key, you can add a customer. A customer is the person or business that will hold money with you. Creating a customer moves no money, but it sets how much the customer can move. Under the platform's standard limits, a new customer with no KYC can move 500.00 USD a day. Once their basic KYC is completed, they can move 50,000.00 USD a day, and you can open accounts for them.
Before you begin
- Your
Secret Key. See Obtain your API key. A scoped key needscustomer:create. - Check whether the customer already exists:
GET /v1/customers?keyword=<email>.keywordmatches first name, last name, email or id. You can use an email only once in your business. - Every POST needs an
Idempotency-Key, a new one for each request. After any 4xx, send the corrected request with a new key. Gravv replays the old response for 24 hours under the old key.
Create an individual customer
Individual customers are people who will use your platform for personal transactions. Amara, a nurse in Lagos, signs up:
curl --request POST \
--url https://api.gravv.xyz/v1/customers \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: cd7a6f53-ef90-41d9-beb4-170ce79ea8a4' \
--header 'Content-Type: application/json' \
--data '
{
"type": "individual",
"first_name": "Amara",
"last_name": "Nwosu",
"email": "amara.nwosu@example.com",
"phone": "+2348031234567",
"gender": "female",
"date_of_birth": "1992-03-14",
"external_id": "user-88412",
"address": {
"address_line1": "14 Bourdillon Road",
"city": "Lagos",
"state": "NG-LA",
"postal_code": "101233",
"country": "NG"
}
}
'
{
"data": {
"id": "3f6b2a1e-8c4d-4e7f-9a2b-5c1d0e9f8a71",
"type": "individual",
"status": "active",
"first_name": "Amara",
"last_name": "Nwosu",
"email": "amara.nwosu@example.com",
"phone": "+2348031234567",
"gender": "female",
"date_of_birth": "1992-03-14",
"external_id": "user-88412",
"date_added": "2026-10-13T23:30:02.677140979+01:00",
"address": {
"address_line1": "14 Bourdillon Road",
"city": "Lagos",
"state": "NG-LA",
"postal_code": "101233",
"country": "NG"
}
},
"error": null
}
- Save
data.id. The response leaves out empty fields rather than sending them asnull. - The response has no
kyclist. Gravv creates thebasicandintermediateKYC rows at the same time, bothnot_started. Read them withGET /v1/customers/{customer_id}. Find a row bytype, not by position. date_addedcarries a UTC offset, such as+01:00. Parse it as a time. Do not compare it as text.- Gravv also sends a
customer.createdwebhook.
The fields follow these rules:
| Field | Rule |
|---|---|
type |
individual or business, lower case |
first_name, last_name, middle_name |
Letters, spaces, ' and - only, with no accents, digits or dots. Write the name as on the ID, without accents (Adaeze, not Ádaeze). Send middle_name only if it is on the ID |
email |
Unique in your business |
phone |
A real, dialable number in E.164 with its country code, such as +2348031234567. The API refuses made-up ranges such as +1555… |
gender |
male, female or other |
date_of_birth |
YYYY-MM-DD. Gravv does not check age here, but most banks refuse under-18s when you open an account |
address.country |
ISO alpha-2, upper case (NG) |
address.state |
The full ISO 3166-2 code (NG-LA, US-CA). It must belong to country |
external_id |
Optional, your own reference. Unique in your business |
Create a business customer
Business customers are companies that will use your platform for business transactions. A business needs at least one associated person, such as a director or an owner. Adire Logistics Ltd, a Lagos freight forwarder, signs up with its director Tunde Bakare:
curl --request POST \
--url https://api.gravv.xyz/v1/customers \
--header 'Api-Key: <API_KEY>' \
--header 'Idempotency-Key: 57f2268e-c753-45e6-98e5-93aa2c86b0b1' \
--header 'Content-Type: application/json' \
--data '
{
"type": "business",
"email": "finance@adirelogistics.example",
"phone": "+2348091234567",
"business_name": "Adire Logistics Ltd",
"business_description": "Freight forwarding and customs clearing for importers",
"business_type": "private_limited",
"business_industry": "Transportation and Warehousing",
"registration_number": "RC-1234567",
"external_id": "biz-2040",
"address": {
"address_line1": "22 Creek Road",
"city": "Apapa",
"state": "NG-LA",
"postal_code": "102272",
"country": "NG"
},
"associated_persons": [
{
"first_name": "Tunde",
"last_name": "Bakare",
"email": "tunde.bakare@adirelogistics.example",
"phone": "+2348021234567",
"gender": "male",
"date_of_birth": "1984-07-22",
"address": {
"address_line1": "7 Glover Road",
"city": "Ikoyi",
"state": "NG-LA",
"postal_code": "106104",
"country": "NG"
}
}
]
}
'
{
"data": {
"id": "0a9b8c7d-6e5f-4a3b-8c2d-1e0f9a8b7c6d",
"type": "business",
"status": "active",
"business_name": "Adire Logistics Ltd",
"business_type": "private_limited",
"business_industry": "Transportation and Warehousing",
"industry_code": "488999",
"registration_number": "RC-1234567",
"associated_persons": [
{
"id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
"first_name": "Tunde",
"last_name": "Bakare",
"type": "ubo",
"status": "active"
}
]
},
"error": null
}
- Save the business
idand everyassociated_persons[].id. Each person is a customer of typeubo(ultimate beneficial owner). Verify each person with their own id before you verify the business. See KYC. - Gravv sends one
customer.createdfor the business and one for each person. - All fields above are required, except
external_id,address_line2and a person'sphone. Each person needs a full address. - The business
emailmust be on the company's own domain. The API refuses free-mail domains such as gmail.com, yahoo.com, outlook.com, hotmail.com, icloud.com, aol.com and protonmail.com. - Every person needs their own email, different from the business email, from each other, and from every other customer in your business.
business_nameallows letters, digits, spaces and'&,.()-.- To add a person later, send
associated_personswith noidonPUT /v1/customers/{customer_id}.phoneis then required.
Business industries
business_industry is free text. Gravv maps it to an industry_code, which the API returns on the customer. Only these exact values, with the same capitals and punctuation, map to a specific code. The API accepts any other value and gives it 999999:
business_industry |
industry_code |
|---|---|
| Agriculture, Forestry, Fishing and Hunting | 111998 |
| Mining, Quarrying, and Oil and Gas Extraction | 212390 |
| Utilities | 221118 |
| Construction | 238990 |
| Manufacturing | 339999 |
| Wholesale Trade | 424990 |
| Retail Trade | 459999 |
| Transportation and Warehousing | 488999 |
| Information | 513199 |
| any other value | 999999 |
What can go wrong
Customer errors return {"data": null, "error": "<text>"}, with error as a string.
| Response | Why | Fix |
|---|---|---|
400 failed to add customer: email already exists |
The email belongs to another customer in your business | Find it with GET /v1/customers?keyword=<email> and reuse it |
400 failed to add customer: external_id already exists |
Another customer already has that external_id |
Send another one, or leave it out |
400 phone number is not valid |
Not a real, dialable number | Send E.164 with the country code |
400 invalid state "LA": expected ISO 3166-2 code (e.g. "NG-LA") |
A bare state code | Send NG-LA |
400 state "US-CA" does not belong to country "NG" |
State from another country | Match state to country |
400 invalid country "ng": expected ISO 3166-1 alpha-2 code (e.g. "NG") |
Lower case or three letters | Send NG |
400 first name cannot contain special characters |
An accent, digit or dot | Remove it |
400 date of birth is required |
No date_of_birth on a person |
Send YYYY-MM-DD |
400 only company emails are allowed |
A free-mail domain on a business | Use the company domain |
400 at least one associated person is required for a business customer |
No associated_persons |
Add the directors and owners |
400 failed to add customer: associated person emails must be unique |
Two people share an email, or a person uses the business email | Give each person their own email |
400 failed to add customer: associated person email already exists |
The person's email belongs to another customer | Use another email |
400 associated person address fields (line1, city, postal_code, state, country) are required |
A person without a full address | Add it |
400 failed to validate request… with a field name, such as 'Email' |
A required field is missing | Add the named field |
Gravv does not refuse an unassigned country code such as ZZ or a malformed US postal code. Check them on your side, because later calls can refuse such a customer.
What next?
Verify the customer with KYC, then open an account. Continue with Your first Gravv integration to learn how to:
- Onboard multiple customers
- Verify customers with KYC
- Fund accounts
- Transfer funds between accounts