> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usezentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List Virtual Accounts

> GET /api/v1/virtual-accounts - List virtual accounts for the authenticated tenant

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

## Endpoint

```
GET /api/v1/virtual-accounts
```

## Query Parameters

<ParamField query="customer_id" type="string">
  Filter by customer ID.
</ParamField>

<ParamField query="status" type="string">
  Filter by account status.
</ParamField>

<ParamField query="account_type" type="string">
  Filter by account type.
</ParamField>

<ParamField query="bank_code" type="string">
  Filter by provider bank code or slug.
</ParamField>

<ParamField query="page" type="number" default="1">
  Page number. The gateway converts this into `offset` internally.
</ParamField>

<ParamField query="limit" type="number" default="20">
  Results per page. Maximum `100`.
</ParamField>

<ParamField query="offset" type="number">
  Explicit record offset. If both `page` and `offset` are supplied, `offset` wins.
</ParamField>

<ParamField query="sort" type="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.
</ParamField>

## Response

List responses return a `data` object containing `items` and `pagination`.

## Example Request

<CodeGroup>
  ```javascript JavaScript theme={null}
  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}`);
  });
  ```

  ```python Python theme={null}
  accounts = client.virtual_accounts.list(
      customer_id='cus_123',
      status='active',
      page=2,
      limit=25,
      sort='-created_at'
  )

  print(f"Total: {accounts.data.pagination.total}")
  for account in accounts.data.items:
      print(f"{account.account_number} - {account.bank_name}")
  ```

  ```php PHP theme={null}
  $accounts = $client->virtualAccounts->list([
      'customer_id' => 'cus_123',
      'status' => 'active',
      'page' => 2,
      'limit' => 25,
      'sort' => '-created_at'
  ]);

  echo "Total: {$accounts->data->pagination->total}\n";
  foreach ($accounts->data->items as $account) {
      echo "{$account->account_number} - {$account->bank_name}\n";
  }
  ```

  ```bash cURL theme={null}
  curl "https://api.usezentra.com/api/v1/virtual-accounts?customer_id=cus_123&status=active&page=2&limit=25&sort=-created_at" \
    -H "Authorization: Bearer YOUR_SECRET_KEY"
  ```
</CodeGroup>

## Example Response

```json theme={null}
{
  "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

```bash theme={null}
# 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

<CodeGroup>
  ```javascript JavaScript theme={null}
  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'
  });
  ```

  ```python Python theme={null}
  active = client.virtual_accounts.list(status='active')
  customer_accounts = client.virtual_accounts.list(customer_id='cus_123')
  wema_accounts = client.virtual_accounts.list(bank_code='wema-bank')
  filtered = client.virtual_accounts.list(
      customer_id='cus_123',
      status='active',
      bank_code='wema-bank',
      account_type='standard'
  )
  ```

  ```php PHP theme={null}
  $active = $client->virtualAccounts->list(['status' => 'active']);
  $customerAccounts = $client->virtualAccounts->list(['customer_id' => 'cus_123']);
  $wemaAccounts = $client->virtualAccounts->list(['bank_code' => 'wema-bank']);
  $filtered = $client->virtualAccounts->list([
      'customer_id' => 'cus_123',
      'status' => 'active',
      'bank_code' => 'wema-bank',
      'account_type' => 'standard'
  ]);
  ```
</CodeGroup>

## Notes

<Info>
  Legacy wrapper payloads like `filters` or `params` are rejected on this reviewed endpoint. Send query parameters directly.
</Info>

## Next Steps

<CardGroup cols={2}>
  <Card title="Get Account" icon="eye" href="/api-reference/virtual-accounts/get">
    Retrieve a single account
  </Card>

  <Card title="Create Account" icon="plus" href="/api-reference/virtual-accounts/create">
    Generate a new virtual account
  </Card>

  <Card title="Close Account" icon="xmark" href="/api-reference/virtual-accounts/close">
    Close an account
  </Card>
</CardGroup>
