Text to Image
Generating high-quality images from natural language descriptions is easy with SIRAYA Model Router. Our unified API allows you to access various state-of-the-art image generation models using a single interface.
https://llm.siraya.ai/v1/images/generations
Header
Bearer <API_KEY>).
Body
gpt-image-2, gemini-3.1-flash-image, z-image-spicy). Z-Image sizes its output with width / height — see Z-Image.
gemini-*-image) accept only 1; a larger value returns a 400.
1024x1024, 1792x1024, 1024x1792).
low, medium, high, auto (the 2.5 models also take xhigh and max); standard and hd are accepted as aliases for medium and high. See the model pages for other families.
b64_json, url. Support depends on the model: GPT Image and Gemini Image models always return b64_json and ignore url; Seedream defaults to b64_json and returns a signed URL for url.
transparent, opaque, auto.
png or jpeg.
output_format: jpeg.
low, auto.
data:image/png;base64,<BASE64> for a local file. Supported by Seedream and Gemini Image models.
auto, disabled. Supported by Seedream models.
false, the request waits for generation to finish and returns the completed image. When true, it returns immediately with an image id while generation runs in the background. There's no status/poll endpoint for images — pass callbackUrl to receive the result. See Asynchronous generation.
async is true and must be an http(s) URL; otherwise the request is rejected with a 400 (see Asynchronous generation). A URL the router will POST to once generation completes (or fails). This is the only way to retrieve the result of an async image job.
import requests
url = "https://llm.siraya.ai/v1/images/generations"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer <API_KEY>"
}
data = {
"model": "gemini-3.1-flash-image",
"prompt": "A cat is playing piano in a cozy room",
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
Example Response
Asynchronous generation
Image generation is normally fast, but some models can take a while. By default the request is synchronous — it waits for generation to finish and returns the completed image. For slower models, set async: true to return immediately with an image id and receive the result later via a callback.
No poll or download endpoint
Unlike video generation, async image generation has no status/poll endpoint and no separate download endpoint. callbackUrl is therefore required whenever async is true. A request without a valid http(s) callbackUrl is rejected with HTTP 400 before any generation starts:
{
"created": 1774716098,
"data": {},
"error": { "message": "callbackUrl must be an http(s) URL when async is true" }
}
Submit an async job
curl https://llm.siraya.ai/v1/images/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <API_KEY>" \
-d '{
"model": "gemini-3.1-flash-image",
"prompt": "A cat is playing piano in a cozy room",
"async": true,
"callbackUrl": "https://your-app.com/webhooks/siraya-image"
}'
The job is accepted immediately. status is processing and no image is returned yet. id identifies the job and is echoed in the callback:
Callback
When the job finishes, the router sends a POST to callbackUrl. The body is the synchronous response — the finished image as base64 under data[], not a URL — plus the job id and a status of completed:
{
"id": "6f1c0b9e8a2d4c7e",
"created": 1774716103,
"status": "completed",
"data": [
{ "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zUAAAAg3..." }
],
"error": {}
}
If generation failed, status is failed, data is empty and error.message carries the reason:
{
"id": "6f1c0b9e8a2d4c7e",
"created": 1774716103,
"status": "failed",
"data": {},
"error": { "message": "..." }
}
Your endpoint should respond 2xx within 10 seconds. A failed delivery is retried up to 3 more times (4 attempts in total).
For a list of all available image models, visit the Models Directory.