Kalpa LabsDocs
DashboardGet API key
Guides

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.

Shell
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,
  "organization": {
    "org_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    "output_audio_seconds": 4890.2,
    "allowance_seconds": 60000.0,
    "allowance_expires_at": "2027-01-11T03:43:35Z",
    "exhausted": false
  }
}

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.

organization is your organization's generated audio against its allowance. All keys of an organization share one allowance. output_audio_seconds is the audio generated so far by all of its keys, allowance_seconds the total it may generate (absent if there is no cap), allowance_expires_at when the allowance expires (absent if it never expires), and exhausted whether generation currently returns 402. A key refused with 402 can read why here even when its own totals are small.

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:

Shell
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 and no organization block (the allowance is a lifetime fact). For invoicing-grade reports or finer-grained breakdowns, write to hello@kalpalabs.ai.