grok-4.20-beta-0309-non-reasoning
Grok 4.20 Non-Reasoning is xAI’s text-and-image model for instruction-driven answers, function calling and structured results. The 0309 identity supports tasks that connect visual evidence and long text context to a clear explanation or fields ready for further processing.
- Ailoot Ultra · OpenAI Chat
POST /v1/chat/completionsgrok-4.20-beta-0309-non-reasoning - Ailoot Ultra · Anthropic Messages
POST /v1/messagesgrok-4.20-beta-0309-non-reasoning
About the model
This description covers the model’s capabilities. Available in Ailoot inputs, outputs and options are listed for the selected method below.
Model identity and purpose
Grok 4.20 Non-Reasoning is xAI’s named configuration for instruction-driven responses and agentic tool calling. The manufacturer lists grok-4.20-beta-0309-non-reasoning as an alias of grok-4.20-0309-non-reasoning. Keeping that exact name matters when distinguishing this edition from a moving latest identifier or another Grok 4.20 configuration. Its declared purpose emphasizes following the prompt and preparing a precise response to the task.
Input, output and context
The model accepts text and images and produces text. The listed context window is 1,000,000 tokens, giving room for substantial instructions, reference text and conversation history around the visual task. Image understanding is input processing; the output here is an explanation or data expressed as text. Prepare legible visual material and explain its role: the interface state to inspect, the chart to interpret or the document fragment to describe.
Function calling
The manufacturer documents function calling as a model capability. A connected application defines the functions and their arguments; the model can select a relevant action and return the information required to invoke it. For a visual support task, provide the screenshot, the user’s goal and the descriptions of allowed diagnostic tools. A useful result could identify the observed state, ask for a missing detail or propose the next available operation. The application executes that operation and returns its observation. The model’s text should distinguish a proposed action from an action actually completed.
Structured outputs
The model also supports structured results for subsequent processing. The manufacturer interface also supports batch processing. Instead of an unrestricted explanation, define fields for the task: the observed item, the relevant detail, a concise interpretation and unresolved questions. An illustrative document task can ask for names and values visible in an image, with an explicit rule for unreadable entries. A product-analysis task can request a comparison table grounded in supplied text and pictures. A schema organizes the response; it does not make an uncertain interpretation of an image into a verified fact.
Preparing a practical request
Keep evidence and instructions separate. If several images accompany a question, identify each image and specify whether the task is comparison, extraction or explanation. Include the criteria that decide the result: the expected interface state, the fields to extract or the details that need to remain unchanged. For a long discussion, provide the relevant history and earlier tool results so the next reply addresses the current state. Request a concrete final artifact, such as a support explanation, a list of observed discrepancies or a structured record for the next application step.
Edition and capability boundaries
Non-Reasoning is retained as the configuration’s identity; it should be selected deliberately alongside separately named reasoning configurations. Text-and-image input does not specify audio or video processing, and the context window is not a maximum answer length. Function calls require actual connected tools, while structured text requires an output format supported by the integration. Preserve the exact 0309 alias when recording the task so changes of edition or application behavior remain distinguishable from the model capabilities described here.
Practical task
Extract a source-grounded return record
Technical example in English
Extract a source-grounded return record
Extract a return record from this message: 'Order R-204 arrived on 8 May. One blue bowl was cracked; the other two are fine. I want a replacement, not a refund.' Return the order ID, affected item, affected quantity and requested resolution. Mark any absent field 'not stated' and do not infer a cause of damage.Expected result
A four-field text record preserving the customer's requested resolution and affected quantity.Check the result
The record distinguishes the one damaged bowl from the two undamaged bowls and does not invent a damage cause.Ailoot Ultra · OpenAI Chat POST /v1/chat/completions grok-4.20-beta-0309-non-reasoning
grok-4.20-beta-0309-non-reasoning
grok-4.20-beta-0309-non-reasoningOverview
Grok 4.20 Non-Reasoning is xAI’s text-and-image model for instruction-driven answers, function calling and structured results. The 0309 identity supports tasks that connect visual evidence and long text context to a clear explanation or fields ready for further processing.
- Accepted inputs
- Text
- Results
- Text
Available in Ailoot · inputs & methods
Ailoot Ultra · OpenAI Chat POST /v1/chat/completions
- Input types
text- Output types
text- Output format
- json or SSE
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits grok-4.20-beta-0309-non-reasoning | Default— |
Fieldmessages | Typemessage[] | RequirementRequired | Values & limits Minimum items: 1 | Default— |
Fieldmessages[].role | Typestring | RequirementRequired | Values & limits Examples: system, user, assistant, tool, function Conditions: These roles are explicitly represented by Source compatibility types; the exact model role set remains model-specific. Model-specific | Default— |
Fieldmessages[].content | Typestring|content_part[]|null | RequirementOptional | Values & limits | Default— |
Fieldmessages[].tool_calls | Typetool_call[] | RequirementOptional | Values & limits | Default— |
Fieldmessages[].tool_call_id | Typestring | RequirementOptional | Values & limits Applies when: role=tool; use actual returned ID | Default— |
Fieldmessages[].name | Typestring | RequirementOptional | Values & limits | Default— |
Fieldmessages[].reasoning_content | Typestring | RequirementOptional | Values & limits Applies when: Round-trip actual returned reasoning where this model uses it | Default— |
Fieldmessages[].reasoning_details | Typeobject|array | RequirementOptional | Values & limits Model-specific | Default— |
Fieldmax_tokens | Typeinteger | RequirementOptional | Values & limits Minimum: 1 Model-specific | Default— |
Fieldmax_completion_tokens | Typeinteger | RequirementOptional | Values & limits Minimum: 1 Model-specific | Default— |
Fieldstream | Typeboolean | RequirementOptional | Values & limits | Defaultfalse |
Fieldstream_options.include_usage | Typeboolean | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtemperature | Typenumber | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtop_p | Typenumber | RequirementOptional | Values & limits Model-specific | Default— |
Fieldstop | Typestring|string[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtools | Typefunction_tool[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtools[].type | Typestring | RequirementOptional | Values & limits function Model-specific | Default— |
Fieldtools[].function.name | Typestring | RequirementRequired | Values & limits Applies when: function tool supplied | Default— |
Fieldtools[].function.description | Typestring | RequirementOptional | Values & limits | Default— |
Fieldtools[].function.parameters | TypeJSON_schema | RequirementOptional | Values & limits | Default— |
Fieldtool_choice | Typestring|object | RequirementOptional | Values & limits Model-specific | Default— |
Fieldparallel_tool_calls | Typeboolean | RequirementOptional | Values & limits Model-specific | Default— |
Fieldresponse_format | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldreasoning_effort | Typestring | RequirementOptional | Values & limits Model-specific | Default— |
Fieldreasoning | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldservice_tier | Typestring | RequirementOptional | Values & limits Model-specific | Default— |
Fieldinstructions | Typestring | RequirementOptional | Values & limits Compatibility field | Default— |
Fieldfunctions | Typefunction[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldfunction_call | Typestring|object | RequirementOptional | Values & limits Model-specific | Default— |
Fieldprompt_cache_options | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldmodalities | Typestring[] | RequirementOptional | Values & limits text | Default— |
Fieldprovider | Typeobject | RequirementOptional | Values & limits Conditions: provider.options is rejected on this Ultra text route | Default— |
Fieldcache_control.ttl | Typestring | RequirementOptional | Values & limits Conditions: 1h is rejected in actual prompt-cache locations | Default— |
Input material combinations
Text · UTF8 text
messages[].content
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametercontent_type | Contractapplication/json |
Parameterrequired | Contractmodel, messages |
Parametermaterial_types | Contracttext |
Parametermessages | Contractmessage array with role/content shape |
Parameterfile_material | Contractactual UTF-8 document inserted as literal text; no file ID inferred |
Parameteroptional_controls | Contractstream, temperature, top_p, stop, max_tokens, max_completion_tokens, reasoning, response_format, tools, tool_choice |
Parametercontrol_scope | Contractmodel-specific; user function tools differ from hosted tools |
Parameteroutput_modalities | Contracttext |
Parameterhosted_operations | Contractfalse |
Parametermultimodal_input_binding | Contractnull |
Lifecycle: synchronous_or_streamed
Send exact model ID with messages.
Context length is not an output cap.
A text file may supply literal text; image/audio/file-object inputs need exact binding.
Pricing
Tariff references do not add request options. Supported parameters are listed for the selected method.
- Fast mode
- Not specified When fast mode is selected
- Flex mode
- Not specified When flex mode is selected
- Maximum reasoning effort
- Not specified When maximum reasoning effort uses the default adjustment
Ailoot rates
Prices by configuration
| Configuration | Rate schedule | Charge |
|---|---|---|
| ConfigurationBase token rates | Rate scheduleBase rate | Charge Input · Input tokens $0.004 / 1K tokens Output · Output tokens $0.012 / 1K tokens Input · Cache read $0 / 1K tokens Input · Cache write $0 / 1K tokens Input · Cache write, 1 hour — / 1K tokens |
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot Ultra · OpenAI Chat
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
p=json.loads('{"model": "grok-4.20-beta-0309-non-reasoning", "messages": [{"role": "user", "content": "Explain the difference between an observation and a hypothesis in three sentences."}]}')
Path("request.json").write_text(json.dumps(p,ensure_ascii=False))
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/chat/completions \
-H "Authorization: Bearer $AILOOT_API_KEY" -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
r=json.loads(Path("result.json").read_text())
for x in r.get("choices",[]):
if x.get("message",{}).get("content"): print(x["message"]["content"])
PY_RESULT
from openai import OpenAI
import os
if not os.environ.get("AILOOT_API_KEY", "").strip(): raise SystemExit("Set AILOOT_API_KEY before making a request")
client=OpenAI(base_url="https://api.ailoot.ai/v1",api_key=os.environ["AILOOT_API_KEY"],max_retries=0)
result=client.chat.completions.create(model='grok-4.20-beta-0309-non-reasoning',messages=[{"role":"user","content":"Explain observations and hypotheses in three sentences."}])
import base64, json
from pathlib import Path
def save_result(data, stem="result"):
# Keep every field, including usage, IDs, reasoning and tool requests.
Path(stem + ".json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(data, ensure_ascii=False, indent=2))
def save_blob(encoded, suffix, label):
raw = base64.b64decode(encoded, altchars=b"-_", validate=True)
ext = "png" if raw.startswith(b"\x89PNG\r\n\x1a\n") else "jpg" if raw.startswith(b"\xff\xd8") else "webp" if raw[:4] == b"RIFF" and raw[8:12] == b"WEBP" else suffix
file = Path(stem + "-" + label + "." + ext)
file.write_bytes(raw)
print("Saved", file)
for index, block in enumerate(data.get("content") or []):
print("Content", index, json.dumps(block, ensure_ascii=False))
for choice in data.get("choices") or []:
print("Choice", choice.get("index"), json.dumps(choice.get("message", choice.get("delta", {})), ensure_ascii=False))
for index, item in enumerate(data.get("output") or []):
print("Output", index, json.dumps(item, ensure_ascii=False))
if item.get("type") == "image_generation_call" and item.get("result"):
save_blob(item["result"], item.get("output_format") or "bin", "output-" + str(index))
for ci, candidate in enumerate(data.get("candidates") or []):
for pi, part in enumerate((candidate.get("content") or {}).get("parts") or []):
print("Candidate/part", ci, pi, json.dumps(part, ensure_ascii=False))
blob = part.get("inlineData") or part.get("inline_data")
if blob and blob.get("data"):
mime = blob.get("mimeType") or blob.get("mime_type")
suffix = {"image/png":"png", "image/jpeg":"jpg", "image/webp":"webp", "audio/wav":"wav", "audio/mpeg":"mp3", "video/mp4":"mp4"}.get(mime, "bin")
save_blob(blob["data"], suffix, "candidate-" + str(ci) + "-part-" + str(pi))
save_result(result.to_dict(mode="json"))
from openai import OpenAI
import os
from pathlib import Path
if not os.environ.get("AILOOT_API_KEY", "").strip(): raise SystemExit("Set AILOOT_API_KEY before making a request")
client=OpenAI(base_url="https://api.ailoot.ai/v1",api_key=os.environ["AILOOT_API_KEY"],max_retries=0)
import base64, json
from pathlib import Path
def save_result(data, stem="result"):
# Keep every field, including usage, IDs, reasoning and tool requests.
Path(stem + ".json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(data, ensure_ascii=False, indent=2))
def save_blob(encoded, suffix, label):
raw = base64.b64decode(encoded, altchars=b"-_", validate=True)
ext = "png" if raw.startswith(b"\x89PNG\r\n\x1a\n") else "jpg" if raw.startswith(b"\xff\xd8") else "webp" if raw[:4] == b"RIFF" and raw[8:12] == b"WEBP" else suffix
file = Path(stem + "-" + label + "." + ext)
file.write_bytes(raw)
print("Saved", file)
for index, block in enumerate(data.get("content") or []):
print("Content", index, json.dumps(block, ensure_ascii=False))
for choice in data.get("choices") or []:
print("Choice", choice.get("index"), json.dumps(choice.get("message", choice.get("delta", {})), ensure_ascii=False))
for index, item in enumerate(data.get("output") or []):
print("Output", index, json.dumps(item, ensure_ascii=False))
if item.get("type") == "image_generation_call" and item.get("result"):
save_blob(item["result"], item.get("output_format") or "bin", "output-" + str(index))
for ci, candidate in enumerate(data.get("candidates") or []):
for pi, part in enumerate((candidate.get("content") or {}).get("parts") or []):
print("Candidate/part", ci, pi, json.dumps(part, ensure_ascii=False))
blob = part.get("inlineData") or part.get("inline_data")
if blob and blob.get("data"):
mime = blob.get("mimeType") or blob.get("mime_type")
suffix = {"image/png":"png", "image/jpeg":"jpg", "image/webp":"webp", "audio/wav":"wav", "audio/mpeg":"mp3", "video/mp4":"mp4"}.get(mime, "bin")
save_blob(blob["data"], suffix, "candidate-" + str(ci) + "-part-" + str(pi))
with client.chat.completions.stream(model='grok-4.20-beta-0309-non-reasoning',messages=[{"role":"user","content":"Explain observations and hypotheses in three sentences."}]) as stream:
with Path("stream-events.jsonl").open("w",encoding="utf-8") as log:
for event in stream:
payload=event.to_dict(mode="json")
log.write(json.dumps(payload,ensure_ascii=False)+"\n"); log.flush()
print(json.dumps(payload,ensure_ascii=False))
final=stream.get_final_completion()
save_result(final.to_dict(mode="json"),"stream-result")
Receive and save results
Ailoot Ultra · OpenAI Chat
json or SSE
Keep all completed results
Keep every complete returned response, file and content part.
Keep every choice and its content/tool calls/reasoning. In SSE assemble deltas by choice/tool index, retain the final finish reason and usage.
If the original response needs checking
Keep request/response IDs and headers. No generic text job retrieval URL is supplied.
Response fields
| Field | Type |
|---|---|
Fieldchoices[].index | Typeinteger |
Fieldchoices[].message.content | Typestring|null |
Fieldchoices[].message.tool_calls | Typetool_call[] |
Fieldchoices[].message.reasoning_content | Typestring |
Fieldchoices[].message.reasoning_details | Typeobject|array |
Fieldchoices[].finish_reason | Typestring|null |
Fieldusage | Typeobject |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Aliases
Model aliases
Ailoot Ultra grok-4.20-beta-0309-non-reasoning
Method path aliases
Use the method paths shown above.
Related caller IDs
Ailoot Ultra · Anthropic Messages POST /v1/messages grok-4.20-beta-0309-non-reasoning
grok-4.20-beta-0309-non-reasoning
grok-4.20-beta-0309-non-reasoningOverview
Grok 4.20 Non-Reasoning is xAI’s text-and-image model for instruction-driven answers, function calling and structured results. The 0309 identity supports tasks that connect visual evidence and long text context to a clear explanation or fields ready for further processing.
- Accepted inputs
- Text
- Results
- json · sse
Available in Ailoot · inputs & methods
Ailoot Ultra · Anthropic Messages POST /v1/messages
- Input types
text- Output types
json,sse- Output format
- JSON or SSE
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits grok-4.20-beta-0309-non-reasoning | Default— |
Fieldmessages | Typemessage[] | RequirementRequired | Values & limits | Default— |
Fieldmessages[].role | Typestring | RequirementRequired | Values & limits user, assistant | Default— |
Fieldmessages[].content | Typestring | RequirementRequired | Values & limits | Default— |
Fieldmax_tokens | Typeinteger | RequirementRequired | Values & limits | Default— |
Fieldstream | Typeboolean | RequirementOptional | Values & limits | Defaultfalse |
Input material combinations
Text · UTF-8 text
messages[].content string
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametercontent_type | Contractapplication/json |
Parameterrequired | Contractmodel, messages, max_tokens |
Parameteroptional_controls | Contractstream |
Parametermaterial_types | Contracttext |
Parametertext_file_material | ContractRead the actual UTF-8 document and put its text in the indicated input or message content string. |
Lifecycle: synchronous_or_streamed
Pricing
Tariff references do not add request options. Supported parameters are listed for the selected method.
- Fast mode
- Not specified When fast mode is selected
- Flex mode
- Not specified When flex mode is selected
- Maximum reasoning effort
- Not specified When maximum reasoning effort uses the default adjustment
Ailoot rates
Prices by configuration
| Configuration | Rate schedule | Charge |
|---|---|---|
| ConfigurationBase token rates | Rate scheduleBase rate | Charge Input · Input tokens $0.004 / 1K tokens Output · Output tokens $0.012 / 1K tokens Input · Cache read $0 / 1K tokens Input · Cache write $0 / 1K tokens Input · Cache write, 1 hour — / 1K tokens |
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot Ultra · Anthropic Messages
{
"model": "grok-4.20-beta-0309-non-reasoning",
"max_tokens": 128,
"messages": [
{
"role": "user",
"content": "Summarize the incident report."
}
],
"stream": false
}set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_TEXT_FILE:?Set your actual UTF-8 document}"
export AILOOT_TEXT_FILE
python3 - <<'PY_REQUEST'
import json, os
from pathlib import Path
source_file = Path(os.environ['AILOOT_TEXT_FILE'])
if not source_file.is_file():
raise SystemExit('Set AILOOT_TEXT_FILE to your actual UTF-8 document')
text = source_file.read_text(encoding='utf-8')
if not text.strip():
raise SystemExit('Choose a document containing text')
payload = {'model': 'grok-4.20-beta-0309-non-reasoning', 'max_tokens': 128, 'messages': [{'role': 'user', 'content': 'Summarize the incident report.'}]}
payload['messages'][0]['content'] = 'Summarize this material and quote supporting source passages.\n\n' + text
Path('request.json').write_text(json.dumps(payload, ensure_ascii=False), encoding='utf-8')
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/messages \
-H "x-api-key: $AILOOT_API_KEY" -H 'anthropic-version: 2023-06-01' -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
result = json.loads(Path('result.json').read_text(encoding='utf-8'))
print(json.dumps(result, ensure_ascii=False, indent=2))
PY_RESULT
import json, os
from pathlib import Path
source_file = Path(os.environ['AILOOT_TEXT_FILE'])
if not source_file.is_file():
raise SystemExit('Set AILOOT_TEXT_FILE to your actual UTF-8 document')
text = source_file.read_text(encoding='utf-8')
if not text.strip():
raise SystemExit('Choose a document containing text')
payload = {'model': 'grok-4.20-beta-0309-non-reasoning', 'max_tokens': 128, 'messages': [{'role': 'user', 'content': 'Summarize the incident report.'}]}
payload['messages'][0]['content'] = 'Summarize this material and quote supporting source passages.\n\n' + text
from urllib.request import Request, urlopen
from urllib.error import HTTPError
api_key = os.environ['AILOOT_API_KEY']
if not api_key.strip():
raise SystemExit('Set AILOOT_API_KEY before making a request')
headers = {'x-api-key': 'PLACEHOLDER_KEY', 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json'}
headers['x-api-key'] = api_key
request = Request('https://api.ailoot.ai/v1/messages', data=json.dumps(payload, ensure_ascii=False).encode('utf-8'), headers=headers, method='POST')
try:
with urlopen(request, timeout=120) as response:
raw = response.read()
Path('response-headers.txt').write_text(str(response.headers), encoding='utf-8')
except HTTPError as error:
Path('result.json').write_bytes(error.read())
Path('response-headers.txt').write_text(str(error.headers), encoding='utf-8')
raise
Path('result.json').write_bytes(raw)
import json
from pathlib import Path
result = json.loads(Path('result.json').read_text(encoding='utf-8'))
print(json.dumps(result, ensure_ascii=False, indent=2))
Receive and save results
Ailoot Ultra · Anthropic Messages
JSON or SSE
Keep all completed results
Keep every complete returned response, file and content part.
Keep all content blocks, thinking signatures and actual tool-use IDs. Assemble all SSE block deltas; a first text block is not the complete output.
If the original response needs checking
Keep request/response IDs and headers. No generic text job retrieval URL is supplied.
Response fields
| Field | Type |
|---|---|
Fieldid | Typestring |
Fieldmodel | Typestring |
Fieldcontent[] | Typetext|thinking|tool_use|other content block |
Fieldstop_reason | Typestring|null |
Fieldusage | Typeobject |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Aliases
Model aliases
Ailoot Ultra grok-4.20-beta-0309-non-reasoning
Method path aliases
Use the method paths shown above.
Related caller IDs
FAQ · grok-4.20-beta-0309-non-reasoning
- What inputs and results are available?
POST /v1/chat/completions·grok-4.20-beta-0309-non-reasoning:text→textPOST /v1/messages·grok-4.20-beta-0309-non-reasoning:text→json,sse- Which fields does the request use?
POST /v1/chat/completions·grok-4.20-beta-0309-non-reasoning:model,messages,stream,modalities,providerPOST /v1/messages·grok-4.20-beta-0309-non-reasoning:model,messages,max_tokens,stream- What limits apply?
POST /v1/chat/completions·grok-4.20-beta-0309-non-reasoning:messages.min_items:1