Billing
Get the billing account
GET /b/v1/billing-accounts/me
The organisation’s billing account and its credit balances. Requires billing.account.read. A user sees both the live and the sandbox balance; an API key sees only its own mode’s. creditBalance is the available balance of mode. 404 RES101 until the account is provisioned.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
mode | query | string | No | Which ledger to read. Defaults to the token’s mode. API keys may only name their own mode (403 BIZ108). One of sandbox | live. |
Example request
Responses
The billing account.
Set the low-balance threshold
PATCH /b/v1/billing-accounts/me/low-balance
Tenant user only, billing.low_balance.configure. Sets the live balance below which one low-balance email is sent each time the balance drops past it; 0 turns it off. Live ledger only.
Who can call it: Signed-in user only: do this in the Yona app.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
threshold | integer | Yes | Live balance below which one low-balance email is sent per crossing; 0 disables. Between 0 and 100000000. |
Example request
Responses
The new threshold and whether the next drop below it will notify.
Check the balance covers an amount
GET /b/v1/billing-accounts/{id}/check-balance
Whether the available balance covers credits, for the caller’s own account (its id or me). Advisory only: the charge itself decides. Requires billing.account.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | The caller’s own billing account id, or me. |
mode | query | string | No | Which ledger to read. Defaults to the token’s mode. API keys may only name their own mode (403 BIZ108). One of sandbox | live. |
credits | query | integer | Yes | Between 1 and 1000000000. |
Example request
Responses
Whether the balance is sufficient.
Get billing account statistics
GET /b/v1/billing-accounts/{id}/stats
Balance, lifetime totals and the consumption rate over the last 30 days, for the caller’s own account (its id or me). Requires billing.account.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | The caller’s own billing account id, or me. |
mode | query | string | No | Which ledger to read. Defaults to the token’s mode. API keys may only name their own mode (403 BIZ108). One of sandbox | live. |
Example request
Responses
The account statistics.
Get the plans and packages catalogue
GET /b/v1/plans
The public subscription plans and credit packages in one response. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
Example request
Responses
Errors: 400
List credit costs
GET /b/v1/plans/credit-costs
The public price list: how many credits each billable action costs, grouped by section. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
Example request
Responses
Errors: 400
List credit packages
GET /b/v1/plans/packages
The public credit packages with their prices in integer minor units; featured filters on whether a package is featured. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
featured | query | boolean | No | Only featured packages (true) or only others (false). |
Example request
Responses
Errors: 400
Get a credit package
GET /b/v1/plans/packages/{id}
One public credit package by its id. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | Yes | |
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
Example request
Responses
Errors: 400, 404
List subscription plans
GET /b/v1/plans/subscriptions
The public subscription plans with their prices in integer minor units, optionally narrowed to one currency or interval. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
Example request
Responses
Errors: 400
Get a subscription plan
GET /b/v1/plans/subscriptions/{code}
One public subscription plan by its code. No token needed.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
code | path | string | Yes | |
currency | query | string | No | Only prices in this currency. One of NGN | USD. |
interval | query | string | No | Only plan prices for this interval. One of monthly | yearly. |
Example request
Responses
Errors: 400, 404
Get a subscription
GET /b/v1/subscriptions/{id}
One subscription of the organisation. Requires billing.subscription.read. Another organisation’s subscription answers 404 RES001.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Example request
Responses
The subscription.
Get the current subscription
GET /b/v1/subscriptions/active
The organisation’s active or past-due subscription and its current monthly allocation window (window is null while past due). Requires billing.subscription.read. 404 RES001 when there is none.
Who can call it: API key or signed-in user.
Example request
Responses
The current subscription.
List subscriptions
GET /b/v1/subscriptions/history
Every subscription of the organisation, newest first. Requires billing.subscription.read.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (1-based). Default: 1. At least 1. |
limit | query | number | No | Items per page. Default: 50. Between 1 and 100. |
Example request
Responses
A page of subscriptions.
List subscription billing periods
GET /b/v1/subscriptions/renewals
The billing periods of the organisation’s subscriptions and how each was charged, optionally for one subscription. Requires billing.subscription.read.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (1-based). Default: 1. At least 1. |
limit | query | number | No | Items per page. Default: 50. Between 1 and 100. |
subscriptionId | query | string (uuid) | No | Only this subscription’s periods (must be the caller’s). |
Example request
Responses
A page of billing periods.
Subscribe to a plan
POST /b/v1/subscriptions/subscribe
Tenant user only, billing.subscription.subscribe, from a live-mode session. Creates a pending_payment subscription and starts a hosted checkout for its first period; it becomes active when the provider confirms the payment. Optional Idempotency-Key header: the same key and body return the original checkout; the same key with another body is 409 BIZ107.
Who can call it: Signed-in user only: do this in the Yona app.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
planCode | string | Yes | |
interval | string | Yes | One of monthly | yearly. |
currency | string | Yes | Required; 422 BIZ101 when no provider is routed for it. One of NGN | USD. |
returnPath | string | No | Dashboard path to return to after checkout; must be one of the allowed dashboard return paths. Absolute URLs are refused. |
Example request
Responses
The same checkout is still pending and is returned again.
A new checkout was started: the subscription, the payment and the checkout URL.
Errors: 403
Cancel a subscription
PUT /b/v1/subscriptions/{id}/cancel
Tenant user only, billing.subscription.cancel. An active subscription is cancelled at the end of its current period (cancelAtPeriodEnd becomes true). A subscription still awaiting its first payment is checked with the payment provider first: unpaid, it and its checkout expire now; already paid, the cancellation is refused with 409 BIZ004.
Who can call it: Signed-in user only: do this in the Yona app.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Why the subscription is being cancelled. At most 500 characters. |
Example request
Responses
The subscription after the cancellation.
Renew a past-due subscription
POST /b/v1/subscriptions/{id}/renew
Tenant user only, billing.subscription.renew, from a live-mode session. Starts a hosted checkout to pay the overdue period of a past_due subscription. Optional Idempotency-Key header: the same key and body return the original checkout; the same key with another body is 409 BIZ107.
Who can call it: Signed-in user only: do this in the Yona app.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
returnPath | string | No | Dashboard path to return to after checkout; must be one of the allowed dashboard return paths. Absolute URLs are refused. |
Example request
Responses
The same checkout is still pending and is returned again.
A new checkout was started: the subscription, the payment and the checkout URL.
Errors: 403
Resume a subscription
PUT /b/v1/subscriptions/{id}/resume
Tenant user only, billing.subscription.resume. Clears a cancellation scheduled for the end of the current period.
Who can call it: Signed-in user only: do this in the Yona app.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Example request
Responses
The subscription after the cancellation was cleared.
Get a payment
GET /b/v1/payments/{id}
One payment of the organisation. Requires billing.payment.read. checkoutUrl is present only while the payment is pending. Another organisation’s payment answers 404 RES001.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Example request
Responses
The payment.
List payments
GET /b/v1/payments/history
The organisation’s payments, newest first, optionally filtered by status and kind. Requires billing.payment.read. No checkout URL in the list.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (1-based). Default: 1. At least 1. |
limit | query | number | No | Items per page. Default: 50. Between 1 and 100. |
status | query | string | No | One of pending | succeeded | failed | expired | partially_refunded | refunded | disputed | charged_back. |
kind | query | string | No | One of credit_purchase | subscription | renewal. |
Example request
Responses
A page of payments.
Buy a credit package
POST /b/v1/payments/purchase
Tenant user only, billing.credits.purchase, from a live-mode session. Starts a hosted checkout for one credit package in the chosen currency; the credits are granted when the provider confirms the payment. Optional Idempotency-Key header: the same key and body return the original checkout; the same key with another body is 409 BIZ107.
Who can call it: Signed-in user only: do this in the Yona app.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
packageId | string (uuid) | Yes | The package id listed by GET /plans/packages. |
currency | string | Yes | Required; 422 BIZ101 when no provider is routed for it. One of NGN | USD. |
returnPath | string | No | Dashboard path to return to after checkout; must be one of the allowed dashboard return paths. Absolute URLs are refused. |
Example request
Responses
The pending payment and its hosted checkout URL.
Errors: 403
List ledger entries
GET /b/v1/transactions
Credit ledger entries (grants, charges, holds, refunds, expiries…), newest first, filtered by kind, date range, cost code or exact reference. Requires billing.ledger.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (1-based). Default: 1. At least 1. |
limit | query | number | No | Items per page. Default: 50. Between 1 and 100. |
type | query | string | No | One of grant_plan | grant_purchase | grant_allowance | grant_adjustment | charge | hold | hold_release | refund | clawback | adjustment_debit | expiry | debt_settlement. |
mode | query | string | No | Defaults to the token’s mode; API keys may only name their own (403 BIZ108). One of sandbox | live. |
startDate | query | string (date-time) | No | |
endDate | query | string (date-time) | No | |
costCode | query | string | No | |
reference | query | string | No | Exact business reference of the entry (no prefix or wildcard match). At most 255 characters. |
Example request
Responses
A page of ledger entries.
Get a ledger entry
GET /b/v1/transactions/{id}
One ledger entry of the organisation. Requires billing.ledger.read. Another organisation’s entry answers 404 RES001.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Example request
Responses
The ledger entry.
Get credit usage over time
GET /b/v1/transactions/analytics/usage
Credits spent per daily, weekly (ISO week) or monthly UTC bucket over a date range (the last 30 days by default, at most 366 days). Requires billing.usage.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
mode | query | string | No | One of sandbox | live. |
startDate | query | string (date-time) | No | |
endDate | query | string (date-time) | No | At most 366 days after startDate. |
period | query | string | No | One of daily | weekly | monthly. Default: daily. |
Example request
Responses
One row per time bucket.
Get credit usage by cost code
GET /b/v1/transactions/breakdown/by-endpoint
Credits spent per cost code, net of refunds, over a date range (the last 30 days by default, at most 366 days). Requires billing.usage.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
mode | query | string | No | One of sandbox | live. |
startDate | query | string (date-time) | No | |
endDate | query | string (date-time) | No | At most 366 days after startDate. |
Example request
Responses
One row per cost code.
Get a monthly statement
GET /b/v1/statements/{period}
One UTC month (YYYY-MM, not in the future) of one ledger: opening and closing balance, grants by source, charges by cost code, refunds, expiries and held credits; payments on live statements. Requires billing.statement.read. Reads the ledger of the token’s mode unless mode names another; an API key may read only its own mode (403 BIZ108).
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
period | path | string | Yes | |
mode | query | string | No | Which ledger to read. Defaults to the token’s mode. API keys may only name their own mode (403 BIZ108). One of sandbox | live. |
Example request
Responses
The statement.
Top up sandbox test credits (capped, no payment)
POST /b/v1/sandbox/topup
Tenant user only, billing.credits.purchase. Grants test credits on the sandbox ledger (never live), expiring with the UTC month. At most the configured per-top-up cap (1,000 credits by default) per top-up, and at most the configured number of top-ups (3 by default) per organisation per UTC month. Not idempotent by key: each accepted call is one of the month’s top-ups.
Who can call it: Signed-in user only: do this in the Yona app.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
credits | integer | No | Test credits to add to the sandbox ledger, from 1 up to the per-top-up cap (1,000 by default); absent means the cap. At least 1. |
Example request
Responses
The grant entry and the month’s top-up count.
Errors: 400, 403, 404, 429
List sandbox ledger entries
GET /b/v1/sandbox/transactions
The sandbox ledger’s entries, newest first, with the same filters as the ledger entry list. Requires billing.ledger.read. A live-mode API key is refused with 403 BIZ108.
Who can call it: API key or signed-in user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | number | No | Page number (1-based). Default: 1. At least 1. |
limit | query | number | No | Items per page. Default: 50. Between 1 and 100. |
type | query | string | No | One of grant_plan | grant_purchase | grant_allowance | grant_adjustment | charge | hold | hold_release | refund | clawback | adjustment_debit | expiry | debt_settlement. |
startDate | query | string (date-time) | No | |
endDate | query | string (date-time) | No | |
costCode | query | string | No | |
reference | query | string | No | Exact business reference of the entry (no prefix or wildcard match). At most 255 characters. |
Example request
Responses
A page of sandbox ledger entries.
Get sandbox allowance usage
GET /b/v1/sandbox/usage
This UTC month’s free sandbox allowance: granted, used and remaining. Requires billing.usage.read. A live-mode API key is refused with 403 BIZ108.
Who can call it: API key or signed-in user.
Example request
Responses
The month’s sandbox allowance.
Get the billing overview
GET /b/v1/setup
The dashboard’s billing overview in one call: the current subscription, the account, balances, the sandbox allowance and the plans on offer priced in the account’s currency (integer minor units). Requires billing.account.read. An API key sees only its own mode’s blocks.
Who can call it: API key or signed-in user.
Example request
Responses
The billing overview.