REST API

# Accounts API

List the bank accounts belonging to the authenticated entity. Read-only — accounts are provisioned during onboarding and cannot be created via the API.

## Required scopes

All account endpoints require the `accounts:read` scope.

## Account object

The response shape differs per deployment. You are viewing the **ZAR** deployment, so accounts look like this:

```json
{
  "id": "01964a3b-0000-7000-8000-ac6000000a01",
  "name": "Operations",
  "status": "open",
  "currency_code": "ZAR",
  "balance": "15420.50",
  "account_number": "1234567890",
  "bank_identifier": "632005",
  "created_at": "2026-01-15T09:00:00Z",
  "updated_at": "2026-04-01T14:22:00Z"
}
```

## List accounts

`GET` `/api/accounts`

Supports filtering by status and currency_code, plus cursor pagination.

cURL

CLI

JavaScript

Ruby

Python

Go

Rust

Elixir

Crystal

PHP

```console
curl "https://zazu.africa/api/accounts?status=open" \
  -H "Authorization: Bearer sk_live_..."
```

```console
zazu accounts list --status open
```

```javascript
import { Zazu } from "@getzazu/sdk";
const zazu = new Zazu({ apiKey: process.env.ZAZU_API_KEY });

await zazu.accounts.list({ status: "open" });
```

```ruby
require "zazu"
zazu = Zazu.new(api_key: ENV["ZAZU_API_KEY"])

zazu.accounts.list(status: "open")
```

```python
from zazu_sdk import Zazu
client = Zazu(api_key="sk_live_...")

client.accounts.list(status="open")
```

```go
import zazu "github.com/getzazu/zazu-go"

client, _ := zazu.New(zazu.WithAPIKey(os.Getenv("ZAZU_API_KEY")))

page, err := client.Accounts.List(ctx, zazu.AccountListParams{Status: "open"})
```

```rust
let client = zazu_sdk::Client::builder()
    .api_key(std::env::var("ZAZU_API_KEY")?)
    .build()?;

let params = zazu_sdk::AccountListParams { status: Some("open".into()), ..Default::default() };
let page = client.accounts().list(params)?;
```

```elixir
{:ok, client} = Zazu.new(api_key: System.fetch_env!("ZAZU_API_KEY"))

{:ok, page} = Zazu.Accounts.list(client, status: "open")
```

```crystal
require "zazu"

client = Zazu::Client.new # reads ZAZU_API_KEY

page = client.accounts.list(status: "open")
```

```php
use Zazu\Client;

$client = new Client(apiKey: getenv('ZAZU_API_KEY'));

$page = $client->accounts->list(status: 'open');
```

```json
{
  "data": [
    {
      "id": "01964a3b-0000-7000-8000-ac6000000a01",
      "name": "Operations",
      "status": "open",
      "currency_code": "ZAR",
      "balance": "15420.50",
      "account_number": "1234567890",
      "bank_identifier": "632005",
      "created_at": "2026-01-15T09:00:00Z",
      "updated_at": "2026-04-01T14:22:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Get account

`GET` `/api/accounts/:id`

Returns the full account object. Responds `404 not_found_error` if the account does not exist or belongs to another entity.

cURL

CLI

JavaScript

Ruby

Python

Go

Rust

Elixir

Crystal

PHP

```console
curl "https://zazu.africa/api/accounts/01964a3b-0000-7000-8000-ac6000000a01" \
  -H "Authorization: Bearer sk_live_..."
```

```console
zazu accounts get 01964a3b-0000-7000-8000-ac6000000a01
```

```javascript
import { Zazu } from "@getzazu/sdk";
const zazu = new Zazu({ apiKey: process.env.ZAZU_API_KEY });

await zazu.accounts.retrieve("01964a3b-0000-7000-8000-ac6000000a01");
```

```ruby
require "zazu"
zazu = Zazu.new(api_key: ENV["ZAZU_API_KEY"])

zazu.accounts.get("01964a3b-0000-7000-8000-ac6000000a01")
```

```python
from zazu_sdk import Zazu
client = Zazu(api_key="sk_live_...")

client.accounts.retrieve("01964a3b-0000-7000-8000-ac6000000a01")
```

```go
import zazu "github.com/getzazu/zazu-go"

client, _ := zazu.New(zazu.WithAPIKey(os.Getenv("ZAZU_API_KEY")))

account, err := client.Accounts.Get(ctx, "01964a3b-0000-7000-8000-ac6000000a01")
```

```rust
let client = zazu_sdk::Client::builder()
    .api_key(std::env::var("ZAZU_API_KEY")?)
    .build()?;

let account = client.accounts().get("01964a3b-0000-7000-8000-ac6000000a01")?;
```

```elixir
{:ok, client} = Zazu.new(api_key: System.fetch_env!("ZAZU_API_KEY"))

{:ok, account} = Zazu.Accounts.get(client, "01964a3b-0000-7000-8000-ac6000000a01")
```

```crystal
require "zazu"

client = Zazu::Client.new # reads ZAZU_API_KEY

account = client.accounts.get("01964a3b-0000-7000-8000-ac6000000a01")
```

```php
use Zazu\Client;

$client = new Client(apiKey: getenv('ZAZU_API_KEY'));

$account = $client->accounts->get('01964a3b-0000-7000-8000-ac6000000a01');
```

## Transactions

`GET` `/api/accounts/:account_id/transactions`

Read-only records of money movement on an account, newest `posted_at` first, with cursor pagination so backfilled records don't reorder pages. The embedded `account` projection carries the same market identifier as the account object above.

cURL

CLI

JavaScript

Ruby

Python

Go

Rust

Elixir

Crystal

PHP

```console
curl "https://zazu.africa/api/accounts/01964a3b-0000-7000-8000-ac6000000a01/transactions?limit=25" \
  -H "Authorization: Bearer sk_live_..."
```

```console
zazu accounts transactions list --account-id 01964a3b-0000-7000-8000-ac6000000a01
```

```javascript
import { Zazu } from "@getzazu/sdk";
const zazu = new Zazu({ apiKey: process.env.ZAZU_API_KEY });

await zazu.accounts.transactions.list("01964a3b-0000-7000-8000-ac6000000a01");
```

```ruby
require "zazu"
zazu = Zazu.new(api_key: ENV["ZAZU_API_KEY"])

zazu.accounts.transactions.list("01964a3b-0000-7000-8000-ac6000000a01")
```

```python
from zazu_sdk import Zazu
client = Zazu(api_key="sk_live_...")

client.accounts.transactions.list("01964a3b-0000-7000-8000-ac6000000a01")
```

```go
import zazu "github.com/getzazu/zazu-go"

client, _ := zazu.New(zazu.WithAPIKey(os.Getenv("ZAZU_API_KEY")))

page, err := client.Accounts.ListTransactions(ctx,
    "01964a3b-0000-7000-8000-ac6000000a01", zazu.TransactionListParams{})
```

```rust
let client = zazu_sdk::Client::builder()
    .api_key(std::env::var("ZAZU_API_KEY")?)
    .build()?;

let page = client.accounts()
    .list_transactions("01964a3b-0000-7000-8000-ac6000000a01", Default::default())?;
```

```elixir
{:ok, client} = Zazu.new(api_key: System.fetch_env!("ZAZU_API_KEY"))

{:ok, page} = Zazu.Accounts.list_transactions(client, "01964a3b-0000-7000-8000-ac6000000a01")
```

```crystal
require "zazu"

client = Zazu::Client.new # reads ZAZU_API_KEY

page = client.accounts.list_transactions("01964a3b-0000-7000-8000-ac6000000a01")
```

```php
use Zazu\Client;

$client = new Client(apiKey: getenv('ZAZU_API_KEY'));

$page = $client->accounts->listTransactions('01964a3b-0000-7000-8000-ac6000000a01');
```

```json
{
  "data": [
    {
      "id": "01964a3b-7c8d-7000-8000-a10000000001",
      "account_id": "01964a3b-0000-7000-8000-ac6000000a01",
      "operation": "credit",
      "amount": "1500.00",
      "currency_code": "ZAR",
      "account_balance_after": "15420.50",
      "internal_transfer": false,
      "other_name": "Acme Corp",
      "source_type": "transfer",
      "source_id": "01964a3b-0000-7000-8000-transfer001",
      "transaction_type": "Transfer",
      "reference": "INV-000042",
      "transfer_id": "01964a3b-0000-7000-8000-transfer001",
      "posted_at": "2026-04-01T14:22:00Z",
      "value_date": "2026-04-01",
      "created_at": "2026-04-01T14:22:00Z",
      "updated_at": "2026-04-01T14:22:00Z",
      "account": {
        "id": "01964a3b-0000-7000-8000-ac6000000a01",
        "name": "Operations",
        "currency_code": "ZAR",
        "account_number": "1234567890"
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Get transaction

`GET` `/api/accounts/:account_id/transactions/:id`

Returns a single transaction. Responds `404 not_found_error` if the account or transaction does not exist, or the transaction belongs to a different account.

```json
{
  "id": "01964a3b-7c8d-7000-8000-a10000000001",
  "account_id": "01964a3b-0000-7000-8000-ac6000000a01",
  "operation": "credit",
  "amount": "1500.00",
  "currency_code": "ZAR",
  "account_balance_after": "15420.50",
  "internal_transfer": false,
  "other_name": "Acme Corp",
  "source_type": "transfer",
  "source_id": "01964a3b-0000-7000-8000-transfer001",
  "transaction_type": "Transfer",
  "reference": "INV-000042",
  "transfer_id": "01964a3b-0000-7000-8000-transfer001",
  "posted_at": "2026-04-01T14:22:00Z",
  "value_date": "2026-04-01",
  "created_at": "2026-04-01T14:22:00Z",
  "updated_at": "2026-04-01T14:22:00Z",
  "account": {
    "id": "01964a3b-0000-7000-8000-ac6000000a01",
    "name": "Operations",
    "currency_code": "ZAR",
    "account_number": "1234567890"
  }
}
```

## Error responses

| Scenario | Status | Type |
| --- | --- | --- |
| Missing accounts:read scope | 403 | `insufficient_scope` |
| Unknown or cross-entity id | 404 | `not_found_error` |
| Invalid status value | 400 | `invalid_request_error` |
| Invalid cursor | 400 | `invalid_request_error` |