Reference

Usage & billing

Reconcile token usage, request cost, balances, and asynchronous settlement.

On this page

This page is for developers and finance operators reconciling API responses with key balances and request logs.

Usage and cost authority#

Response bodies are passed through. Token fields depend on the protocol and upstream API. When an OpenAI-compatible response includes a finite non-negative usage.cost, that upstream-reported value is the charge authority. Otherwise the billing worker uses its local price table. Reasoning and thinking tokens are charged as output tokens.

For OpenAI-compatible prompt caching, usage.cost already reflects any upstream cache discount. Clients do not need to calculate a separate discount from cached-token fields.

JSONSyntax highlighted
{"usage":{"prompt_tokens":120,"completion_tokens":30,"total_tokens":150,"cost":0.00042}}

If no price can be found, the request can be logged as unpriced for later reconciliation. Binary responses without usage, such as speech audio, can use a request-text estimate that is marked as estimated in the cost breakdown.

Balance and allocation#

Read a key's balance projection with authenticated GET /v1/balance:

BashSyntax highlighted
curl https://api.clssai.com/v1/balance \
  -H "Authorization: Bearer $CLSSAI_API_KEY"
JSONSyntax highlighted
{
  "object": "balance",
  "key": "sk-...abc123",
  "identity": "account",
  "remaining_usd": 2.25,
  "limit_usd": 2.5,
  "recharge_usd": 2,
  "credit_usd": 1,
  "allocated_usd": 0.5,
  "consumption_usd": 0.25,
  "grace_usd": 0.1,
  "expires_at": null,
  "expired": false,
  "disabled": false,
  "settlement": "asynchronous",
  "note": "consumption_usd settles asynchronously and can lag recent requests by minutes; shared child Keys report the parent balance."
}

identity is one of account, allocated_child, or shared_child. An allocated child has its own funded balance. A shared child returns its parent's balance but never exposes the parent key, and its usage is billed to that parent.

The key limit is recharge_usd + credit_usd - allocated_usd, and remaining_usd = max(limit_usd - consumption_usd, 0). Allocation is the amount assigned to independently funded child keys. expires_at is null for a key with no expiry, otherwise a Unix timestamp in seconds. Expired or disabled keys still receive a 200 response from this balance endpoint, with expired or disabled set to true; callers must inspect those fields.

Each key has a small grace_usd amount that can allow a request at the admission boundary. grace_usd is a small request-admission allowance, not spendable balance; do not include it in remaining_usd.

Manage balances at Credits (sign-in required).

Settlement is asynchronous#

Requests enter a billing queue without waiting for settlement. consumption_usd, remaining_usd, and aggregate consumption can therefore lag request completion by several minutes. The response reports settlement: "asynchronous"; do not expect an inference response and the balance projection to change atomically.

Reconcile request logs#

The key appears in the management path, so construct this URL only in trusted server tooling and never log it. The range, page, and page_size query parameters select the time window, result page, and requested rows per page.

BashSyntax highlighted
curl "https://api.clssai.com/key/$CLSSAI_API_KEY/logs.json?range=24h&page=1&page_size=30" \
  -H "Content-Type: application/json"

The top-level JSON object contains:

FieldMeaning
errorError value reported by the endpoint.
rangeEffective time-window selection.
sourceLog source reported for the result set.
pageCurrent result page.
page_sizeEffective number of rows per page.
totalTotal number of matching rows.
total_pagesTotal number of result pages.
window_startStart of the selected time window.
window_endEnd of the selected time window.
itemsArray of request-log rows.

Each items[] row contains:

FieldMeaning
timeRequest time.
providerProvider recorded for the request.
statusRecorded status label.
status_codeRecorded HTTP status code.
cachedWhether this response was returned from an upstream gateway cache.
modelModel recorded for the request.
tokens_inRecorded input-token count.
tokens_outRecorded output-token count.
costRecorded request cost.
countCount value reported for the row.
duration_msRecorded request duration in milliseconds.
upstream_idUpstream identifier recorded for the request.
sourceSource recorded for the request.

For native Anthropic requests, tokens_in and tokens_out omit the cache_creation_input_tokens and cache_read_input_tokens counters, so those two logged token values alone cannot be used to reproduce cost.

Free models and the daily pool#

A complete model ID ending in :free has zero local token prices, unless an upstream-reported cost overrides them. Free users also share a separate global daily pool. When that pool is exhausted, the gateway returns 429. These are distinct limits.

Common mistakes#

  • Do not assume settlement is real-time.
  • Do not subtract only consumption; account for recharge, credit, and allocated amounts.
  • Do not assume a 200 balance response means the key is active; inspect expired and disabled.
  • Do not add grace_usd to available balance.
  • Do not publish or log a key-bearing management URL.
  • Preserve the complete author/model:free or author/model:batch ID.
  • Include /v1 in OpenAI SDK base URLs, omit it from the Anthropic SDK base URL, and call from a server.
  • Check empty streaming choices arrays and retain cf-ray for inference tracing.
Need a hand?

Find answers to common questions or diagnose a failed request.

Frequently asked questions →Troubleshoot errors →