Accounts
Accounts hold customer balances. Each account has a type, currency, and set of limits. Accounts can be frozen, closed, or extended with virtual sub-accounts.
Account Types
| Type | Description |
|---|---|
SAVINGS | Interest-bearing savings account |
CURRENT | Demand deposit / checking account |
FIXED_DEPOSIT | Time deposit with fixed tenor and maturity date |
DOMICILIARY | Foreign currency account (USD, GBP, EUR) |
JOINT | Jointly owned account |
CORPORATE | Business/corporate account |
Account Statuses
| Status | Description |
|---|---|
PENDING | Created, awaiting activation |
ACTIVE | Open and operational |
DORMANT | No activity for extended period |
FROZEN | Debits blocked (credits still allowed) |
CLOSED | Permanently closed |
BLOCKED | All operations blocked |
Create an Account
POST /api/v1/accounts
- cURL
- Node.js
- Python
curl -X POST https://api.korastratum.com/api/v1/cba/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-ID: demo_bank" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acct-$(uuidgen)" \
-d '{
"customer_id": "cust-uuid",
"account_type": "SAVINGS",
"currency": "NGN",
"product_code": "SAV001",
"branch_code": "001",
"alias": "Emergency Fund",
"initial_deposit": 100000.00,
"created_by": "user-uuid"
}'
const account = await cbaRequest("POST", "/api/v1/accounts", token, {
customer_id: "cust-uuid",
account_type: "SAVINGS",
currency: "NGN",
product_code: "SAV001",
branch_code: "001",
alias: "Emergency Fund",
initial_deposit: 100000.0,
created_by: "user-uuid",
});
account = cba_request("POST", "/api/v1/accounts", token, {
"customer_id": "cust-uuid",
"account_type": "SAVINGS",
"currency": "NGN",
"product_code": "SAV001",
"branch_code": "001",
"alias": "Emergency Fund",
"initial_deposit": 100000.00,
"created_by": "user-uuid",
})
Response:
{
"id": "acct-uuid",
"tenant_id": "tenant-uuid",
"customer_id": "cust-uuid",
"account_number": "1001234567",
"account_type": "SAVINGS",
"status": "ACTIVE",
"currency": "NGN",
"available_balance": 100000.00,
"ledger_balance": 100000.00,
"hold_amount": 0.00,
"minimum_balance": 1000.00,
"overdraft_limit": 0.00,
"interest_rate": 2.5,
"daily_withdraw_limit": 500000.00,
"daily_transfer_limit": 1000000.00,
"transaction_count": 1,
"branch_code": "001",
"product_code": "SAV001",
"alias": "Emergency Fund",
"opened_at": "2026-02-28T10:00:00Z",
"created_by": "user-uuid"
}
The account number is auto-generated based on a per-tenant sequence. Product defaults (limits, interest rate, minimum balance) are inherited from the product template.
List Accounts
GET /api/v1/accounts?limit=20&status=ACTIVE¤cy=NGN
Supports cursor-based pagination. Filter by status, currency, account_type, and branch_code.
Get Account by Number
GET /api/v1/accounts/by-number/1001234567
Get Balance
GET /api/v1/accounts/:id/balance
{
"available_balance": 100000.00,
"ledger_balance": 100000.00,
"hold_amount": 0.00,
"currency": "NGN"
}
- Ledger balance — Total posted balance including holds.
- Available balance — Ledger balance minus holds. This is what's available for withdrawal or transfer.
- Hold amount — Sum of all active holds on the account.
Account Holds
Place a temporary hold on funds (e.g. pending authorization, dispute).
Place a Hold
POST /api/v1/accounts/:id/hold
{
"amount": 50000.00,
"reason": "Pending card authorization",
"reference": "AUTH20260228001",
"expires_at": "2026-03-07T00:00:00Z"
}
Holds reduce available_balance without changing ledger_balance.
Release a Hold
POST /api/v1/accounts/:id/hold/:hold_id/release
Freeze / Unfreeze
POST /api/v1/accounts/:id/freeze
POST /api/v1/accounts/:id/unfreeze
A frozen account blocks debits but allows credits (incoming transfers).
Close an Account
POST /api/v1/accounts/:id/close
An account can only be closed if its balance is zero and there are no active holds.
Account Statement
GET /api/v1/accounts/:id/statement?start_date=2026-01-01&end_date=2026-02-28
Returns balance entries (debits and credits) with running balance for the specified date range.
Virtual Accounts
Virtual accounts are sub-accounts under a parent. They share the parent's infrastructure but maintain independent balances.
Types
| Type | Use Case |
|---|---|
COLLECTION | Aggregate customer collections with unique references |
SWEEP | Auto-sweep funds to parent when threshold is reached |
SUB_ACCOUNT | Customer sub-accounts for budgeting or segregation |
INVESTMENT | Investment vehicles |
ESCROW | Escrow and settlement accounts |
POOLING | Pooled liquidity accounts |
Create a Virtual Account
POST /api/v1/accounts/:parent_id/virtual-accounts
{
"virtual_account_type": "COLLECTION",
"alias": "Invoice Collections",
"currency": "NGN"
}
Configure Auto-Sweep
PUT /api/v1/virtual-accounts/:id/config
{
"auto_sweep": true,
"sweep_threshold": 10000.00,
"sweep_target_account_id": "parent-uuid",
"sweep_frequency": "DAILY",
"include_in_parent_balance": true,
"inherit_parent_limits": true
}
| Sweep Frequency | Description |
|---|---|
IMMEDIATE | Sweep as soon as threshold is reached |
DAILY | Sweep once per day |
WEEKLY | Sweep once per week |
MONTHLY | Sweep once per month |
Consolidated Balance
Get the combined balance of a parent account and all its virtual accounts:
GET /api/v1/accounts/:parent_id/consolidated-balance
Customer Accounts
List all accounts belonging to a customer:
GET /api/v1/customers/:customer_id/accounts
Multi-Currency Aggregation
Get an aggregated balance view across all currencies:
GET /api/v1/accounts/aggregate
Next Steps
- Transactions — Transfer between accounts.
- General Ledger — How account balances link to the GL.
- Transaction Types — All account and transaction models.