Balance and compliance
The account facts a request can be refused over: the credit balance (a send or a campaign start) and the outbound compliance acknowledgment (a campaign start only); and what the credits went on (usage). How-to: Credits and balance, Usage and spend, Accept the outbound compliance acknowledgment.
Generated from /openapi/v1.json; interactive version: API reference.
Endpoints
Section titled “Endpoints”| method | path | what it does | success |
|---|---|---|---|
GET | /v1/balance | Read the credit balance | 200 |
GET | /v1/usage | Report what the credits went on | 200 |
GET | /v1/usage/events | List charges one by one, newest first | 200 |
GET | /v1/usage/export | Download the charges as CSV | 200 |
GET | /v1/compliance | Read the outbound compliance acknowledgment | 200 |
POST | /v1/compliance/accept | Accept the outbound compliance acknowledgment | 200 |
GET /v1/balance
Section titled “GET /v1/balance”Read the credit balance.
The workspace’s credits, what can be spent now (available_credits) and whether it is suspended: what 402 insufficient_credits, 402 billing_not_eligible and 402 workspace_suspended are decided on. Any key of the workspace. The balance is at most about 5 minutes old (updated_at), so reading it more often than that does not make it fresher. Add credits in the dashboard under Settings, Billing.
Answers 200 with Balance. Errors use the error envelope; common codes: balance and compliance, every request.
GET /v1/usage
Section titled “GET /v1/usage”Report what the credits went on.
Credits charged in a window, in total and grouped by category (default), UTC day and/or label (what was charged, in words). Default window: the current billing cycle (cycle_start) to now, the same usage pending_credits on GET /v1/balance counts. from is inclusive, to exclusive, at most 400 days apart. Any key of the workspace. Not paged; a day with no usage has no group.
Parameters
| name | in | type | description |
|---|---|---|---|
from | query | string | Start of the window, inclusive: an ISO 8601 date (midnight UTC) or instant. Default: the start of the current billing cycle (cycle_start). |
to | query | string | End of the window, exclusive. Default: now. At most 400 days after from. To make /v1/usage, /v1/usage/events and /v1/usage/export answer the same rows, pass all three the from and to that /v1/usage echoed. |
category | query | stringphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | Only this category: phone (call minutes, attempts, voicemails and short calls), recording (call connection and call recording minutes, recording storage), speech (speech-to-text, text-to-speech and realtime voice), ai (AI model tokens and embeddings), messaging (SMS and MMS, and messages on chat channels (Telegram, Messenger, Instagram, LINE, Slack, Discord)), whatsapp (WhatsApp conversation and platform fees), email (email sent), numbers (phone number rental), other (anything else (knowledge-base crawls, workflow steps, new kinds of usage)). |
group_by | query | string | One or two of day, category and label, comma-separated (default category). units and unit are filled only with label. |
Answers 200 with UsageReport. Errors use the error envelope; common codes: balance and compliance, every request.
GET /v1/usage/events
Section titled “GET /v1/usage/events”List charges one by one, newest first.
Every charge in the window, newest first, with its category, label, credits and the conversation, agent and campaign it was for. Same from, to and category as GET /v1/usage: pass the from and to it echoed to read the same rows, and pass both to walk a fixed set (a default window is resolved again on every page). Any key of the workspace.
Parameters
| name | in | type | description |
|---|---|---|---|
from | query | string | Start of the window, inclusive: an ISO 8601 date (midnight UTC) or instant. Default: the start of the current billing cycle (cycle_start). |
to | query | string | End of the window, exclusive. Default: now. At most 400 days after from. To make /v1/usage, /v1/usage/events and /v1/usage/export answer the same rows, pass all three the from and to that /v1/usage echoed. |
category | query | stringphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | Only this category: phone (call minutes, attempts, voicemails and short calls), recording (call connection and call recording minutes, recording storage), speech (speech-to-text, text-to-speech and realtime voice), ai (AI model tokens and embeddings), messaging (SMS and MMS, and messages on chat channels (Telegram, Messenger, Instagram, LINE, Slack, Discord)), whatsapp (WhatsApp conversation and platform fees), email (email sent), numbers (phone number rental), other (anything else (knowledge-base crawls, workflow steps, new kinds of usage)). |
limit | query | integer 1–200 | Page size, 1 to 200 (default 50). |
after | query | string | The previous page’s next_cursor. |
Answers 200 with UsageEventList. Errors use the error envelope; common codes: balance and compliance, every request.
GET /v1/usage/export
Section titled “GET /v1/usage/export”Download the charges as CSV.
The rows of GET /v1/usage/events for the same from, to and category, as one CSV file (recorded_at,category,label,units,unit,credits,conversation_id,agent_id,campaign_id), newest first. At most 250,000 rows: over that the export is refused before any byte (400 export_too_large), never cut short in the file. One export at a time per workspace. If the connection is cut mid-file, the body is incomplete: compare the row count to events from GET /v1/usage. Text cells that start with =, +, - or @ get a leading '. Any key of the workspace.
Parameters
| name | in | type | description |
|---|---|---|---|
from | query | string | Start of the window, inclusive: an ISO 8601 date (midnight UTC) or instant. Default: the start of the current billing cycle (cycle_start). |
to | query | string | End of the window, exclusive. Default: now. At most 400 days after from. To make /v1/usage, /v1/usage/events and /v1/usage/export answer the same rows, pass all three the from and to that /v1/usage echoed. |
category | query | stringphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | Only this category: phone (call minutes, attempts, voicemails and short calls), recording (call connection and call recording minutes, recording storage), speech (speech-to-text, text-to-speech and realtime voice), ai (AI model tokens and embeddings), messaging (SMS and MMS, and messages on chat channels (Telegram, Messenger, Instagram, LINE, Slack, Discord)), whatsapp (WhatsApp conversation and platform fees), email (email sent), numbers (phone number rental), other (anything else (knowledge-base crawls, workflow steps, new kinds of usage)). |
Answers 200 (text/csv) with the file. Errors use the error envelope; common codes: balance and compliance, every request.
GET /v1/compliance
Section titled “GET /v1/compliance”Read the outbound compliance acknowledgment.
Whether the workspace accepted the current outbound compliance acknowledgment, its text and its current_version. A workspace’s first campaign start needs it (409 outbound_compliance_required). Any key of the workspace.
Answers 200 with OutboundCompliance. Errors use the error envelope; common codes: balance and compliance, every request.
POST /v1/compliance/accept
Section titled “POST /v1/compliance/accept”Accept the outbound compliance acknowledgment.
Accepts the text GET /v1/compliance returned, for the whole workspace, as the key’s owner. Owners and admins only. Send the current_version you read, so you accept the text you were shown. Accepting again changes nothing: the first acceptance (who and when) is kept.
Request body: ComplianceAccept.
Answers 200 with OutboundCompliance. Errors use the error envelope; common codes: balance and compliance, every request.
Objects
Section titled “Objects”Balance
Section titled “Balance”| field | type | description |
|---|---|---|
object | string, required always balance | |
credits | number, required | Credits the workspace holds. paid_credits + bonus_credits adds up to this (0 when it is 0 or below) whenever both are known. |
paid_credits | number or null, required | The part you bought or were granted; it never expires. Null when we could not read the breakdown just now. |
bonus_credits | number or null, required | The part included with this billing period, used first; it expires at bonus_expires_at. Null when we could not read the breakdown just now. |
bonus_expires_at | string or null, required | When bonus_credits expire (ISO 8601), or null. |
pending_credits | number, required | This period’s usage that is not yet taken off credits. |
available_credits | number, required | credits minus pending_credits, never below 0: what you can still spend now. A send or a campaign that needs more is 402 insufficient_credits. |
suspended | boolean, required | True when sends and calls are refused (402 workspace_suspended). |
suspended_reason | string or null, requiredcredit_exhausted, subscription_past_due, subscription_canceled, no_billing_record | Why the workspace is suspended; null when it is not. |
tier | integer, required | What the account may do: 0 no card, 1 a card on file, 2 subscribed. A send that needs a card is 402 billing_not_eligible at tier 0. |
has_payment_method | boolean, required | |
auto_recharge_disabled | boolean, required | True when automatic top-up was switched off after three failed charges. Turn it back on in the dashboard under Settings, Billing. |
plan | object or null, required | The subscription plan, or null with none. |
plan.id | string, required | |
plan.name | string, required | |
plan.renews_at | string or null, required | When the plan renews (ISO 8601), or null. |
updated_at | string or null, required | When the balance was last read from the billing system (ISO 8601): at most about 5 minutes before the request. Null when it never was. |
Example: see Credits and balance.
UsageReport
Section titled “UsageReport”| field | type | description |
|---|---|---|
object | string, required always usage_report | |
from | string, required | The window’s start, inclusive, as read (ISO 8601 UTC, microseconds). |
to | string, required | The window’s end, exclusive, as read (ISO 8601 UTC, microseconds). |
cycle_start | string, required | The current billing cycle’s start (the default from) (ISO 8601 UTC, microseconds). |
cycle_end | string or null, required | When the current billing cycle ends (ISO 8601), or null when the workspace has no billing period (the cycle is then the last 30 days). |
category | string or null, requiredphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | The category filter, or null. |
group_by | array of string, required each day, category, label | |
total_credits | number, required | Credits charged in the window (rounded to 4 decimals). The groups’ credits add up to it, give or take the rounding of each group. |
events | integer, required | Charges in the window: the rows /v1/usage/events and /v1/usage/export answer for the same from, to and category. |
groups | array of UsageGroup, required | Day ascending, then credits descending. At most 5,000 (400 too_many_groups above). |
Example: see Usage and spend.
UsageGroup
Section titled “UsageGroup”| field | type | description |
|---|---|---|
day | string or null, required | The UTC day (YYYY-MM-DD) when group_by has day, else null. A day with no usage has no group. |
category | string or null, requiredphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | When group_by has category, else null. |
label | string or null, required | What was charged, in words (SMS outbound (US), AI Tokens (input)), when group_by has label, else null. New labels appear as we bill new things. |
credits | number, required | Credits charged, rounded to 4 decimals. |
units | number or null, required | How much was used, in unit. Only when group_by has label and the label has one unit; null otherwise (3 messages and 3 minutes are not 6 of anything). |
unit | string or null, required | What units count: message, minute, 1k_tokens, 1k_chars, number_month, … (new values appear). Null with units. |
events | integer, required | How many charges the group adds up. |
{ "day": null, "category": "phone", "label": null, "credits": 0.83, "units": null, "unit": null, "events": 1}UsageEventList
Section titled “UsageEventList”| field | type | description |
|---|---|---|
object | string, required always list | |
data | array of UsageEvent, required | |
has_more | boolean, required | |
next_cursor | string or null, required | Pass as after for the next page; null on the last. |
Example: see Credits and balance.
UsageEvent
Section titled “UsageEvent”| field | type | description |
|---|---|---|
id | string, required | The charge’s id (UUID). |
object | string, required always usage_event | |
recorded_at | string, required | When it was charged (ISO 8601 UTC, microseconds). |
category | string, requiredphone, recording, speech, ai, messaging, whatsapp, email, numbers, other | What the credits went on: phone (call minutes, attempts, voicemails and short calls), recording (call connection and call recording minutes, recording storage), speech (speech-to-text, text-to-speech and realtime voice), ai (AI model tokens and embeddings), messaging (SMS and MMS, and messages on chat channels (Telegram, Messenger, Instagram, LINE, Slack, Discord)), whatsapp (WhatsApp conversation and platform fees), email (email sent), numbers (phone number rental), other (anything else (knowledge-base crawls, workflow steps, new kinds of usage)). |
label | string, required | What was charged, in words. |
units | number, required | How much was used, in unit. |
unit | string or null, required | What units count, or null when unknown. |
credits | number, required | Credits charged (4 decimals). |
conversation_id | string or null, required | The conversation it was for (UUID, as GET /v1/conversations/{id} takes), or null. |
agent_id | string or null, required | The agent (ag-…), or null. |
campaign_id | string or null, required | The campaign (its UUID, as a call’s campaign_id), or null. |
Example: see Credits and balance.
OutboundCompliance
Section titled “OutboundCompliance”| field | type | description |
|---|---|---|
object | string, required always outbound_compliance | |
accepted | boolean, required | True when the current text is accepted. Until then a campaign start is 409 outbound_compliance_required (a preview reports the same code); drafts are not gated. |
version | string or null, required | The version this workspace accepted last, or null if none. |
current_version | string, required | The version of attestation: send it to POST /v1/compliance/accept. |
attestation | string, required | The text an owner or admin accepts. |
accepted_at | string or null, required | When version was accepted (ISO 8601), or null. |
Example: see Accept the outbound compliance acknowledgment.
ComplianceAccept
Section titled “ComplianceAccept”| field | type | description |
|---|---|---|
version | string, required ≥ 1 chars | The current_version you read from GET /v1/compliance: you accept the text you were shown. |
{ "version": "2026-09-01"}