Skip to main content
GET
/
api
/
v1
/
virtual-accounts
List Virtual Accounts
curl --request GET \
  --url https://api.usezentra.com/api/v1/virtual-accounts \
  --header 'Authorization: Bearer <token>'

List Virtual Accounts

Retrieve a paginated list of virtual accounts for the authenticated tenant.

Endpoint

GET /api/v1/virtual-accounts

Query Parameters

customer_id
string
Filter by customer ID.
status
string
Filter by account status.
account_type
string
Filter by account type.
bank_code
string
Filter by provider bank code or slug.
page
number
default:"1"
Page number. The gateway converts this into offset internally.
limit
number
default:"20"
Results per page. Maximum 100.
offset
number
Explicit record offset. If both page and offset are supplied, offset wins.
sort
string
Sort field. Supported values: created_at, -created_at, account_number, -account_number, total_received_minor, -total_received_minor. The legacy aliases total_credits and -total_credits are also accepted.

Response

List responses return a data object containing items and pagination.

Example Request

const accounts = await client.virtualAccounts.list({
  customerId: 'cus_123',
  status: 'active',
  page: 2,
  limit: 25,
  sort: '-created_at'
});

console.log(`Total: ${accounts.data.pagination.total}`);
accounts.data.items.forEach(account => {
  console.log(`${account.accountNumber} - ${account.bankName}`);
});

Example Response

{
  "data": {
    "items": [
      {
        "id": "va_abc123xyz",
        "tenant_id": "tenant_123",
        "customer_id": "cus_1234567890",
        "account_number": "0123456789",
        "account_name": "John Doe",
        "bank_code": "wema-bank",
        "bank_name": "Wema Bank",
        "provider": "paystack_dva",
        "status": "active",
        "account_type": "standard",
        "total_received_minor": 500000,
        "transaction_count": 5,
        "metadata": {
          "purpose": "collections"
        },
        "expires_at": null,
        "created_at": "2026-03-07T10:30:00Z",
        "updated_at": "2026-03-07T15:45:00Z"
      }
    ],
    "pagination": {
      "page": 2,
      "limit": 25,
      "offset": 25,
      "total": 26,
      "pages": 2,
      "has_more": true
    }
  },
  "meta": {
    "timestamp": "2026-03-07T15:45:00Z",
    "requestId": "req_123"
  }
}

Sorting

# Newest first (default)
GET /api/v1/virtual-accounts?sort=-created_at

# Oldest first
GET /api/v1/virtual-accounts?sort=created_at

# Highest inbound value first
GET /api/v1/virtual-accounts?sort=-total_received_minor

# Legacy alias, still accepted
GET /api/v1/virtual-accounts?sort=-total_credits

# By account number
GET /api/v1/virtual-accounts?sort=account_number

Filtering Examples

const active = await client.virtualAccounts.list({ status: 'active' });
const customerAccounts = await client.virtualAccounts.list({ customerId: 'cus_123' });
const wemaAccounts = await client.virtualAccounts.list({ bankCode: 'wema-bank' });
const filtered = await client.virtualAccounts.list({
  customerId: 'cus_123',
  status: 'active',
  bankCode: 'wema-bank',
  accountType: 'standard'
});

Notes

Legacy wrapper payloads like filters or params are rejected on this BaaS endpoint. Send query parameters directly.

Next Steps

Get Account

Retrieve a single account

Create Account

Generate a new virtual account

Close Account

Close an account