input_image vs image_url: The Two Syntaxes
On this page
Two APIs, two syntaxes
xAI offers two endpoints for interacting with Grok, and each uses a different syntax for sending images. Understanding these differences is essential for writing correct code and avoiding frustrating errors.
Responses API: input_image (recommended)
The Responses API is xAI’s new primary endpoint. New features are added here first. This is the API to prioritize for any new project.
Syntax
{
"model": "grok-4.5",
"store": false,
"input": [
{
"type": "input_image",
"image_url": "https://exemple.com/photo.jpg",
"detail": "high"
},
{
"type": "input_text",
"text": "Describe this image."
}
]
}
Characteristics
- The type is
input_image(notimage_url) - The URL or Data URI goes directly in
image_url(no nested object) detailsits at the same level asimage_url- Text uses the
input_texttype - The
inputarray replaces themessagesarray from Chat Completions
Python SDK
response = client.responses.create(
model="grok-4.5",
input=[
{
"type": "input_image",
"image_url": "https://exemple.com/photo.jpg",
"detail": "high"
},
{
"type": "input_text",
"text": "Describe this image."
}
],
store=False
)
print(response.output_text)
Chat Completions API: image_url (legacy)
The Chat Completions API is the legacy endpoint, maintained for compatibility with existing OpenAI SDKs. If you are migrating code written for OpenAI, this API eases the transition.
Syntax
{
"model": "grok-4.5",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://exemple.com/photo.jpg",
"detail": "high"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}
Characteristics
- The type is
image_url(notinput_image) - The URL sits in a nested
image_url.urlobject (double nesting) detaillives inside theimage_urlobject- Text uses the
texttype (notinput_text) - Messages have a
role(system, user, assistant)
Python with OpenAI SDK
from openai import OpenAI
client = OpenAI(
api_key="your-xai-key",
base_url="https://api.x.ai/v1"
)
response = client.chat.completions.create(
model="grok-4.5",
messages=[{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://exemple.com/photo.jpg",
"detail": "high"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}]
)
print(response.choices[0].message.content)
Comparison table
| Aspect | API Responses | Chat Completions |
|---|---|---|
| Status | Primary (recommended) | Legacy (compatibility) |
| Image type | input_image | image_url |
| Text type | input_text | text |
| Image URL | image_url: "..." | image_url.url: "..." |
| State management | Stateful (previous_response_id) | Stateless (resend everything) |
| Storage | store: true/false | No (stateless) |
| Server tools | web_search, x_search, code_interpreter | Limited |
Common syntax errors
Error 1: Mixing formats
# WRONG — Chat Completions syntax in Responses API
input=[
{"type": "image_url", "image_url": {"url": "..."}} # No!
]
# CORRECT — Responses API syntax
input=[
{"type": "input_image", "image_url": "..."} # Yes!
]
Error 2: Forgetting nested structure in Chat Completions
# WRONG — Direct URL in Chat Completions
{"type": "image_url", "image_url": "https://..."} # No!
# CORRECT — Nested object
{"type": "image_url", "image_url": {"url": "https://..."}} # Yes!
Error 3: Using “text” instead of “input_text”
# WRONG — "text" type in Responses API
input=[
{"type": "text", "text": "Describe."} # No!
]
# CORRECT
input=[
{"type": "input_text", "text": "Describe."} # Yes!
]
When to use which API
- New project: use the Responses API. It gives access to the latest features and conversation storage
- Migrating from OpenAI: start with Chat Completions to minimize code changes, then migrate to the Responses API gradually
- Sensitive images: Responses API with
store: falseor Chat Completions API (stateless by nature)
Key takeaways
- Responses API uses
input_image+input_text, Chat Completions API usesimage_url+text - URL structure differs: direct in Responses, nested in Chat Completions
- Responses API is the recommended choice for all new development
- Never mix syntaxes from both APIs in the same request
- Always check the object type (
input_imagevsimage_url) to avoid silent errors
Test your knowledge
xAI API vision: formats, tokens, syntaxes—is everything in place?
1. How do you send an image to the API?
Answer: Via URL or Base64, in a mixed-content message—respecting documented format and size constraints.
2. What does the detail parameter (auto, low, high) control?
Answer: Analysis granularity and cost: low saves tokens for coarse use cases, high maximizes precision (OCR, fine details), auto lets the API decide.
3. How is the cost of an image calculated?
Answer: In image tokens—from 256 to 1792 depending on resolution and detail: sizing your images and your detail level is the first optimization lever.
4. What does multi-image comparison enable?
Answer: Sending multiple images in a single request and reasoning over them—differences, evolutions, consistency—with no limit on the number of images per request.
5. input_image or image_url: which to choose?
Answer: input_image is the modern syntax of the Responses API; image_url persists as Chat Completions legacy—for new code, the modern syntax is mandatory.
Good format, good detail, good syntax: vision is piloted like text—down to the token.