Collections
A collection is a one-off NGN bank-transfer account created for a specific payment. The customer
pays the exact amount into the account before it expires; the transfer is credited to your wallet
and a collection.successful webhook fires.
Collections are stored as virtual accounts with kind: "collection", distinct from the persistent
reserved accounts.
Endpoints
Section titled “Endpoints”| Method | Path | Scope | Success |
|---|---|---|---|
POST |
/v1/collections |
collections:write |
201 |
GET |
/v1/collections/:id |
read |
200 |
There is no list endpoint for collections. Persist the id and reference you receive.
Create a collection
Section titled “Create a collection”POST /v1/collections
| Field | Type | Required | Notes |
|---|---|---|---|
amount |
number | Yes | Major units, minimum 1 |
currency |
string | Yes | Must be NGN |
reference |
string | Yes | Your reference. Used for de-duplication within the workspace |
customer |
object | Yes | See below |
customer.name |
string | Yes | Used to derive the account name |
customer.email |
string | No | Must be a valid email if present; defaults to an internal address |
customer.phone |
string | No | Stored but not required by the collection rail |
expires_in |
integer | No | Seconds the account stays open. Minimum 60, default 3600 |
metadata |
object | No | Stored with the account |
curl -X POST https://api.nuansis.co/v1/collections \ -H "Authorization: Bearer $NUANSIS_API_KEY" \ -H "Idempotency-Key: order-1042-collection" \ -H "Content-Type: application/json" \ -d '{ "amount": 250000, "currency": "NGN", "reference": "order-1042", "customer": { "name": "Adaeze Okafor", "email": "ada@example.com", "phone": "+2348012345678" }, "expires_in": 3600, "metadata": { "order_id": "1042" } }'{ "data": { "id": 812, "status": "pending", "amount": 250000, "currency": "NGN", "reference": "order-1042", "account": { "bank": "Providus Bank", "bank_code": "101", "account_number": "9901234567", "account_name": "Adaeze Okafor", "expires_at": "2026-10-18T11:26:07.412Z" }, "created_at": "2026-10-18T10:26:07.412Z" }, "meta": { "request_id": "e6d4f2a5-0b7c-4d4e-9f1a-5b6c7d8e9f0a" }}De-duplication by reference
Section titled “De-duplication by reference”Creating a collection with a reference that already exists for the workspace and kind returns the
existing collection instead of opening a second account. This makes a retried create safe even
without the Idempotency-Key header. The check is scoped to kind: "collection", so a reserved
account may use the same reference string.
Status values
Section titled “Status values”| Status | Meaning |
|---|---|
pending |
Waiting for payment, not yet expired |
paid |
A matching bank transfer was received and credited |
expired |
The expiry passed before payment |
Expiry is evaluated lazily. A pending collection is marked expired the next time it is read after
its expires_at, which is also when the collection.expired webhook is emitted. Do not treat the
absence of that event as proof the account is still open — compare expires_at yourself.
Get a collection
Section titled “Get a collection”GET /v1/collections/:id
{ "data": { "id": 812, "status": "paid", "amount": 250000, "currency": "NGN", "reference": "order-1042", "account": { "bank": "Providus Bank", "bank_code": "101", "account_number": "9901234567", "account_name": "Adaeze Okafor", "expires_at": "2026-10-18T11:26:07.412Z" }, "created_at": "2026-10-18T10:26:07.412Z" }, "meta": { "request_id": "f7e5a3b6-1c8d-4e5f-8a2b-6c7d8e9f0a1b" }}The id is the numeric account id returned at creation, not your reference.
An unknown id — or an id belonging to another workspace — returns 404 not_found. There is no
distinction between “does not exist” and “not yours”.
When paid, the collection also produces a normal wallet transaction (channel: "collection_va",
direction: "in") visible from Balances & transactions.
Common errors
Section titled “Common errors”| Status | Code | Cause |
|---|---|---|
400 |
invalid_request |
Missing field, amount < 1, currency other than NGN, expires_in < 60, invalid customer email |
401 |
unauthorized |
Missing or invalid API key |
403 |
insufficient_scope |
Key lacks collections:write |
404 |
not_found |
Unknown collection id on GET |
429 |
rate_limited |
Request budget exhausted |
503 |
provider_error |
The collection rail could not open the account |
Provider failures return 503 with a message such as
Could not open the collection account: <provider detail>.
Webhooks
Section titled “Webhooks”| Event | Fired when | Data |
|---|---|---|
collection.successful |
A bank transfer is matched to the account | id, reference, amount, currency, account_number, novac_reference |
collection.expired |
A pending collection is read after expires_at |
id, reference, amount, account_number |
Register an endpoint in Webhooks to receive them.