Guides
.md ↗

Usage

What completed generations meter, and reading your key’s running totals from GET /v1/usage.

What completed generations meter

Each completed JSON generation response carries a usage object — the metered quantities for that call. SSE sends it in the terminal end event, and WebSocket sends it in responseDone. Validation, auth, and backend-error responses do not carry usage:

json
{ "usage": { "input_chars": 42, "input_audio_seconds": 6.5, "output_audio_seconds": 3.2 } }
FieldMeaning
input_charsCharacters of input text billed for the request.
input_audio_secondsSeconds of audio you supplied (spoken history / reference clips in converse).
output_audio_secondsSeconds of audio generated for you.

Log these on your side if you want per-request attribution — the API's own accounting is keyed to your API key, not to your users.

A cancelled WebSocket response still reports the partial output_audio_seconds produced before cancellation, but its input fields are zero and nothing is added to your durable totals. Those inputs carry forward to the next completed response.

Your usage totals

GET /v1/usage returns durable totals for the key making the request. Without parameters it answers with the key's lifetime usage; totals survive deploys and restarts.

bash
curl -s https://api.kalpalabs.ai/v1/usage -H "Authorization: Bearer $KALPA_API_KEY"
json
{
  "key_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "requests": 1284,
  "input_chars": 91230,
  "input_audio_seconds": 411.0,
  "output_audio_seconds": 3120.5,
  "first_request_ts": 1748600000.0,
  "last_request_ts": 1751500000.0
}

key_id is the key's non-secret identifier (it's what appears in our logs — the secret itself never does). first_request_ts / last_request_ts are the Unix times, in seconds, of the key's first and most recent billed requests — absent until the first one.

requests counts completed generation events — not every HTTP request, validation failure, backend failure, or cancelled stream. Events are ingested asynchronously, so a just-completed generation can take a few seconds to appear in the totals.

Filtering by time

start_time and end_time (ISO 8601; naive timestamps are read as UTC; end_time is exclusive) restrict the totals to a window. Usage is accounted in hourly buckets, so the effective window snaps outward to hour boundaries and is echoed back — the response below covers 10:00–13:00 even though the request asked for 10:30–12:15:

bash
curl -s "https://api.kalpalabs.ai/v1/usage?start_time=2026-08-01T10:30:00Z&end_time=2026-08-01T12:15:00Z" \
  -H "Authorization: Bearer $KALPA_API_KEY"
json
{
  "key_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "requests": 3,
  "input_chars": 9,
  "input_audio_seconds": 0.0,
  "output_audio_seconds": 4.0,
  "start_time": "2026-08-01T10:00:00Z",
  "end_time": "2026-08-01T13:00:00Z"
}

Either bound may be omitted: only start_time means "since then", only end_time means "up to then". Windowed answers carry no first_request_ts/last_request_ts. For invoicing-grade reports or finer-grained breakdowns, write to hello@kalpalabs.ai.