Volboo Docs
Home Pricing Dashboard

Virtual accounts

Create account

Issues a virtual account and returns the details your customer pays into. Choose a static account that stays with the customer, a dynamic account that expires after one hour, or a checkout account that gives you a hosted payment link instead of raw account details.

POST /v2/create_account

Account types

TypeBehaviour
static A permanent account. Each customer (email) gets one per bank. Calling again for the same customer and bank returns the existing account. Requires bvn.
dynamic A short-lived account for a single payment, valid for 1 hour. Requires amount and amounttype. While a customer still has a live dynamic account with a bank, calling again returns that account instead of creating a new one. Returns the account details directly.
checkout A short-lived account for a single payment, provisioned the same way as dynamic (same 1-hour expiry, same amount / amounttype requirements). Instead of account details, the response gives you a hosted checkout_url — send your customer there and Volboo shows them the bank details, counts down to expiry, and lets them share the link with whoever is making the payment.

Headers

HeaderValue
Content-Typeapplication/json
api-keyYour business API key
secret-keyYour business secret key

Request body

FieldTypeRequiredNotes
typestringYesstatic, dynamic or checkout.
emailstringYesThe customer this account belongs to. Must be a valid email address.
refstringYesYour own reference, 3 to 100 characters: letters, numbers, hyphens, underscores and dots. Each ref can only be used once per business. Returned as client_reference everywhere the account appears.
fnamestringYesFirst name, 2 to 60 characters. Letters, spaces, hyphens and apostrophes only.
lnamestringYesLast name, same rules as fname.
phonenumberYesCustomer phone number, 10 to 15 digits.
banksarrayYesWhich partner banks to issue with. Currently ["9PSB"].
bvnnumberStatic onlyCustomer's 11-digit BVN. Required when type is static; ignored for dynamic and checkout accounts.
amountnumberDynamic & checkoutAmount in NGN. Must be greater than 0.
amounttypestringDynamic & checkoutEXACT accepts only the exact amount. ANY accepts any amount paid into the account.

Request

Static account
curl -X POST /v2/create_account \
  -H "Content-Type: application/json" \
  -H "api-key: <your api key>" \
  -H "secret-key: <your secret key>" \
-d '{
    "type": "static",
    "email": "customer@example.com",
    "ref": "order_10432",
    "fname": "Amanda",
    "lname": "Elumelu",
    "phone": 8060082079,
    "bvn": 22222222222,
    "banks": ["9PSB"]
  }'
{
  "type":    "static",
  "email":   "customer@example.com",
  "ref":     "order_10432",
  "fname":   "Amanda",
  "lname":   "Elumelu",
  "phone":   8060082079,
  "bvn":     22222222222,
  "banks":   ["9PSB"]
}
Dynamic account
curl -X POST /v2/create_account \
  -H "Content-Type: application/json" \
  -H "api-key: <your api key>" \
  -H "secret-key: <your secret key>" \
-d '{
    "type": "dynamic",
    "email": "customer@example.com",
    "ref": "order_10433",
    "fname": "Amanda",
    "lname": "Elumelu",
    "phone": 8060082079,
    "amount": 5000,
    "amounttype": "EXACT",
    "banks": ["9PSB"]
  }'
{
  "type":       "dynamic",
  "email":      "customer@example.com",
  "ref":        "order_10433",
  "fname":      "Amanda",
  "lname":      "Elumelu",
  "phone":      8060082079,
  "amount":     5000,
  "amounttype": "EXACT",
  "banks":      ["9PSB"]
}
Checkout account
curl -X POST /v2/create_account \
  -H "Content-Type: application/json" \
  -H "api-key: <your api key>" \
  -H "secret-key: <your secret key>" \
-d '{
    "type": "checkout",
    "email": "customer@example.com",
    "ref": "order_10434",
    "fname": "Amanda",
    "lname": "Elumelu",
    "phone": 8060082079,
    "amount": 5000,
    "amounttype": "EXACT",
    "banks": ["9PSB"]
  }'
{
  "type":       "checkout",
  "email":      "customer@example.com",
  "ref":        "order_10434",
  "fname":      "Amanda",
  "lname":      "Elumelu",
  "phone":      8060082079,
  "amount":     5000,
  "amounttype": "EXACT",
  "banks":      ["9PSB"]
}

Response

FieldTypeNotes
statusstringsuccess when at least one account was issued or already existed. error when every requested bank failed.
resultsarrayOne entry per requested bank.
results[].vol_referencestringVolboo's identifier for the account. Not present when status is failed.
results[].account_namestringName the account is held in. Not present for checkout accounts — use the hosted page instead.
results[].account_numberstringThe number your customer pays into. Not present for checkout accounts — use the hosted page instead.
results[].checkout_urlstringcheckout accounts only. Link to the hosted payment page — send your customer here to see the bank details and pay.
results[].bank_namestringPartner bank holding the account.
results[].account_typestringstatic, dynamic or checkout.
results[].expires_atstringDynamic and checkout accounts only. When the account stops accepting payments, formatted YYYY-MM-DD HH:MM:SS.
results[].statusstringcreated, existing or failed.
results[].messagestringOnly when status is failed. Says why that bank could not issue an account.
request_refstringYour ref, echoed back.
200 Success (static)
{
  "status": "success",
  "results": [
    {
      "vol_reference":  "VOL-695E0C5DA6A9A-9PS",
      "account_name":   "VOLBOO/AMANDA ELUMELU",
      "account_number": "9060132960",
      "bank_name":      "9PSB",
      "account_type":   "static",
      "status":         "created" //created or existing
    }
  ],
  "request_ref": "order_10432"
}
200 Success (dynamic)
{
  "status": "success",
  "results": [
    {
      "vol_reference":  "VOL-DY-695E0C5DA6A9A-9PS",
      "account_name":   "VOLBOO/AMANDA ELUMELU",
      "account_number": "9060132961",
      "bank_name":      "9PSB",
      "account_type":   "dynamic",
      "expires_at":     "2026-09-28 15:02:00",
      "status":         "created" //created or existing
    }
  ],
  "request_ref": "order_10433"
}
200 Success (checkout)
{
  "status": "success",
  "results": [
    {
      "vol_reference": "VOL-CK-695E0C5DA6A9A-9PS",
      "bank_name":     "9PSB",
      "account_type":  "checkout",
      "status":        "created", //created or existing
      "expires_at":    "2026-09-28 15:02:00",
      "checkout_url":  "https://volboo.com/checkout/checkout?acct_vol_reference=VOL-CK-695E0C5DA6A9A-9PS"
    }
  ],
  "request_ref": "order_10434"
}
200 Bank failure
{
  "status": "error",
  "results": [
    {
      "bank_name":    "9PSB",
      "account_type": "static",
      "status":       "failed",
      "message":      "9PSB API Failure"
    }
  ],
  "request_ref": "order_10432"
}
Store vol_reference against your own customer record. It is what ties a later payment or webhook event back to the account you issued. For dynamic and checkout accounts, also keep expires_at so you know when to stop showing the account — or the checkout link — to your customer.
Checkout accounts are provisioned at the bank exactly like dynamic accounts — same expiry, same amount rules — the only difference is what you get back. Use checkout when you want to hand your customer a single link rather than displaying bank details yourself; use dynamic when you want the account details to build your own payment UI.

Errors

A rejected call answers with status: "error" and the reason in message. The HTTP code is still 200, so check status in the body. See Errors for the shape.

MessageCause
type must be 'static', 'dynamic' or 'checkout'type is missing or not one of the three values.
<field> is requiredA required field for that account type is missing, including bvn for static and amount / amounttype for dynamic and checkout.
BVN must be exactly 11 digitsbvn is not 11 digits.
amounttype must be either 'ANY' or 'EXACT'Invalid amounttype on a dynamic or checkout request.
amount must be greater than zeroamount is zero or negative.
'<bank>' is not a supported bankAn entry in banks is not supported. The message lists the supported banks.
Invalid API keysapi-key or secret-key is wrong.
The reference '<ref>' has already been used for this business.You have already used this ref. Send a new one for each request.