xAI
Route your xAI API calls through AI SpendOps for automatic usage tracking and cost attribution.
Configuration
| Setting | Value |
|---|---|
| Route | /v1/xai/* |
| Upstream | https://api.x.ai |
| Auth header | Authorization: Bearer ... |
| Streaming usage | Auto-injected (stream_options.include_usage) |
SDK base URL
https://proxy.aispendops.com/v1/xai/v1
Example
curl https://proxy.aispendops.com/v1/xai/v1/chat/completions \
-H "Authorization: Bearer your-xai-key" \
-H "X-ASO-API-Key: aso_k_yourkey.secret" \
-H "Content-Type: application/json" \
-d '{"model":"grok-3","messages":[{"role":"user","content":"Hello"}]}'
Python SDK
xAI is OpenAI-compatible, so the OpenAI SDK works with a changed base URL:
from openai import OpenAI
client = OpenAI(
api_key="your-xai-key",
base_url="https://proxy.aispendops.com/v1/xai/v1",
default_headers={"X-ASO-API-Key": "aso_k_yourkey.secret"},
)
response = client.chat.completions.create(
model="grok-3",
messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)
Usage fields
| Field | Description |
|---|---|
prompt_tokens | Input tokens, including any cached tokens |
completion_tokens | Output tokens, including any reasoning tokens |
total_tokens | Sum of prompt and completion tokens |
prompt_tokens_details.cached_tokens | Portion of prompt_tokens served from cache |
completion_tokens_details.reasoning_tokens | Portion of completion_tokens spent on reasoning |
xAI follows the OpenAI usage shape, so cached tokens are reported inclusively
as a breakdown inside prompt_tokens. AI SpendOps subtracts the cached portion
before pricing so it is charged once at the cache-read rate. See
OpenAI for the full explanation, and Anthropic
for the provider that does the opposite.
Watching reasoning spend on Grok
Grok's reasoning models bill thinking at the output rate, and that thinking never appears in the response. A request can return three sentences and be charged for thousands of output tokens.
Because AI SpendOps records reasoning_tokens as its own field on every event,
you can see the split directly rather than inferring it from an invoice total:
- Compare
reasoning_tokensagainstcompletion_tokensto get the share of output spend that is thinking rather than answers. - Break that down by dimension to find which feature or team is driving it.
- If a reasoning model is being used where a standard model would do, model allow-lists can stop a given ASO key reaching it at all.
What AI SpendOps records
| Field | Populated |
|---|---|
cache_read_tokens | Yes, from prompt_tokens_details.cached_tokens |
cache_write_tokens | No. There is no separate cache write charge |
reasoning_tokens | Yes for reasoning models |
provider_cost | No. Cost is calculated from token counts and the current xAI rate card |
Notes
- The proxy injects
stream_options: { include_usage: true }on streaming requests. See Streaming. - Full field definitions are in the usage event field reference.