Skip to content
Get Started

Image

This quickstart walks you through generating your first image with SIRAYA Model Router.

Image generation

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 cute baby sea otter"
  }'

from openai import OpenAI

client = OpenAI(
    api_key="<API_KEY>", # Replace with your Key "sk-***"
    base_url="https://llm.siraya.ai/v1"
)

prompt = """A cute baby sea otter."""

result = client.images.generate(
    model="gemini-3.1-flash-image",
    prompt=prompt,
)

print(result)
  • https://llm.siraya.ai/v1/images/generations is the base URL
  • <API_KEY> is your API Key generated in API page.
  • model is the model name, such as gemini-3.1-flash-image or gpt-image-2, available model list can be access in Model page.
  • prompt is the prompt.
  • async (boolean, optional, default false) — when false, the request waits for generation to finish and returns the finished image. When true, the request returns immediately with an image id while generation runs in the background; there's no status/poll endpoint for images, so pass callbackUrl to receive the result.
  • callbackUrl (string, required when async is true) — must be an http(s) URL; a request with async: true and no valid callbackUrl is rejected with HTTP 400. The full 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.

Example response

{
    "created": 1774716098,
    "data": [
        {
            "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zUAAAAg3..."
        }
    ]
}

Asynchronous generation

Some image models can take a while. Set async: true to return immediately with an image id instead of waiting, and get 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 it is rejected with an error.

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 cute baby sea otter",
    "async": true,
    "callbackUrl": "https://your-app.com/webhooks/siraya-image"
  }'

Example response — the job is accepted; status is processing and no image yet:

{
  "created": 1779869107,
  "id": "6f1c0b9e8a2d4c7e",
  "status": "processing"
}

Callback

When the job finishes, the router sends a POST to your callbackUrl. The body is the synchronous response — the finished image as base64 under data[], not a URL — plus the job id from the response above and a status of completed:

{
  "id": "6f1c0b9e8a2d4c7e",
  "created": 1779869112,
  "status": "completed",
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zUAAAAg3..."
    }
  ],
  "error": {}
}

If generation failed, status is failed, data is empty and error.message carries the reason. Your endpoint should respond 2xx within 10 seconds; a failed delivery is retried up to 3 more times.