Ledgers
WhoComply ships a native double-entry ledger. Every transaction is balanced (total debits equal total credits), append-only, hash-chained, and HMAC-signed at posting time. This gives you a regulator-defensible audit trail for the funds movements that compliance reports cite.
Amounts are passed as minor-unit integers serialized as strings (e.g. "250000000" for ₦2,500,000.00 — NGN has 2 decimals). String form prevents JavaScript from losing precision on large amounts.
GETs require read scope. Mutations require write scope.
List currencies
Returns the currencies configured for the tenant. Each currency declares its minor-unit precision.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/currencies" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": [
{ "code": "NGN", "name": "Nigerian Naira", "minor_unit_decimals": 2 },
{ "code": "USD", "name": "United States Dollar", "minor_unit_decimals": 2 }
]
}
Create ledger
Create a new ledger. Each ledger holds accounts denominated in a single currency. Requires write scope.
- Name
name- Type
- string
- Description
Human-readable ledger name.
- Name
currency- Type
- string
- Description
ISO currency code. Must be configured for the tenant.
- Name
description- Type
- string
- Description
Optional description.
- Name
metadata- Type
- object
- Description
Free-form JSON metadata.
Request
curl -X POST "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers" \
-H "Authorization: Bearer wc_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Wallets",
"currency": "NGN",
"description": "Primary Naira wallet ledger"
}'
Response (201)
{
"status": "ok",
"data": {
"id": "ldg-a1b2c3d4-...",
"name": "Customer Wallets",
"currency": "NGN",
"status": "active",
"description": "Primary Naira wallet ledger",
"created_at": "2026-04-17T08:00:00Z"
}
}
List ledgers
Returns all ledgers for the tenant.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": [
{
"id": "ldg-a1b2c3d4-...",
"name": "Customer Wallets",
"currency": "NGN",
"status": "active",
"created_at": "2026-04-17T08:00:00Z"
}
]
}
Get ledger
Returns a single ledger.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers/{ledger_id}" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": {
"id": "ldg-a1b2c3d4-...",
"name": "Customer Wallets",
"currency": "NGN",
"status": "active",
"description": "Primary Naira wallet ledger",
"created_at": "2026-04-17T08:00:00Z"
}
}
Create account
Create an account inside a ledger. Currency is inherited from the ledger and not specified in the body. Requires write scope.
- Name
code- Type
- string
- Description
Short, tenant-unique account code (e.g.
ACC-005,OPS-CASH).
- Name
name- Type
- string
- Description
Human-readable account name.
- Name
account_type- Type
- string
- Description
One of
asset,liability,equity,revenue, orexpense. Determines the natural balance side.
- Name
external_ref- Type
- string
- Description
Your external reference (e.g. core-banking account number) for correlation.
- Name
metadata- Type
- object
- Description
Free-form JSON metadata.
Request
curl -X POST "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers/{ledger_id}/accounts" \
-H "Authorization: Bearer wc_..." \
-H "Content-Type: application/json" \
-d '{
"code": "ACC-005",
"name": "Adebayo Mustapha Wallet",
"account_type": "liability",
"external_ref": "090267-0012345678",
"metadata": { "customer_id": "f1e2d3c4-..." }
}'
Response (201)
{
"id": "acc-x1y2z3-...",
"ledger_id": "ldg-a1b2c3d4-...",
"code": "ACC-005",
"name": "Adebayo Mustapha Wallet",
"account_type": "liability",
"currency": "NGN",
"external_ref": "090267-0012345678",
"metadata": { "customer_id": "f1e2d3c4-..." },
"is_active": true,
"created_at": "2026-04-17T08:15:00Z"
}
List accounts
Returns all accounts in a ledger with running balances.
Account fields
- Name
balance- Type
- string
- Description
Signed minor-unit balance, computed by
natural-side - opposite-side. For asset/expense accounts that'sdebit_total - credit_total; for liability/equity/revenue accounts it'scredit_total - debit_total. Returned as a string.
- Name
debit_total- Type
- string
- Description
Sum of all debit entries on this account, in minor units.
- Name
credit_total- Type
- string
- Description
Sum of all credit entries on this account, in minor units.
- Name
entry_count- Type
- integer
- Description
Total number of entries booked.
- Name
last_activity_at- Type
- timestamp
- Description
When the most recent entry was posted.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers/{ledger_id}/accounts" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": [
{
"id": "acc-x1y2z3-...",
"code": "ACC-005",
"name": "Adebayo Mustapha Wallet",
"account_type": "liability",
"currency": "NGN",
"external_ref": "090267-0012345678",
"is_active": true,
"debit_total": "0",
"credit_total": "250000000",
"balance": "250000000",
"entry_count": 1,
"last_activity_at": "2026-04-17T09:00:00Z",
"created_at": "2026-04-17T08:15:00Z"
}
]
}
Post transaction
Create a balanced double-entry transaction. The sum of debits must equal the sum of credits in minor units, or the request is rejected. Requires write scope.
Each posting is hash-chained against the previous transaction in the ledger and signed with HMAC-SHA-256, so any tampering with stored entries is detectable via the verify endpoint.
- Name
ledger_id- Type
- uuid
- Description
Ledger this posting belongs to.
- Name
currency- Type
- string
- Description
ISO currency code. Must match the ledger's currency.
- Name
description- Type
- string
- Description
Human-readable description.
- Name
reference- Type
- string
- Description
Your external reference for this transaction.
- Name
idempotency_key- Type
- string
- Description
Pass a unique key to deduplicate retries. A second request with the same key returns the original transaction.
- Name
narration- Type
- string
- Description
Free-form context, surfaced in reports.
- Name
metadata- Type
- object
- Description
Free-form JSON metadata.
- Name
entries- Type
- array
- Description
Two or more
PostingEntryobjects (see below).
PostingEntry
- Name
account_id- Type
- uuid
- Description
The account being debited or credited. The same account may not appear twice in one posting.
- Name
debit- Type
- string
- Description
Minor-unit amount as a string. Mutually exclusive with
credit.
- Name
credit- Type
- string
- Description
Minor-unit amount as a string. Mutually exclusive with
debit.
- Name
description- Type
- string
- Description
Optional line-level description.
Request
curl -X POST "https://api.whocomply.com/api/v1/tenants/kuda-mfb/postings" \
-H "Authorization: Bearer wc_..." \
-H "Content-Type: application/json" \
-d '{
"ledger_id": "ldg-a1b2c3d4-...",
"currency": "NGN",
"description": "Wallet funding via bank transfer",
"reference": "TXN-2026-04-17-001",
"idempotency_key": "deposit-001",
"entries": [
{ "account_id": "acc-funding-...", "debit": "250000000", "description": "Funding source" },
{ "account_id": "acc-x1y2z3-...", "credit": "250000000", "description": "Customer wallet" }
]
}'
Response (201)
{
"status": "ok",
"data": {
"transaction": {
"id": "post-d4e5f6g7-...",
"ledger_id": "ldg-a1b2c3d4-...",
"reference": "TXN-2026-04-17-001",
"currency": "NGN",
"amount_minor": "250000000",
"status": "posted",
"hash_chain_position": 142,
"transaction_hash": "...",
"previous_hash": "...",
"is_immutable": true,
"posted_at": "2026-04-17T09:00:00Z"
},
"entries": [
{ "id": "ent-001", "account_id": "acc-funding-...", "debit_minor": "250000000", "credit_minor": "0" },
{ "id": "ent-002", "account_id": "acc-x1y2z3-...", "debit_minor": "0", "credit_minor": "250000000" }
]
}
}
List transactions
Returns posted transactions in a ledger, ordered by hash-chain position.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/ledgers/{ledger_id}/transactions?limit=20" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": [
{
"id": "post-d4e5f6g7-...",
"ledger_id": "ldg-a1b2c3d4-...",
"reference": "TXN-2026-04-17-001",
"currency": "NGN",
"amount_minor": "250000000",
"status": "posted",
"hash_chain_position": 142,
"posted_at": "2026-04-17T09:00:00Z"
}
]
}
Get transaction
Returns a single transaction with all its entries.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/postings/{posting_id}" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": {
"transaction": {
"id": "post-d4e5f6g7-...",
"ledger_id": "ldg-a1b2c3d4-...",
"reference": "TXN-2026-04-17-001",
"currency": "NGN",
"amount_minor": "250000000",
"status": "posted",
"hash_chain_position": 142,
"posted_at": "2026-04-17T09:00:00Z"
},
"entries": [
{ "id": "ent-001", "account_id": "acc-funding-...", "debit_minor": "250000000", "credit_minor": "0" },
{ "id": "ent-002", "account_id": "acc-x1y2z3-...", "debit_minor": "0", "credit_minor": "250000000" }
]
}
}
Verify transaction
Re-runs every cryptographic + structural check on a posted transaction. Returns a checks object covering content hash, signature, hash-chain linkage, and double-entry balance. Used in audits and dispute investigations.
- Name
checks.content_hash_ok- Type
- boolean
- Description
The recomputed hash of the posting payload matches what was stored at posting time.
- Name
checks.transaction_hash_ok- Type
- boolean
- Description
The transaction-level hash matches its expected derivation.
- Name
checks.signature_ok- Type
- boolean
- Description
HMAC signature over the transaction hash verifies against the ledger's signing key.
- Name
checks.chain_ok- Type
- boolean
- Description
The transaction's
previous_hashcorrectly links it into the ledger's hash chain.
- Name
checks.double_entry_ok- Type
- boolean
- Description
Total debits equal total credits across all entries.
- Name
verified- Type
- boolean
- Description
trueonly when all checks pass.
Request
curl "https://api.whocomply.com/api/v1/tenants/kuda-mfb/postings/{posting_id}/verify" \
-H "Authorization: Bearer wc_..."
Response
{
"status": "ok",
"data": {
"transaction_id": "post-d4e5f6g7-...",
"checks": {
"content_hash_ok": true,
"transaction_hash_ok": true,
"signature_ok": true,
"chain_ok": true,
"double_entry_ok": true
},
"verified": true,
"verified_at": "2026-04-17T09:05:00Z"
}
}