Customer Enrollment & KYC
Submit KYC
Submit one identity verification document. Call this once per type the target account requires — see the KYC types and requirements below.
POST /v1/customer/:uuid/kyc
Use this endpoint to
- Submit a BVN or NIN for NGN account verification
- Submit a government ID or proof of address for USD/EUR/GBP account verification
- Build up a customer's KYC profile one document at a time
KYC types
type |
What it is | Verified by |
|---|---|---|
bvn |
Nigerian Bank Verification Number | Number lookup |
nin |
Nigerian National Identity Number | Number lookup |
passport |
International passport | Document review |
drivers_license |
Driver's license | Document review |
national_id |
National ID card | Document review |
proof_of_address |
Utility bill / bank statement | Document review |
Number-based types (bvn, nin) are validated against the identity provider immediately. Document types (passport, drivers_license, national_id, proof_of_address) are accepted on submission and reviewed before they turn approved. For USD/EUR/GBP accounts, the partner bank performs the authoritative review at account-issuance time and can still decline a document.
Request
Headers
| Header | Value |
|---|---|
Authorization |
Bearer <access_token> |
Content-Type |
application/json |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
uuid |
string | Yes | Customer id from Enroll Customer |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | One of the KYC types above |
value |
string | Conditional | The ID / document number. Required for all types except proof_of_address |
country |
string | Conditional | ISO country code. Required for document types; defaults to NG for bvn/nin |
document_front |
string (URL) | Conditional | Image URL of the document front. Required for all document types |
document_back |
string (URL) | Conditional | Image URL of the document back. Required for drivers_license and national_id |
Required fields per type
type |
value |
document_front |
document_back |
country |
|---|---|---|---|---|
bvn |
✅ | — | — | defaults NG |
nin |
✅ | — | — | defaults NG |
passport |
✅ | ✅ | — | ✅ |
drivers_license |
✅ | ✅ | ✅ | ✅ |
national_id |
✅ | ✅ | ✅ | ✅ |
proof_of_address |
— | ✅ (utility bill / bank statement) | — | ✅ |
Note: document_front / document_back must be publicly reachable image URLs — uploaded via your own storage or our upload endpoint.
Business rules:
- Submitting a
typethat's alreadyapproved→CONFLICT(409) - Submitting a
typethat already has apendingsubmission →DUPLICATE_REQUEST - A
bvnalready registered to a different customer in your business →DUPLICATE_IDENTITY(one person = one profile) - A successful submission sets the customer's overall
kyc_statustopending
Code Samples
// BVN (number type)
const bvnResponse = await fetch(
"https://sandbox.hitchpay.ng/v1/customer/CUSTOMER_UUID/kyc",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
type: "bvn",
value: "22345678901"
})
}
);
console.log(await bvnResponse.json());
// Passport (no back required)
const passportResponse = await fetch(
"https://sandbox.hitchpay.ng/v1/customer/CUSTOMER_UUID/kyc",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
type: "passport",
value: "A01234567",
country: "GB",
document_front: "https://cdn.example.com/passport-front.jpg"
})
}
);
console.log(await passportResponse.json());<?php
// BVN (number type)
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://sandbox.hitchpay.ng/v1/customer/CUSTOMER_UUID/kyc",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
"type" => "bvn",
"value" => "22345678901"
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_ACCESS_TOKEN",
"Content-Type: application/json"
]
]);
echo curl_exec($ch);
curl_close($ch);
// Driver's license (front + back)
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://sandbox.hitchpay.ng/v1/customer/CUSTOMER_UUID/kyc",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
"type" => "drivers_license",
"value" => "DL-99881122",
"country" => "US",
"document_front" => "https://cdn.example.com/dl-front.jpg",
"document_back" => "https://cdn.example.com/dl-back.jpg"
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_ACCESS_TOKEN",
"Content-Type: application/json"
]
]);
echo curl_exec($ch);
curl_close($ch);import requests
url = "https://sandbox.hitchpay.ng/v1/customer/CUSTOMER_UUID/kyc"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
# Proof of address (no value)
payload = {
"type": "proof_of_address",
"country": "GB",
"document_front": "https://cdn.example.com/utility-bill.jpg"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())Response
{
"status": "success",
"message": "KYC information submitted successfully. Verification is in progress.",
"data": {
"uuid": "…",
"customerid": "your-customer-ref-001",
"kyc_status": "pending"
}
}Fields
| Field | Type | Description |
|---|---|---|
uuid |
string | Customer id |
customerid |
string | Your reference |
kyc_status |
string | Overall status after this submission — pending until reviewed |
Errors
| Code | HTTP | Meaning |
|---|---|---|
INVALID_REQUEST |
400 | Missing/invalid field, unsupported type, or a per-type requirement not met |
NOT_FOUND |
404 | Customer not found for your business |
CONFLICT |
409 | This type is already approved |
DUPLICATE_REQUEST |
400 | A pending submission for this type already exists |
DUPLICATE_IDENTITY |
400 | This BVN is already registered to another customer profile |
PROVIDER_ERROR |
400 | Verification provider (e.g. Veriff) could not be reached |
REQUEST_FAILED |
400 | The request could not be completed |
Note: Submit one document per call. To submit multiple documents, call this endpoint once per type.
Questions? Email [email protected]. Also on GitBook.