tokenstat
tokenstat

Read API

Your own numbers, as JSON

The CLI answers these questions on your device, and its MCP server lets an agent ask them. Use this API when the client is elsewhere, such as a dashboard, scheduled job, status page, or remote agent.

Legend Read-only, scoped to your own account. Create a token in settings.

Authentication

Send a bearer token in the Authorization header. Tokens are shown once when created and stored as hashes. No endpoint can return a token after creation. Revocation takes effect on the next request.

curl -H "Authorization: Bearer tsk_…" \
  https://tokenstat.ai/api/v1/usage

Session cookies are refused on these routes, so a logged-in browser tab cannot be tricked into making an authenticated call on your behalf. A read token cannot sync. The token minted by tokenstat login carries both scopes so the desktop app's account view and the CLI's uploads share one credential.

Usage rows

GET/api/v1/usage

Counters, summed and grouped however you ask. Everything the hosted side knows comes from the CLI's sync payload, so this is the same shape: tokens, cache reads and writes, and a request count.

ParameterMeaning
group_byday (default), model, source, project, or machine.
fromYYYY-MM-DD, inclusive. Clamped to your plan's history window.
toYYYY-MM-DD, inclusive.
formatjson (default) or csv.
{
  "group_by": "day",
  "window": { "from": null, "to": null },
  "rows": [
    {
      "day": "2026-07-28",
      "input": 1300,
      "output": 600,
      "cache_read": 4000,
      "cache_write": 200,
      "tokens": 6100,
      "events": 4
    }
  ]
}

project is the opaque HMAC your device computed, or null for unattributed work. The server cannot convert it back to a path, so it returns the value unchanged. events counts requests, not sessions.

Profile document

GET/api/v1/profile

The same document your public page renders from, published or still private: totals, cache split, per-model and per-harness breakdowns, the daily series, the activity timeline, streaks, busiest day, peak hour, and list-rate cost. Use this when you want what the page shows without re-deriving it from rows.

{
  "handle": "yourname",
  "since": "2026-06-17",
  "updated": "2026-07-30",
  "totals":  { "tokens": 1234567, "events": 4321, "activeDays": 44 },
  "cache":   { "read": 0.83, "write": 0.05, "output": 0.10, "fresh": 0.03 },
  "models":  [ { "id": "claude-sonnet-4-5", "tokens": 987654 } ],
  "sources": [ { "id": "claude_code", "tokens": 876543 } ],
  "daily":   [ { "d": "2026-07-30", "tokens": 23500000 } ]
}

Shown abridged. Fields are added over time and never repurposed: if a key means something different, it gets a different name. Returns 404 no_data until a device has synced.

Sync schema

GET/api/v1/schema

No token, no account, no tier. This is the schema the server accepts from the CLI, published so clients can inspect exactly what the server accepts. Unknown fields are rejected, and adding a field requires a visible schema change. It also carries the per-plan sync intervals.

curl https://tokenstat.ai/api/v1/schema

Errors

Every error is JSON with an error code and a message written for a person. The code is the part to branch on.

StatusCodeMeans
400invalid_requestA parameter is not one of the accepted values.
401unauthorizedMissing, malformed, unknown, or revoked token.
402upgrade_requiredValid token, but the plan does not include the read API.
403forbiddenThe token is real but lacks the data:read scope.
404no_dataNothing has been synced to this account yet.
429rate_limitedOver 60 requests in a minute. Retry-After says when.

A lapsed plan returns 402, not 403. The token remains valid and works again when the plan renews.

Limits

  • 60 requests a minute per token.
  • Your own data only. There is no endpoint that reads another account, public profile or not.
  • Read-only. Nothing here can write, and nothing here can sync. Uploading is the CLI's job and needs a different token entirely.
  • The history window is your plan's window. Asking for an earlier from gets you the earliest date your plan covers, not an error.
  • No webhooks or streaming.

The CLI and the desktop app are free to use and work offline with no account at all. If everything you want is on one device, tokenstat export and the MCP server already do this locally, for free, and you should use those instead.