curl --request POST \
--url https://api.apiyi.com/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "grok-imagine-image",
"prompt": "A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography"
}
'import requests
url = "https://api.apiyi.com/v1/images/generations"
payload = {
"model": "grok-imagine-image",
"prompt": "A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'grok-imagine-image',
prompt: 'A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography'
})
};
fetch('https://api.apiyi.com/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'grok-imagine-image',
'prompt' => 'A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}"
response = http.request(request)
puts response.read_body{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/1ab87d04-3637-464f-bafd-f026cac05dd3.jpg",
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000,
"output_tokens": 0
}
}Text-to-Image API Reference
Grok Imagine 2 text-to-image API reference and live testing — prompt-only generation with 5 aspect ratios, 1K/2K tiers, up to 10 images per call
curl --request POST \
--url https://api.apiyi.com/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "grok-imagine-image",
"prompt": "A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography"
}
'import requests
url = "https://api.apiyi.com/v1/images/generations"
payload = {
"model": "grok-imagine-image",
"prompt": "A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'grok-imagine-image',
prompt: 'A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography'
})
};
fetch('https://api.apiyi.com/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'grok-imagine-image',
'prompt' => 'A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"grok-imagine-image\",\n \"prompt\": \"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography\"\n}"
response = http.request(request)
puts response.read_body{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/1ab87d04-3637-464f-bafd-f026cac05dd3.jpg",
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000,
"output_tokens": 0
}
}Bearer sk-xxx), fill in prompt, pick aspect_ratio / resolution, and send.image / image_url / images here raises no error. It returns 200 and generates a brand-new image from the prompt — the reference is silently discarded and you are still billed.With no error signal, this usually surfaces only when someone notices the output has nothing to do with the input. Any workflow with a reference image must use /v1/images/edits.aspect_ratio (e.g. 5:7), resolution (e.g. 1K, 1024x1024) and response_format (e.g. base64) all silently fall back to defaults and still return an image. When output does not match expectations, check the parameter spelling first — note that resolution values are lowercase 1k / 2k.One exception: resolution: "4k" returns 503 model_service_unavailable, meaning the tier is unsupported, not that the channel is down. Retrying will not help.Code Examples
Python (OpenAI SDK)
from openai import OpenAI
import urllib.request
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1",
timeout=360.0 # image APIs are synchronous — allow plenty of time
)
resp = client.images.generate(
model="grok-imagine-image",
prompt="A photorealistic red wooden boat moored on a glassy alpine lake at dawn, "
"mist over the water, snow-capped peaks behind, cinematic photography",
n=1,
# aspect_ratio / resolution are not standard OpenAI SDK fields — pass via extra_body
extra_body={
"aspect_ratio": "16:9",
"resolution": "1k",
"response_format": "url"
}
)
# response_format defaults to url, returning a direct link (.jpg for 1K, .png for 2K)
urllib.request.urlretrieve(resp.data[0].url, "out.jpg")
Python (raw requests)
import requests
import base64
API_KEY = "sk-your-api-key"
response = requests.post(
"https://api.apiyi.com/v1/images/generations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"model": "grok-imagine-image",
"prompt": "Cyberpunk city on a rainy night, neon signage close-up, cinematic lighting",
"n": 1,
"aspect_ratio": "16:9",
"resolution": "2k", # 2k returns PNG at 5-6 MB per image
"response_format": "b64_json"
},
timeout=360 # 2K takes 15-17s and longer at peak; 60s causes spurious timeouts
).json()
# b64_json is raw base64 with no data: prefix — decode and write directly
with open("out.png", "wb") as f:
f.write(base64.b64decode(response["data"][0]["b64_json"]))
cURL
curl -X POST "https://api.apiyi.com/v1/images/generations" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-image-quality",
"prompt": "An orange tabby cat wearing sunglasses at a seaside bar, photorealistic, warm sunset tones",
"n": 1,
"aspect_ratio": "16:9",
"resolution": "1k",
"response_format": "url"
}'
Node.js (native fetch)
import fs from 'node:fs';
const resp = await fetch('https://api.apiyi.com/v1/images/generations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk-your-api-key'
},
body: JSON.stringify({
model: 'grok-imagine-image',
prompt: 'A serene Japanese garden with cherry blossoms, koi pond, golden hour',
n: 2, // up to 10 per call, billed per image
aspect_ratio: '4:3',
resolution: '1k',
response_format: 'url'
}),
// Node 18+ has no default timeout — use AbortSignal.timeout in production
signal: AbortSignal.timeout(360000)
});
const data = await resp.json();
// with n=2 the data array holds two entries — download each
for (const [i, item] of data.data.entries()) {
const img = await fetch(item.url);
fs.writeFileSync(`out-${i}.jpg`, Buffer.from(await img.arrayBuffer()));
}
Browser JavaScript
// ⚠️ Demo only: a front-end key is exposed — use a backend proxy in production
const resp = await fetch('https://api.apiyi.com/v1/images/generations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk-your-api-key'
},
body: JSON.stringify({
model: 'grok-imagine-image',
prompt: 'a minimalist poster of a mountain at sunrise, flat vector style',
aspect_ratio: '3:4',
resolution: '1k',
response_format: 'url' // url is far lighter than b64_json in a browser
})
});
const data = await resp.json();
document.querySelector('#preview').src = data.data[0].url;
Parameter Reference
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | ✅ | — | grok-imagine-image ($0.02/image) or grok-imagine-image-quality ($0.045/image) |
prompt | string | ✅ | — | Prompt in English or Chinese. Describe subject, scene, style and lighting |
n | integer | ❌ | 1 | Images per call, 1-10, billed per image. 0 becomes 1; ≥11 returns 400 |
aspect_ratio | string | ❌ | 1:1 | 1:1 / 16:9 / 9:16 / 4:3 / 3:4; other values silently fall back to 1:1 |
resolution | string | ❌ | 1k | 1k (JPEG, ~1 MP) or 2k (PNG, ~4.2-4.5 MP). Same price; 4k returns 503 |
response_format | string | ❌ | url | url returns a direct link; b64_json returns raw base64 (no data: prefix) |
aspect_ratio | 1k | 2k |
|---|---|---|
1:1 | 1024x1024 | 2048x2048 |
16:9 | 1280x720 | 2816x1584 |
9:16 | 720x1280 | 1584x2816 |
4:3 | 1152x864 | 2368x1776 |
3:4 | 864x1152 | 1776x2368 |
seed is not supported (accepted without error but has no effect — results are not reproducible), and neither is mask inpainting. OpenAI-style fields such as size / quality / style are silently ignored.Response Format
{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/1ab87d04-3637-464f-bafd-f026cac05dd3.jpg"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000,
"output_tokens": 0
}
}
- Each
data[]entry contains eitherurlorb64_jsondepending onresponse_format— never both. revised_promptis not returned, nor arerespect_moderation/model. Do not assume they exist.b64_jsonis raw base64 with nodata:image/...;base64,prefix — decode it directly.createdis always0and cannot be used as a timestamp.- With
n > 1thedataarray holds multiple entries — do not read onlydata[0].
usage cannot be used for reconciliation: prompt_tokens is always 1000 x n, independent of actual prompt length. This family is billed at a flat rate per image ($0.02 / $0.045); use the APIYI Console billing records for actual charges.Authorizations
API Key created in the APIYI Console
Body
Model ID. The quality variant delivers higher fidelity at a higher price
grok-imagine-image, grok-imagine-image-quality Prompt, English or Chinese. Describe subject, scene, style and lighting in detail
"A photorealistic red wooden boat moored on a glassy alpine lake at dawn, mist over the water, snow-capped peaks behind, cinematic photography"
Number of images, 1-10. Values of 11 or above return 400; 0 is silently treated as 1
1 <= x <= 101
Output aspect ratio. Actual pixel dimensions per resolution tier:
| Aspect ratio | 1k | 2k |
|---|---|---|
1:1 | 1024x1024 | 2048x2048 |
16:9 | 1280x720 | 2816x1584 |
9:16 | 720x1280 | 1584x2816 |
4:3 | 1152x864 | 2368x1776 |
3:4 | 864x1152 | 1776x2368 |
Values outside this enum do not raise an error — they silently fall back to 1:1.
1:1, 16:9, 9:16, 4:3, 3:4 "16:9"
Resolution tier. 1k is roughly 0.9-1.05 megapixels and returns JPEG;
2k is roughly 4.2-4.5 megapixels and returns PNG (5-6 MB per image).
Both tiers cost the same.
4k returns 503; other invalid values (such as 1K or 1024x1024) silently fall back to 1k.
1k, 2k "1k"
Response format. url returns a direct image link (no signed query params);
b64_json returns a raw base64 string (without the data: prefix).
Invalid values silently fall back to the default url.
url, b64_json "url"
Response
Images generated successfully
Creation timestamp. Always 0 for this model — do not use it for timing
0
Array of image results, length equals the requested n
Show child attributes
Show child attributes
Placeholder values — do not use for billing reconciliation. prompt_tokens is always
1000 x n, regardless of actual prompt length. Use the Console billing records instead.
Show child attributes
Show child attributes
Was this page helpful?