Skip to content

Settlements

The batches in which your collected money is paid out to you.

Endpoint What it does
GET /v1/settlements List settlements
GET /v1/settlements/{id} Retrieve a settlement
GET /v1/settlements/{id}/items List a settlement’s lines
GET /v1/withdrawals List withdrawals

Try any of them in the API tester.

GET /v1/settlements

Your settlement batches: one per currency per period, newest period first.

expected_payout_at is the “when do I get paid” answer. It is derived from the period end plus your configured settlement delay, so it is an ESTIMATE and expected_payout_is_estimate says so; paid_at is the fact.

MIND THE WORD pending. A settlement whose status is pending has closed and is awaiting approval in our payout queue. That is NOT the pending on /v1/balances, which means a partner has not yet funded us for your collections. Every settlement carries a status_detail sentence that says which is which.

amounts is the whole composition — gross, platform fees, commissions, refunds, reversals, reserve movements and adjustments — not just a net, so you can reproduce the arithmetic. The database enforces that identity.

A period window is always applied: omitting one defaults to the last 90 days, and a window wider than 400 days is refused rather than silently truncated.

Authentication: a secret key (server-side only) with the scope settlement.read.

Field Type Required Allowed values and limits What it is
limit integer no min 1; max 100; default 25 Rows per page. Clamped to 100.
offset integer no min 0 Rows to skip.
period_after string no RFC 3339. Batches whose period ENDS at or after this. Defaults to 90 days ago; the window may not exceed 400 days.
period_before string no RFC 3339. Batches whose period ends before this. Defaults to now.
currency string no e.g. GHS One batch exists per currency per period.
status string no One of: accruing, pending, approved, processing, paid, failed, on_hold Note that pending here means awaiting approval in our payout workflow, NOT the pending on /v1/balances.
Field Type What it is
data array
has_more boolean Derived from fetching one row beyond the page, so a full final page does not advertise an empty next one.
object string
offset integer
page_size integer
window object
window.created_after string (date-time)
window.created_before string (date-time)
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.


GET /v1/settlements/{id}

Adds the payout destination to what the list returns. destination.verified is the most actionable field on a settlement that is not moving: we do not pay out to an account a name enquiry has not confirmed.

A failed settlement reports the status and nothing more — the detailed reason is an internal operations note. Quote the reference to support. A settlement on_hold does carry a short hold_reason; it is prose, not a code.

Authentication: a secret key (server-side only) with the scope settlement.read.

Field Type Required Allowed values and limits What it is
{id} string (uuid) yes The settlement batch’s id.
Field Type What it is
amounts object
amounts.adjustment integer Signed. A negative net from a previous period is carried forward as a negative adjustment here rather than paid as a negative amount.
amounts.commissions integer Partner or reseller commission, deducted.
amounts.gross integer Sum of collections settled in the period.
amounts.net integer What we pay you: gross minus platform_fees minus commissions minus refunds minus reversals minus reserve_held plus reserve_released plus adjustment. The database enforces that identity, so if it does not add up the batch would not have been written.
amounts.payouts integer Payouts you made from your balance in the period, plus their fees, less any returned. A deduction: that money has already left.
amounts.platform_fees integer Our fees and taxes, deducted.
amounts.refunds integer Refunds you issued in the period, deducted.
amounts.reserve_held integer Moved into a rolling reserve this period, deducted. Mirrors the reserved figure on /v1/balances.
amounts.reserve_released integer Released from reserve this period, added back.
amounts.reversals integer Reversals and chargebacks in the period, deducted.
closed_at string (date-time) When the accrual window closed. Absent while the batch is still accruing.
created_at string (date-time)
currency string
destination object
destination.account_name string
destination.type string One of: bank, mobile_money, wallet
destination.verified boolean False means we have not confirmed this account with the bank or network. We do not pay out to an unverified destination.
environment string One of: test, live
expected_payout_at string (date-time) Derived from period_end plus your configured settlement delay. An estimate, not a commitment — read status.
expected_payout_is_estimate boolean Always true. Use paid_at for what actually happened.
hold_reason string A short note from our operations team. Prose, not a code — do not parse it. Contact support quoting the reference.
id string
object string
paid_at string (date-time) When we actually sent the money. This is the fact; expected_payout_at was the estimate.
period object
period.end string (date-time)
period.start string (date-time)
reference string Quote this to support. It also appears on the bank narration where the rail allows one.
status string One of: accruing, pending, approved, processing, paid, failed, on_hold
status_detail string
transaction_count integer Distinct collections in the batch. Fees, refunds and adjustments are lines on /items, not transactions.
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 404: no such resource on this account
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.


GET /v1/settlements/{id}/items

The statement, line by line. A disputed settlement is always argued at this level, which is why we store the lines and not just the total.

amount IS SIGNED AS STORED: a fee, a refund and a reversal are negative. We do not normalise them to positive numbers with a type to interpret, because that is how a reconciliation ends up summing to twice the gross.

transaction_date is the date to reconcile against, not the date we wrote the line. Each transaction_id is readable at /v1/transactions/{id}.

Pages are larger here than elsewhere — 100 by default, up to 500 — because walking a month of collections 25 at a time is hundreds of round trips.

Authentication: a secret key (server-side only) with the scope settlement.read.

Field Type Required Allowed values and limits What it is
{id} string (uuid) yes The settlement batch whose lines to list.
limit integer no min 1; max 500; default 100 Rows per page. Clamped to 500 — higher than elsewhere because reconciling a month of collections 25 at a time is hundreds of round trips.
offset integer no min 0 Rows to skip.
Field Type What it is
data array
has_more boolean
object string
offset integer
page_size integer
settlement_id string
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 404: no such resource on this account
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.


GET /v1/withdrawals

Withdrawals you requested against your available balance, newest first. Distinct from a settlement: a settlement is us paying you on a schedule, a withdrawal is you asking for your available balance now.

amount is what you asked for, fee is deducted from it rather than added, and net is what reaches your account.

Unlike a settlement, a failed withdrawal DOES carry failure_reason: you chose the destination, so “the account number was rejected” is yours to act on.

A date window is always applied: omitting one defaults to the last 90 days, and a window wider than 400 days is refused.

Authentication: a secret key (server-side only) with the scope settlement.read.

Field Type Required Allowed values and limits What it is
limit integer no min 1; max 100; default 25 Rows per page. Clamped to 100.
offset integer no min 0 Rows to skip.
created_after string no RFC 3339. Defaults to 90 days ago; the window may not exceed 400 days.
created_before string no RFC 3339. Defaults to now.
status string no One of: pending, approved, processing, paid, failed, cancelled, on_hold Only withdrawals in this state. pending: awaiting approval. approved: released for sending. processing: being sent. paid: sent to your account. failed: the transfer failed; see failure_reason. cancelled: called off before sending. on_hold: frozen, for example by a dispute or a review.
Field Type What it is
data array
has_more boolean
object string
offset integer
page_size integer
  • 401: the key is missing, wrong or revoked
  • 403: the key lacks the scope, or your account may not do this
  • 422: a field is invalid; errors names it
  • 429: too many requests; wait for Retry-After
  • 500: Internal Server Error
  • 503: the payment partner is unreachable; safe to retry

Every error is a JSON problem with a stable code. See Errors.