Documentation

Two endpoints, one bearer token. Nothing sits in your request path.

Authentication

Create a key in Settings and send it as a bearer token. Keys are stored hashed — the plaintext is shown once at creation. A key belongs to one workspace and can ingest events and check budgets.

Authorization: Bearer tk_live_xxx

POST /api/public/ingest

Records one model call. Costs are computed server-side from your price book, so you never send money amounts. Returns 202 with the priced event.

curl -X POST https://toknly.in/api/public/ingest \
  -H "Authorization: Bearer tk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1",
    "input_tokens": 1200,
    "output_tokens": 450,
    "reasoning_tokens": 0,
    "team": "platform",
    "feature": "chat",
    "customer": "Acme Corp",
    "environment": "production",
    "latency_ms": 820,
    "status": "success"
  }'
FieldTypeNotes
modelstringRequired. Matched against your price book.
input_tokensnumberRequired.
output_tokensnumberRequired.
reasoning_tokensnumberOptional, defaults to 0. Priced separately.
providerstringOptional. Inferred from the model name when omitted.
team / feature / customerstringOptional attribution tags.
environmentstringproduction or staging. Defaults to production.
request_idstringOptional. Groups agent-loop calls together.
latency_msnumberOptional.
statusstringsuccess or error. Defaults to success.
event_timeISO 8601Optional. Defaults to now — use it for backfills.
metadataobjectOptional free-form JSON.

POST /api/public/budget-check

Call this before an expensive request. Returns a verdict of allow, warn or block based on your budgets and the projected cost of the call.

curl -X POST https://toknly.in/api/public/budget-check \
  -H "Authorization: Bearer tk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1",
    "estimated_input_tokens": 50000,
    "estimated_output_tokens": 8000,
    "team": "platform",
    "feature": "agent-loop"
  }'

Node.js example

async function logUsage(event) {
  await fetch("https://toknly.in/api/public/ingest", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.TOKENLEDGER_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(event),
  });
}

const completion = await openai.chat.completions.create({ /* ... */ });
await logUsage({
  model: completion.model,
  input_tokens: completion.usage.prompt_tokens,
  output_tokens: completion.usage.completion_tokens,
  reasoning_tokens: completion.usage.completion_tokens_details?.reasoning_tokens ?? 0,
  feature: "chat",
  customer: currentAccount.name,
});

Error codes

  • 401 — missing or invalid API key.
  • 402 — plan limit exceeded past the 7-day grace window. Existing data stays readable; upgrade to resume ingestion.
  • 422 — payload failed validation; the response lists the offending fields.
  • 500 — we could not record the event. Safe to retry.

Plan limits

Limits are on tracked monthly AI spend, not on event count. When you go over, ingestion continues for 7 days with an in-app banner and an email. After that, new events are rejected with a 402 — dashboards and history always stay readable.