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.
| Page | Use it to |
|---|---|
| Overview | Follow spend, success rate and latency over time, by channel group and by model |
| Logs | Inspect each request: tokens, charge, timing, errors |
| API keys | Compare lifetime spend and last use across keys |
| Billing | Check 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.
| Number | What it tells you |
|---|---|
| Spend | Amount charged in the period, and how many requests made it up |
| Success rate | Share of requests that succeeded, and how many failed |
| P95 TTFT | Time to first token at the 95th percentile, with the average |
| Throughput | Average output tokens per second |
| Cache hit rate | Share of input tokens served from the prompt cache |
| Balance | What'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.
| Column | Contents |
|---|---|
| Time | Start of the request. Hover to see the exact timestamp. |
| Model | Model id. A ⇢ marks a streamed request. |
| Group | Channel group that served it |
| Status | HTTP status you received |
| In | Input tokens, counting tokens written to the prompt cache |
| Cached | Input tokens read from the prompt cache |
| Out | Output tokens, counting reasoning tokens |
| TTFT | Time to first token, for streamed requests |
| Tok/s | Output tokens per second |
| Charge | What 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.
| Value | Meaning |
|---|---|
new | The conversation's first request |
sticky | A later turn that stayed on its conversation's channel, so the cache could be reused |
explicit | Grouped by a session id your client sent |
none | Nothing 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.