> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sempera.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Billing boundaries

> What the API never does with money, which usage and cost reads exist, and where plans and invoices are managed.

This page says what the Sempera API does and does not do with money, so an integration never has to guess. It repeats no price on purpose: the published plans are on the [pricing page](https://sempera.org/pricing/), and a number copied here could only drift out of date.

## The short version

* **The API never moves money.** No route charges a card, buys something, changes a plan, adds a credit or issues a refund.
* **Plans, payment methods, invoices and credit packs live in the Sempera App.** A workspace owner manages them there, through the payment provider the App uses.
* **A running agent is billed through its plan.** A fixed monthly fee and its phone number, with included minutes and overage. Credits never pay for a live call.
* **Building spends credits.** Assistant turns, simulations and evals, test voice calls and knowledge processing draw on the workspace's credit balance, which the API can read (below).
* **The gates that exist in the API protect spending; they are not payments.** They are listed below.

## What the API tells you

Four routes are as close to billing state as the API gets. The two organization reads are native and describe the organization only. The two `/v1/compat` reads belong to the Compatibility tag, which exists so clients shaped for other consoles can read the fields they expect, and they answer in the `{"data": ..., "errors": null}` envelope. All four are reads: none charges, changes a plan or sends anything. The first time anything asks, Sempera creates the workspace's default billing record (no payment processor attached, status `none`), so a first read of either `/v1/compat` route can add that one row; a second read changes nothing.

| Route | Scope | What it answers |
| - | - | - |
| `GET /v1/organizations` | `organizations:read` | The organizations you can see. Today every workspace is its own organization, the membership and billing umbrella ([Workspaces and organizations](https://docs.sempera.org/workspaces.md)). |
| `GET /v1/organizations/{organization_id}` | `organizations:read` | One of them, or `404 not_found`. |
| `GET /v1/compat/app/orgs/{uuid}/billing` | `organizations:read` | The workspace's `plan`, `status` and `billing_provider`. The balance and refill fields are `null`, because there is no prepaid balance. Another workspace's id answers `404 not_found`. |
| `GET /v1/compat/app/billing/customer` | `organizations:read` | The billing customer Sempera holds for the workspace, or `"customer": null` with `"has_payment_method": false` when there is none. Fields the payment provider keeps are `null`, never copied. |

`POST /v1/compat/app/pay/purchases` also exists for client compatibility. It creates no purchase and charges nothing: it answers an empty `purchases` list.

## Credits

Every workspace starts with 100 free credits, once. Credit packs are one-off purchases in the App, cost US dollars, and never expire: the prices are on the Buy credits page and the [pricing page](https://sempera.org/pricing/). What each action costs is in `costs` on the read below, so an integration never hard-codes it.

| Route | Scope | What it answers |
| - | - | - |
| `GET /v1/credits` | `organizations:read` | `balance`, `held`, `spent_total`, what each action costs (`costs`), the packs on sale (`packs`). The workspace is the credential's, never a parameter. |
| `GET /v1/credits/history` | `organizations:read` | Every grant, purchase, spend, refund and reversal, newest first. `limit` is 1 to 200; pass `next_before` as `before` for the next page. |

* **Reserve, then settle.** Credits are held when work starts, so a balance can dip by more than the work finally costs. What is not used comes back as a `refund` row. Work that fails is refunded in full. A hold whose work never reports refunds itself.
* **Empty stops building, and only building.** A refused action answers `402 credits_exhausted` with `needed`, `balance`, `debt` and, where buying can work, `buy_path`, and starts nothing. Agents already live keep answering and placing calls, whatever the balance.
* **A run does what its credits cover.** An eval holds up to 25 conversations and scores no more than it held; `left_unscored` says how many remain, and another run picks them up. A test voice call ends at the minutes held, with a spoken reason. Live calls have no such limit.
* **Publishing never spends on its own.** Checks after a publish are opt-in: the answer says what they would cost, and they run when you start them.
* \*\*`POST /v1/calls` spends no credits.\*\* Neither does `POST /v1/sessions`. Only a phone test (a call with `test`) and a spoken test in the App do. A test voice call also uses the plan's minutes and counts toward call limits, like any call, on top of its credits.
* **Not charged:** typed tests, the Builder, explaining a call and Speech Studio. The Assistant's daily token allowance stays as an abuse limit, separate from credits.
* **A refund takes its share of a pack back, and a dispute all of it.** What the balance cannot cover is recorded as `debt`, which stops building and buying until it is cleared. A won dispute clears it and restores the rest. The balance itself never goes below zero.
* **A workspace a provider bills cannot buy packs.** `can_buy` is false and `buy_note` says why; Sempera adds its credits.
* **TEST payments add no credits on a production service,** and TEST credits never carry into live.
* **One free grant per workspace.** A creator who already had one on a workspace now deleted starts the next at zero.

## Usage and cost you can see

* **In the App, not the API.** Settings, Usage shows this billing period's inbound and outbound calls and minutes. Every figure is an estimate of use, not an invoice. The plan's published figures sit beside it, no overage charge is worked out, and inbound and outbound minutes are not added together against the plan's included minutes ([Owner features in the App](https://docs.sempera.org/app-features.md)). Its daily chart reads the internal browser route `GET /api/workspaces/{workspace_id}/usage-series?days=30`, not a developer-key billing endpoint. Active workspace members may read 7, 14, 30 or 90 UTC calendar days, including the partial current day. The answer carries `available`, `days` (each with `day`, `calls`, `minutes`, `unmeasured_calls`), `as_of`, `timezone`, `is_invoice: false` and `basis_note`. Carrier/runtime duplicates count once; released outbound attempts, tests and previews do not count. A missing duration remains explicitly unmeasured, not a measured zero. Other workspaces and unauthenticated readers receive the same 404; invalid ranges receive 400; an unreadable meter receives 503, never a fabricated empty chart. All three internal usage reads (today, billing period and daily series) recheck the browser credential's workspace authorization and bind that target's database request context, independently of the session's last selected workspace. Developer API keys cannot use these browser routes.
* **The cost of a disposition before you publish it.** `POST .../dispositions/{id}/estimates` quotes the cost per call in US dollars, with its assumptions, and stores nothing. Publishing a disposition whose expected cost is above zero requires `acknowledgeEstimate: true`, so a cost cannot start by accident ([Dispositions](https://docs.sempera.org/dispositions.md)).
* **Not offered:** a cost metric. Metric alerts are computed only from records Sempera already keeps, and cost is not one of them ([Metric alerts](https://docs.sempera.org/alerts.md)).

## Limits that protect spending

* **Outbound call limits.** A workspace owner can cap the calls the workspace places per UTC hour and per UTC day. No cap is set by default, the platform may set a ceiling for every workspace, and the stricter one applies. `POST /v1/calls` over a cap answers `429 rate_limited` with `retry_after_s` and places nothing. If the cap cannot be read, it answers `503 service_unavailable` and places nothing ([Sessions and calls](https://docs.sempera.org/sessions-and-calls.md), [Owner features in the App](https://docs.sempera.org/app-features.md)).
* **Request rate limits** are 600 requests a minute per key and 60 a minute per address on routes that need no credential. They protect the service; they are not a quota tied to a plan ([Errors and limits](https://docs.sempera.org/errors-and-limits.md)).
* **Drafts cannot place real calls.** `POST /v1/calls` needs a published version, so a half-edited agent cannot ring a customer's phone ([Sessions and calls](https://docs.sempera.org/sessions-and-calls.md)).

## What stays outside the API

* **Choosing, changing or cancelling a plan**, adding or removing a payment method, and receiving an invoice.
* **Buying a phone number.** `POST /v1/phone-numbers` points a number you supply at an agent. No route searches for or buys one.
* **Paying anyone.** The payment provider delivers its own events to Sempera on a route you never call, under the provider's own signature ([Webhooks](https://docs.sempera.org/webhooks.md)).

If your integration needs a billing fact that is not here, ask the workspace owner to read it from the App, or write to [hello@sempera.org](mailto:hello@sempera.org). Do not infer it from the compatibility routes above, which report only what Sempera records.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.