Customers represent the end-users of your application. Each customer belongs to your API client and receives a unique customerId code (prefixed HYP_). You can assign a dedicated virtual account to a customer so that any inbound bank transfer is automatically associated with them and posted to your webhook.
Create a customer
POST /api/v1/customers
Customer’s email address.
Date of birth in YYYY-MM-DD format.
Customer’s physical address.
curl --request POST \
--url https://api.hyparrow.com/api/v1/customers \
--header "x-api-key: your_api_key" \
--header "x-api-secret: your_api_secret" \
--header "Content-Type: application/json" \
--data '{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"phoneNumber": "+2348012345678",
"dateOfBirth": "1990-04-15",
"address": "12 Marina Street, Lagos"
}'
{
"success" : true ,
"message" : "Customer created successfully" ,
"data" : {
"id" : "uuid-..." ,
"customerId" : "HYP_aBcDeFgH1234" ,
"firstName" : "Jane" ,
"lastName" : "Doe" ,
"email" : "jane@example.com" ,
"phoneNumber" : "+2348012345678" ,
"status" : "active" ,
"createdAt" : "2025-06-01T10:00:00Z"
}
}
Customer statuses: active, suspended, inactive.
Create a virtual account
Assign a permanent virtual bank account to a customer. Any transfer made to this account number is linked to the customer and triggers the customer.transaction.completed webhook event.
POST /api/v1/customers/virtual-account
UUID of the customer (the id field, not customerId code).
Bank code of the preferred issuing bank (e.g. "035" for Wema Bank).
curl --request POST \
--url https://api.hyparrow.com/api/v1/customers/virtual-account \
--header "x-api-key: your_api_key" \
--header "x-api-secret: your_api_secret" \
--header "Content-Type: application/json" \
--data '{
"customerId": "uuid-...",
"bankCode": "035"
}'
{
"success" : true ,
"message" : "Virtual account created successfully" ,
"data" : {
"id" : "uuid-..." ,
"customerId" : "HYP_aBcDeFgH1234" ,
"accountNumber" : "0123456789" ,
"accountName" : "Hyparrow / Jane Doe" ,
"bankCode" : "035" ,
"bankName" : "Wema Bank"
}
}
Each customer can hold one virtual account. Calling this endpoint a second time for the same customer returns a 400 error.
List customers
GET /api/v1/customers
Query parameter Type Default Description pagenumber 1Page number limitnumber 20Results per page statusstring — Filter by customer status (active, suspended, inactive)
curl --request GET \
--url "https://api.hyparrow.com/api/v1/customers?page=1&limit=20&status=active" \
--header "x-api-key: your_api_key" \
--header "x-api-secret: your_api_secret"
{
"success" : true ,
"data" : [ ... ],
"pagination" : {
"page" : 1 ,
"limit" : 20 ,
"total" : 42 ,
"totalPages" : 3
}
}
Get a customer
GET /api/v1/customers/:id
curl --request GET \
--url https://api.hyparrow.com/api/v1/customers/uuid-... \
--header "x-api-key: your_api_key" \
--header "x-api-secret: your_api_secret"
Returns the full customer object including virtual account details when one has been assigned.
Receiving payments via webhook
When a transfer is made to a customer’s virtual account, Hyparrow posts a customer.transaction.completed event to your configured webhook URL.
Webhook payload
{
"event" : "customer.transaction.completed" ,
"data" : {
"customerId" : "HYP_aBcDeFgH1234" ,
"customerUuid" : "uuid-..." ,
"amount" : 10000.00 ,
"currency" : "NGN" ,
"accountNumber" : "0123456789" ,
"bankCode" : "035" ,
"bankName" : "Wema Bank" ,
"reference" : "TXN-REF-001" ,
"narration" : "Transfer from John Smith" ,
"createdAt" : "2025-06-01T10:05:00Z"
}
}
Always validate the webhook signature header before processing the payload. Reject any request that fails signature verification.
Webhook response fields
Always customer.transaction.completed for customer VA payments.
The HYP_ prefixed customer code.
Internal UUID of the customer record.
Amount received in the transaction.
The virtual account number that received the transfer.
Unique transaction reference.
Narration/description supplied by the sender.
ISO 8601 timestamp of the transaction.