curl --request GET \
--url https://sandbox-api.sakawave.example/v1/customers/{customerId} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sandbox-api.sakawave.example/v1/customers/{customerId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://sandbox-api.sakawave.example/v1/customers/{customerId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"id": "01K2Z3AB4C5D6E7F8G9HJKMNPQ",
"type": "individual",
"jurisdiction": "NG",
"externalReference": "cust_1001",
"displayName": "Ada Okafor",
"name": null,
"firstName": "Ada",
"middleName": null,
"lastName": "Okafor",
"email": "ada@example.com",
"phoneNumber": "+2348012345678",
"dateOfBirth": "1992-04-18",
"gender": "female",
"address": {
"line1": "14 Marina Road",
"line2": null,
"city": "Lagos",
"state": "Lagos",
"postalCode": "100001",
"country": "NG"
},
"tier": 1,
"hasBvn": true,
"hasNin": false,
"hasPassport": false,
"hasDriversLicence": false,
"hasTaxId": false,
"hasRegistrationNumber": false,
"createdAt": "2026-08-14T09:00:00.000Z",
"updatedAt": "2026-08-14T09:00:00.000Z"
}{
"statusCode": 400,
"message": "Must be a valid identifier.",
"code": "validation_failed",
"errors": [
{
"message": "Must be a valid identifier.",
"field": "accountId",
"code": "custom",
"path": [
"accountId"
]
}
]
}{
"statusCode": 401,
"code": "INVALID_API_KEY",
"message": "Invalid or inactive API credentials."
}{
"statusCode": 404,
"code": "resource_not_found",
"message": "Resource not found."
}{
"statusCode": 409,
"code": "resource_conflict",
"message": "The request conflicts with the current resource state."
}{
"statusCode": 429,
"message": "Too many API requests. Try again later.",
"code": "api_key_rate_limit_exceeded",
"retryAfterSeconds": 17
}{
"statusCode": 500,
"code": "internal_server_error",
"message": "An unexpected error occurred."
}Get a customer
Returns one customer belonging to the authenticated business. An archived customer answers 404.
curl --request GET \
--url https://sandbox-api.sakawave.example/v1/customers/{customerId} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sandbox-api.sakawave.example/v1/customers/{customerId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://sandbox-api.sakawave.example/v1/customers/{customerId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"id": "01K2Z3AB4C5D6E7F8G9HJKMNPQ",
"type": "individual",
"jurisdiction": "NG",
"externalReference": "cust_1001",
"displayName": "Ada Okafor",
"name": null,
"firstName": "Ada",
"middleName": null,
"lastName": "Okafor",
"email": "ada@example.com",
"phoneNumber": "+2348012345678",
"dateOfBirth": "1992-04-18",
"gender": "female",
"address": {
"line1": "14 Marina Road",
"line2": null,
"city": "Lagos",
"state": "Lagos",
"postalCode": "100001",
"country": "NG"
},
"tier": 1,
"hasBvn": true,
"hasNin": false,
"hasPassport": false,
"hasDriversLicence": false,
"hasTaxId": false,
"hasRegistrationNumber": false,
"createdAt": "2026-08-14T09:00:00.000Z",
"updatedAt": "2026-08-14T09:00:00.000Z"
}{
"statusCode": 400,
"message": "Must be a valid identifier.",
"code": "validation_failed",
"errors": [
{
"message": "Must be a valid identifier.",
"field": "accountId",
"code": "custom",
"path": [
"accountId"
]
}
]
}{
"statusCode": 401,
"code": "INVALID_API_KEY",
"message": "Invalid or inactive API credentials."
}{
"statusCode": 404,
"code": "resource_not_found",
"message": "Resource not found."
}{
"statusCode": 409,
"code": "resource_conflict",
"message": "The request conflicts with the current resource state."
}{
"statusCode": 429,
"message": "Too many API requests. Try again later.",
"code": "api_key_rate_limit_exceeded",
"retryAfterSeconds": 17
}{
"statusCode": 500,
"code": "internal_server_error",
"message": "An unexpected error occurred."
}Error codes
| Status | code | Cause |
|---|---|---|
400 | validation_failed | The identifier is not a ULID. |
404 | customer_not_found | No such customer for this business, or it has been archived. |
401 | INVALID_API_KEY | The key is missing, invalid, inactive, expired, from the other environment, or blocked by its IP allowlist. |
404 | client_not_found | The key authenticated, but its business no longer exists. |
409 | client_not_a_business | Customer management is available only to business clients. |
429 | api_key_rate_limit_exceeded | The per-minute limit for this key was exceeded. |
Authorizations
A secret API key, sent as Authorization: Bearer sk_test_… in sandbox or Bearer sk_live_… in live.
Path Parameters
Customer ULID. A 26-character ULID.
26^[0-7][0-9A-HJKMNP-TV-Z]{25}$"01K2Z3AB4C5D6E7F8G9HJKMNPQ"
Response
Successful response.
A 26-character ULID.
26^[0-7][0-9A-HJKMNP-TV-Z]{25}$"01K2Z3AB4C5D6E7F8G9HJKMNPQ"
Fixed at creation. It decides which of the fields below apply.
individual, business Uppercase ISO 3166-1 alpha-2 country of the relationship. Fixed at creation.
2Your own reference. Unique among your customers that are not archived.
The business name, or the personal names joined, or "Unnamed customer" when neither is on file. Always safe to render.
male, female, other Show child attributes
Show child attributes
Verification tier. Every customer is created at tier 1. It becomes 3 when the customer passes verification, announced by customer.kyc.approved. No endpoint sets it directly, and a later suspension does not lower it.
1, 2, 3 Whether a BVN is on file. The number itself is never returned.
Whether a NIN is on file.
Whether a passport number is on file.
Whether a driving licence number is on file.
Whether a tax identifier is on file.
Whether a company registration number is on file. Business customers only.
"2026-08-14T09:00:00.000Z"
"2026-08-14T09:00:00.000Z"