Credits
GET /api/orgs/{org_id}/credits
Section titled “GET /api/orgs/{org_id}/credits”Get Credits
Balance, floor, period, plan and resolved entitlements for this org.
Read enforced before anything else. It is the only field that says
whether a balance means anything here, and it is false in three quite
different situations that must all render as “credits do not gate this org”
rather than as a zero: an enterprise plan (the counter runs and never
stops anything), an org with no subscription row, and credits switched off
platform-wide. In all of them balance is null.
Never raises for an unprovisioned org. UNSUBSCRIBED resolves to
plan = null with the deny-everything entitlement set and a 200 — the
permissive direction every earlier PR takes with that sentinel, because a
customer looking at a broken billing state is better served by an empty
panel than by a 500 or a frozen account.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | CreditsResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/credits/breakdown
Section titled “GET /api/orgs/{org_id}/credits/breakdown”Get Credit Breakdown
Credits burned in a window, grouped by metric, by agent and by chat.
Burns only. Grants, expiries and adjustments are excluded because the question is “what consumed my credits”, and folding a grant into that makes the totals meaningless. Credits are reported positive for the same reason: the ledger stores a burn as a negative delta, but a consumption report reads as “this chat used 4,120 credits”, not “-4,120”.
The agent and chat dimensions are not on credit_ledger — a burn is keyed
to a usage_events row, and that is what carries chat_id. So both
groupings join through the event and then to agent_chats; work that
belongs to no chat (a title generation, a scheduled sweep) buckets under
"(none)" rather than vanishing, because credits it burned are still
credits the customer paid.
Each grouping is capped at the top {limit} rows by spend. truncated says
when that bit, so a panel can offer the full statement instead of implying
these are all the consumers there were.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| days | query | integer | no | Window size in days, ending now. |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | BreakdownResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/credits/ledger
Section titled “GET /api/orgs/{org_id}/credits/ledger”List Credit Ledger
The org’s credit statement, newest first, in the shared page envelope.
Every row carries a projected receipt, never the stored meta: the
burn receipt embeds our provider cost and the per-model multiplier verbatim,
and neither is a fact about the customer’s work. What survives is what
answers their question — which model ran, how the charge was computed, and
how much was metered.
kind is validated against the known set so a typo is a 422 rather than a
silently empty statement, which is indistinguishable from “you have never
spent anything”. metric is deliberately not validated the same way:
the metric vocabulary grows without a migration, and rejecting an unknown
one would break a client the day a new metric ships.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| kind | query | string | no | Filter to one ledger kind: grant | burn | adjustment | purchase | expiry. Omit for every kind. |
| limit | query | integer | no | Max rows to return (1-100). Omit to return every row. |
| metric | query | string | no | Filter to one usage metric (burn rows only carry one). Omit for every metric. |
| offset | query | integer | no | Rows to skip — pass the previous response’s next_offset. |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | Page_LedgerEntry_ |
| 422 | Validation Error | HTTPValidationError |