Providers · 04 macOS only

Grok (xAI)

Halton Meter's xAI adapter meters api.x.ai across both the OpenAI-shape /v1/chat/completions and the Anthropic-shape /v1/messages paths.

macOS 12+ · Python 3.11+ Reading time 2 min Updated May 11, 2026

The xAI adapter (daemon/halton_meter/adapters/xai.py) owns the host api.x.ai. It meters both API surfaces xAI exposes:

PathWire shapePurpose
/v1/chat/completionsOpenAI-compatibleThe default surface most clients use
/v1/messagesAnthropic-compatibleDrop-in for Anthropic SDK clients

The two paths share request/response shapes with their progenitors. The xAI adapter delegates parsing to the shape it sees and writes the row with provider = "xai". Reports treat both as one provider.

Captured fields

  • provider = "xai"
  • model — from the response (e.g. grok-4, grok-3-mini)
  • input_tokens, output_tokens — from the usage block in whichever wire shape the response carried
  • cost_usd_minor_units — against the active rate card

thinking_tokens is non-zero for Grok-4 reasoning calls when xAI returns it under usage.reasoning_tokens. cache_* columns are zero — xAI does not currently expose prompt-cache accounting in its usage block.

Streaming

Both paths support stream=true. The adapter buffers, reads the final usage event, writes the row. Truncated streams set tokens_complete = false.

Tools that route through this adapter

ToolPath
OpenAI SDK pointed at https://api.x.ai/v1/v1/chat/completions
Anthropic SDK pointed at https://api.x.ai/v1/v1/messages
curl https://api.x.ai/v1/...Either
Cursor / Windsurf configured with an xAI base URL/v1/chat/completions

Verifying capture

~ — verify xAI capture (OpenAI shape)
$ halton-meter run -- curl -sS https://api.x.ai/v1/chat/completions \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{"model":"grok-3-mini","messages":[...]}'

$ halton-meter report --since 5m --by model

Error classification

xAI’s API is OpenAI-compatible verbatim, including the error envelope shape. The daemon routes provider=xai through the OpenAI classifier without a separate adapter, so the OpenAI table is the mapping — including the HTTP 429 insufficient_quotaauth split. Shipped in v0.3.0.

HTTP status is the primary signal; the error.type string match is best-effort, since xAI does not publish the exact strings. If post-launch traffic shows xAI diverging (e.g. rate_limit_exceeded versus rate_limit_error), a thin alias map is added rather than forking the adapter. For the bucket definitions, see Error classification.

Host matching

api.x.ai is matched by exact equality. The legacy api.grok.x.ai host is not in scope.