halfoff.devDocs
Get a key
Account

Usage & logs

See what each Half Off Dev key spends, read per-request tokens, latency and errors, trace calls by request id, and reconcile your balance.

Paying half price only helps if you can see where the money goes. Half Off Dev records every model request your keys make, usually within a few seconds of it finishing, and gives you four places to look.

PageUse it to
OverviewFollow spend, success rate and latency over time, by channel group and by model
LogsInspect each request: tokens, charge, timing, errors
API keysCompare lifetime spend and last use across keys
BillingCheck your balance, credits and daily spend

Overview dashboard#

Overview totals traffic from all your keys over the last 24 hours, 7, 30 or 90 days.

NumberWhat it tells you
SpendAmount charged in the period, and how many requests made it up
Success rateShare of requests that succeeded, and how many failed
P95 TTFTTime to first token at the 95th percentile, with the average
ThroughputAverage output tokens per second
Cache hit rateShare of input tokens served from the prompt cache
BalanceWhat's left, and how many keys are active

Under the totals you get spend and token charts, splits By channel group and By model, and an Error distribution that groups failed requests by error type. Time to first token and throughput come from streaming requests only.

Logs#

Logs shows your model requests newest first, 50 per page; Load more goes further back. Narrow the list by channel group, model, status (Succeeded or Failed) and, once you have several keys, by API key.

ColumnContents
TimeStart of the request. Hover to see the exact timestamp.
ModelModel id. A ⇢ marks a streamed request.
GroupChannel group that served it
StatusHTTP status you received
InInput tokens, counting tokens written to the prompt cache
CachedInput tokens read from the prompt cache
OutOutput tokens, counting reasoning tokens
TTFTTime to first token, for streamed requests
Tok/sOutput tokens per second
ChargeWhat you paid for it

Click a row to open its details: Request id, the Key used, the API format (anthropic, openai or gemini), total Latency, Cache write and Reasoning tokens, Cache hit rate, the Error type when it failed, and Affinity. At the bottom, Ask support about this request starts a support request with the id already filled in.

Affinity#

Affinity tells you whether a request was kept on the same channel as the rest of its conversation, which is what lets the prompt cache cut the cost of long chats. Prompt caching explains the savings.

ValueMeaning
newThe conversation's first request
stickyA later turn that stayed on its conversation's channel, so the cache could be reused
explicitGrouped by a session id your client sent
noneNothing to group it with

What gets logged#

  • Every request that got past the key and balance checks, whether it succeeded or failed. Failed ones show their status and error type, at a charge of $0.
  • Not logged, and never charged: requests turned away at the door. That covers a missing or invalid key, a body that isn't JSON, an unknown model, a model the key isn't allowed to use, an empty balance and a key over its rate limit. Your code gets the error directly.

Logs are kept for 90 days.

Request ids#

Each model response includes an x-halfoff-request-id header, for example req_3f9c1a7e5b2d4c6e8a0b1d2f. It's the same Request id you see in Logs. Errors carry one as well, including requests refused before they were logged (bad key, empty balance, unknown model), and support can trace those from the id alone.

Store the id next to your own records and send it along when you ask support about a call.

curl -sD - -o /dev/null https://halfoff.dev/v1/chat/completions \
  -H "Authorization: Bearer $HALFOFF_API_KEY" \
  -H "content-type: application/json" \
  -d '{"model": "gpt-6.1-sol", "messages": [{"role": "user", "content": "Reply with one word: ready?"}]}' \
  | grep -i '^x-halfoff'

The x-halfoff-group header on the same response names the channel group that served it.

Reconcile your charges#

Two things move your balance: credits raise it, requests lower it.

  • Credits: top-ups, redeemed codes and referral earnings, listed under Credit history on Billing.
  • Requests: every charged model request, in Logs.

To audit a single key, put its Spent figure on API keys next to its requests in Logs, filtered by that key.

Small gaps usually have one of these causes:

  • Charges land a few seconds late. A charge is recorded shortly after the request finishes, so a total read during a traffic spike can trail by a little.
  • A stream you cut off is billed for what was produced. If you close a stream before its final usage event, the output is billed from an estimate of the text already sent to you. See Streaming.
  • The Charge column is the final word. It's exactly what left your balance for that request. Per-token prices are on the model list.

Contact support#

Open Support and press New request. If your question is about one call, include its request id (req_…); from a row in Logs, Ask support about this request does this for you. Answers appear on the same page, and Support in the sidebar gets a badge when one arrives. Reply to add details, or mark the request resolved.