Billing
What is in the pool, what it went on, and what any one customer is allowed to spend of it.
Read one customer's spending limits
GET/v1/customers/{id}/limits
What this customer may spend and how many calls they may run at once, plus what they have spent today and this month. A limit of `null` means no limit of your own — your account-wide caps still apply.
Permission: customers:read
Parameters
| Name | In | Type | |
|---|---|---|---|
id * | path | string | Kleos id or your `external_ref`. |
Response
{
"object": "customer_limits",
"customer_id": "0f2a6c4e-96a2-4f2e-8f2b-6c1a0e73d8b1",
"external_ref": "crm-8842",
"daily_spend_cap_cents": 2000,
"monthly_spend_cap_cents": 40000,
"max_concurrent_calls": 2,
"spend": {
"today_cents": 640,
"month_cents": 9120
}
}Refusals
| Status | Code | When |
|---|---|---|
| 404 | customer_not_found | No customer with that id in this mode. |
Cap one customer's spending
PATCH/v1/customers/{id}/limits
The pool is shared, so one customer's runaway campaign can spend money that is funding the rest. Send only the fields you want to change; send `null` to clear one. Caps stop NEW calls — a call already in progress is never cut off.
Permission: customers:write
Parameters
| Name | In | Type | |
|---|---|---|---|
id * | path | string | Kleos id or your `external_ref`. |
Idempotency-Key | header | string | Your own unique string. Replaying it returns the first response for 24 hours. |
Body
| Field | Type | |
|---|---|---|
daily_spend_cap_cents | integer | Most this customer may spend in a UTC day. `null` clears it. |
monthly_spend_cap_cents | integer | Most this customer may spend in a calendar month. `null` clears it. |
max_concurrent_calls | integer | Most calls this customer may have running at once. Never raises your account ceiling. |
Response
{
"object": "customer_limits",
"customer_id": "0f2a6c4e-96a2-4f2e-8f2b-6c1a0e73d8b1",
"external_ref": "crm-8842",
"daily_spend_cap_cents": 2000,
"monthly_spend_cap_cents": 40000,
"max_concurrent_calls": 2
}Refusals
| Status | Code | When |
|---|---|---|
| 400 | invalid_limit | A limit was negative, fractional, or not a number. |
| 404 | customer_not_found | No customer with that id in this mode. |
What is in the pool, and what a minute costs
GET/v1/balance
Both halves matter. `available_cents` excludes money held against calls already running, so it is what your next call can actually draw on. The rate is the one in force right now — it drops as the month's minutes cross a tier, so a figure hard-coded in your own billing will be wrong from the 5,001st minute onwards. All amounts are whole US cents.
Permission: billing:read
Response
{
"object": "balance",
"currency": "usd",
"available_cents": 41250,
"balance_cents": 43100,
"paid_cents": 40000,
"bonus_cents": 3100,
"bonus_expires_at": "2027-08-04T00:00:00.000Z",
"reserved_cents": 1850,
"minimum_top_up_cents": 2500,
"low_balance": "ok",
"rates": {
"call_cents_per_minute": 20,
"minutes_used_this_month": 1840,
"estimated_call_minutes_remaining": 2062,
"number_cents_per_month": 1500,
"caller_id_cents_per_month": 1200,
"chat_message_cents": 2,
"prospect_cents": 4,
"call_tiers": [
{
"from_minutes": 0,
"cents_per_minute": 20
},
{
"from_minutes": 5000,
"cents_per_minute": 18
},
{
"from_minutes": 25000,
"cents_per_minute": 16
},
{
"from_minutes": 100000,
"cents_per_minute": 15
}
]
},
"spend": {
"today_cents": 3120,
"month_cents": 36800,
"daily_cap_cents": null,
"monthly_cap_cents": null
}
}Every movement of money, itemised
GET/v1/usage
The ledger you rebill your own customers from. Each line carries `customer_id`, so attribution never has to be reconstructed. Negative is money out, positive is money in. Test-mode lines are returned with `applied: false` — they show what live traffic would have cost and were never charged.
Permission: billing:read
Parameters
| Name | In | Type | |
|---|---|---|---|
limit | query | integer | How many to return. Defaults to 100, capped at 200. |
customer_id | query | string | Only lines belonging to this customer. |
Response
{
"object": "list",
"data": [
{
"object": "usage_entry",
"id": "7c2f1a90-2c3e-4c0a-9b76-3f0a1e8d44c2",
"type": "usage",
"amount_cents": -80,
"currency": "usd",
"balance_after_cents": 41170,
"applied": true,
"customer_id": "0f2a6c4e-96a2-4f2e-8f2b-6c1a0e73d8b1",
"reference": "call_9f31c0",
"description": "Call — 4 minutes",
"mode": "live",
"created_at": "2026-08-04T09:41:02.000Z"
}
],
"has_more": false
}