Introduction
An OpenAI-compatible chat endpoint for xAI's Grok 4.6, where a screenshot and the question about it travel in the same user turn.
Grok 4.6 comes from xAI and answers at POST https://api.spicyapi.ai/v1/chat/completions under the model name xai/grok-4.6. The request surface is the familiar one: a messages array of at most 256 ordered turns, an output cap, two sampling dials, a tool list, a response format, and reasoning_effort to say how hard the model should work before it writes. The window holds 500,000 tokens and a single reply can take 450,000 of them, so the larger share of the budget can sit on the answer side rather than the prompt side. Message content accepts text parts and image_url parts; there is no file or PDF part on this endpoint, and the modality is text and images in, text out.
Key features & highlights
A picture and the sentence about it, in one turn
Content may be a plain string or an array of parts, and an image part carries a url plus a detail hint of auto, low or high. The capture and the question about it arrive together, so the model reads the pixels instead of your description of them, which is the whole difference whenever the answer hangs on a mislabelled axis, a stack trace cut off at the edge, or a layout that only breaks at one width. Image content is metered inside the 500,000-token window rather than beside it, so several large captures and a long history compete for the same budget.
Almost the entire budget can go to the answer
A single reply can reach 450,000 tokens, which is an unusual shape for a chat model: most of the window can be spent writing rather than reading. max_tokens still starts at 4,096, so a long generation is something you ask for and never something you fall into, and a cut at the default arrives without a warning. reasoning_effort takes low, medium, high or xhigh and begins at high; that effort is spent in output tokens, so it counts against your cap and your bill at the same time.
Nothing of ours sits in the path
We add no content classifier of our own between you and this model. What it declines to write is its own behaviour rather than a layer inserted here, and what you send is not scanned, scored or rewritten on the way through. You hold the rights to the material you send, and you answer for what is done with the reply.
Request parameters
| Parameter | Required | Description |
|---|---|---|
messages | Yes | At most 256 turns. Content can mix text and |
reasoning_effort | No | low, medium, high or xhigh. High is the default; effort is spent in output tokens. |
max_tokens | No | Caps the visible reply at 450,000; the default of 4,096 truncates a long answer silently. |
temperature | No | 0 to 2, default 0.7. Use 0 when comparing two mockups or two runs. |
top_p | No | 0.01 to 1. Move this or temperature, not both together. |
tools | No | Up to 128 function definitions per request. at most 128 items |
parallel_tool_calls | No | true or false, default true: the model may request several tool calls in one turn. Default: |
tool_choice | No | auto, none, required, or an object naming the function to call. |
response_format | No | Request a JSON object when the answer is read by code rather than a person. |
Pricing
Input $2 / Output $6 per 1 million tokens; Prompts of 200K tokens or more: Input $4 / Output $12
Total input includes cached tokens. At 200,000 input tokens or more, long-context rates apply to all input, cached input, and output for the request; smaller inputs use standard rates. Output includes reasoning tokens. Check the request budget before submitting. The initial hold assumes no cache savings, and settlement refunds the difference against measured usage.
Use cases
Triage a capture instead of describing it
Send the screenshot at detail high beside the question in one user message and the model works from the pixels: the axis label that is wrong, the row that disappeared, the frame cut off at the edge. Two captures an hour apart in the same turn let you ask which number moved, rather than asking about a summary you typed out by hand.
Write something book-length in a single call
Raise max_tokens toward 450,000 and the migration guide, the long report or the whole test suite comes back as one response instead of a chain of continuations, each of which loses a little of the thread. Turn on stream: true and the text lands while it is still being written.
Keep a tool loop readable
Declare up to 128 function definitions, pair them with tool_choice, and hand each result back as a tool-role message on the following turn. Hold reasoning_effort steady for the whole loop and the only thing that varies between iterations is the conversation itself, which is what makes a trace worth reading when the loop goes wrong.
Hand the answer to code, not to a person
Ask for a JSON object through response_format and drop temperature to 0, and the reply comes back as a structure your parser can take. Pair that with an image part and you have extraction straight from a receipt, a chart or a form capture, with no transcription step in between.
Prompt guide & pro tips
Put the image where the question is
Keep the text part and the image parts inside the same user message rather than sending the picture first and the question afterwards. Say what you want read out of it, whether that is a number, a difference or a verdict, and name the panel when there is more than one: detail high buys resolution, not attention.
POST https://api.spicyapi.ai/v1/chat/completions
{
"model": "xai/grok-4.6",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "These two captures are an hour apart on the same dashboard. Which metric regressed, and what in the second image explains it?"},
{"type": "image_url", "image_url": {"url": "https://cdn.spicyapi.ai/models/examples/inputs/c681580c3c6a0b63.jpeg", "detail": "high"}},
{"type": "image_url", "image_url": {"url": "https://cdn.spicyapi.ai/models/examples/inputs/59f0bc6291069978.jpeg", "detail": "high"}}
]
}
],
"reasoning_effort": "high",
"max_tokens": 4000
}
Spend effort where it changes the answer
reasoning_effort begins at high, so an omitted field already buys the careful setting and the output tokens that come with it. Keep xhigh for work that has to be right the first time, use medium for ordinary review, and drop to low for short mechanical turns. Effort is billed as output, so it shares a ceiling with the reply itself, and a generous cap at xhigh is a large request in both senses.
Check which tier the request lands in
Input and cached input are added together, and from 200,000 tokens the whole request prices on the long-context rate, not only the part above the line. Trimming a history from 210,000 tokens down to 190,000 therefore changes more than the cost of the tokens you removed. The hold taken before the call assumes no cache savings at all and settlement refunds the difference against measured usage, so the figure you see up front is a ceiling rather than the price.
API quick start
curl --fail-with-body -sN https://api.spicyapi.ai/v1/chat/completions \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "xai/grok-4.6/chat",
"messages": [
{
"role": "user",
"content": "Summarise the following release notes into three bullet points."
}
],
"stream": true
}' \
| jq --unbuffered -Rrj 'select(startswith("data: ")) | .[6:] | select(. != "[DONE]") | fromjson | if .error then "\n[error] \(.error.message)\n" else (.choices[0].delta.content? // empty) end'
See the API reference for authentication, the complete schema, polling, and error handling.










