API reference
One base URL per environment, one key per environment, JSON in and out. The full OpenAPI 3.1 document is the authority for schemas; this page is the map.
Authentication
A bearer API key, issued per environment and shown once. Keys carry scopes, so a key that reads credits cannot approve a payout even if it leaks.
Authorization: Bearer nvk_live_01J9... Content-Type: application/json Idempotency-Key: <your key, on every write>
Conventions
- Money is
{ currency, value }withvaluea two-decimal string. Never a float. - Times are ISO 8601 in UTC. Date filters are inclusive of both ends, in your product’s timezone.
- Lists are cursor-paginated:
?limit=&cursor=, withnext_cursorin the response. - Ids are prefixed by kind —
crd_,hld_,pay_— so a wrong one is obvious in a log.
Endpoints
Accounts and directory
The addresses money arrives on, and who they belong to.
| GET | /v1/accounts | Every virtual account, with its holder and group. |
| GET | /v1/accounts/{id} | One account, with its credits. |
| POST | /v1/accounts | Issue an account number for a holder. |
| GET | /v1/groups | Your hierarchy, in your vocabulary. |
| GET | /v1/holders/{id} | One holder and their accounts. |
Credits
Money that arrived. Immutable — a correction is a new entry.
| GET | /v1/credits?from=&to=&group_id= | Credits in a range, filterable by group. |
| GET | /v1/credits/{id} | One credit with its fee breakdown and ledger lines. |
| GET | /v1/credits/{id}/postings | The journal entries it wrote. |
Wallets
Derived balances. Never stored, always computed.
| GET | /v1/wallets/{owner}/balance | The balance, as of an instant it names. |
| GET | /v1/wallets/{owner}/statement?from=&to= | Postings by value date with a running balance. |
| POST | /v1/transfers | Move value between two wallets in the same product. Needs an Idempotency-Key. |
Payouts
Money leaving. Recorded here, executed at the bank.
| GET | /v1/payouts?status= | Payouts by status, with ageing. |
| POST | /v1/payouts | Request one against a group wallet. Posts nothing — it reserves. |
| POST | /v1/payouts/{id}/approve | Move it into payout clearing. Needs payouts:approve. |
| POST | /v1/payouts/{id}/paid | Record the bank reference once it is actually paid. |
Settlements
What the bank paid, and which credits it covered.
| GET | /v1/settlements?from=&to=&status= | Cycles with totals and reconciliation state. |
| GET | /v1/settlements/{id} | One cycle with its identity checks. |
| GET | /v1/settlements/{id}/credits | The credits it covers. |
Delivery
What we sent you, and what you said back.
| GET | /v1/deliveries?event_id=&status= | Deliveries, filterable. |
| GET | /v1/deliveries/{event_id}/attempts | Every attempt, with status, latency and response snippet. |
| POST | /v1/deliveries/{event_id}/replay | Replay one, reusing the event id. |
| POST | /v1/webhooks/{id}/pause | Queue events without dead-lettering them. |
Reports
Read from the ledger, never recomputed.
| GET | /v1/reports/collections?granularity= | By day, week or month; filterable by group. |
| GET | /v1/reports/fees | The fee split over a range. |
| GET | /v1/reports/balances | Balances by owner. |
| POST | /v1/exports | CSV for any report. Under 5,000 rows is synchronous. |
What is built today
Nineveh is in pilot. The consoles, the ledger, delivery, settlement, reconciliation and payouts are built and running against a real database; the HTTP surface above is specified in the OpenAPI document and is being exposed endpoint by endpoint as the first product needs it. Ask before you build against one — we will tell you honestly whether it exists yet.
The sandbox console is the fastest way to see the whole thing behave: sign in and press Simulate a top-up.