Usage & balance
Track inference consumption, understand how cost is calculated, and handle billing-related errors and retries correctly.
Usage endpoint
https://inferenceapi.wethinkdigital.solutions/v1/usageAggregate request and token usage for a time window, grouped by day or model.
| Field | Type | Description |
|---|---|---|
| from | RFC 3339 | Optional. Inclusive start of the reporting window. Defaults to 30 days ago. |
| to | RFC 3339 | Optional. Inclusive end of the reporting window. Defaults to now. |
curl "https://inferenceapi.wethinkdigital.solutions/v1/usage?from=2026-10-01T00:00:00Z&to=2026-11-01T00:00:00Z&group_by=day" \
-H "Authorization: Bearer sk_live_xxxxxxxx"{
"totals": {
"requests": 1284,
"inputTokens": 948201,
"outputTokens": 312940,
"costMicro": 18400200,
"upstreamCostMicro": 0
},
"series": [
{
"bucket": "2026-10-01",
"label": "2026-10-01",
"requests": 98,
"inputTokens": 70214,
"outputTokens": 23880,
"costMicro": 1384200
}
],
"byModel": [
{
"modelId": "model-pro",
"modelName": "Model Pro",
"requests": 912,
"inputTokens": 688120,
"outputTokens": 241000,
"costMicro": 14200100,
"upstreamCostMicro": 0
}
]
}Usage is eventually consistent for the current day. Historical windows are stable and can be cached on your side. Never infer your balance from locally accumulated usage — query the balance endpoint.
Balance endpoint
https://inferenceapi.wethinkdigital.solutions/v1/balanceCurrent available balance in micro-dollars, normalized to USD.
curl https://inferenceapi.wethinkdigital.solutions/v1/balance \
-H "Authorization: Bearer sk_live_xxxxxxxx"{
"balanceMicro": 18420000,
"heldMicro": 0,
"currency": "USD"
}A balance check is advisory. Concurrency can change the balance between your check and the inference request. The authoritative check happens at request admission and returns 402 insufficient_credit when funds are not sufficient.
Cost semantics
Pricing is published per million tokens for each model. A request has separate input and output rates, and some models expose cached read or cache write rates.
| Component | Unit | Notes |
|---|---|---|
| Input tokens | per 1M tokens | Prompt and context tokens processed by the model. |
| Output tokens | per 1M tokens | Generated tokens, including streaming output. |
| Cached read | per 1M tokens | Applied only when the model reports cache support and a cached read occurs. |
| Cached write | per 1M tokens | Applied only where the model supports cache writes. |
input_cost = input_tokens / 1_000_000 * input_rate
output_cost = output_tokens / 1_000_000 * output_rate
cost = input_cost + output_cost (+ cached components where applicable)Accounting uses integer micro-dollars (1 USD = 1,000,000 micro). The response usage object reports tokens; the console request ledger and usage API report the settled micro-dollar cost. Rounding is applied at the ledger boundary, not per event.
Prices can change
GET /v1/models at startup or with a short cache TTL for accurate cost estimates.Errors & status codes
Errors always return JSON in a single envelope. Capture error.requestId in logs; never log the token.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after the indicated interval.",
"requestId": "req_01J8Z9..."
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed JSON, missing required field, or unsupported parameter. |
| 401 | unauthorized | Token is missing, malformed, expired, or revoked. |
| 402 | insufficient_credit | Available balance cannot cover the maximum expected cost of the request. |
| 403 | model_unavailable | The model is not activated for inference. |
| 404 | model_not_found | The requested model ID is not in the catalog. |
| 409 | idempotency_conflict | The Idempotency-Key was already used for another request. |
| 429 | rate_limited | A rate limit was exceeded. Honor the Retry-After header. |
| 500 | internal_error | The request could not be completed. Retry with backoff and report the requestId. |
Retry guidance
- Retry
429and500with exponential backoff and jitter. HonorRetry-Afterwhen present. - Do not retry
400,401,402, or404without changing the request or credential. - For streaming requests, a connection can close after output begins. Treat partial output as consumed and reconcile using the usage ledger.
Rate limits
Limits are applied per token: authentication endpoints are limited per IP address and inference endpoints per account. When a limit is exceeded the API returns 429 with a Retry-After header (seconds):
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{"error":{"code":"rate_limited","message":"Too many requests. Please slow down.","requestId":"..."}}Sudden bursts and concurrent streaming requests can hit limits sooner than a request-per-second budget alone suggests; design a queue for high concurrency.
Idempotency
Send an Idempotency-Key header (up to 128 characters: letters, digits, -, _, . or :) on a billable POST to make duplicate submissions detectable.
curl https://inferenceapi.wethinkdigital.solutions/v1/chat/completions -H "Authorization: Bearer sk_live_xxxxxxxx" -H "Idempotency-Key: 3f7c60b1-8b2a-4fcb-bdb6-8a8e2d28f201" -H "Content-Type: application/json" -d '{
"model": "model-pro",
"messages": [{ "role": "user", "content": "Generate a release title." }]
}'Keys are scoped to your account. Reusing a key returns 409 idempotency_conflict and never charges a second time. The platform does not replay the original response, so use a new key for a deliberate retry and inspect the request history to confirm whether the first attempt completed.
Do not retry blind
/v1/usage before retrying a billable call.