Gemini Image Generation

Overview

AIone supports the Gemini family of image generation models through two endpoints:

Endpoint Use it for Capabilities
POST /v1/chat/completions Quick integration with your existing OpenAI SDK Generation, image-to-image, streaming
POST /v1beta/models/{model}:generateContent When you need a specific resolution or aspect ratio Everything above + resolution / aspect ratio control

In short: to just get an image, use /v1/chat/completions; to control the size, use the /v1beta native endpoint.

Available models

Model Notes
gemini-3.1-flash-image Primary model, balanced speed and quality
gemini-3-pro-image More consistent output, suited to final artwork
gemini-2.5-flash-image Previous-gen Flash, default size only

For the full model list, refer to GET /v1/models and the Portal model list page.


1. Quick generation: /v1/chat/completions

Minimal request:

curl https://api.aiin1.ai/v1/chat/completions \
  -H "Authorization: Bearer sk-nex-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-image",
    "messages": [
      {"role": "user", "content": "Draw a cute cat"}
    ]
  }'

Response shape

The image is returned inside message.content as a Markdown-embedded data URI:

{
  "id": "chatcmpl-xxx",
  "object": "chat.completion",
  "model": "gemini-3.1-flash-image",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "![image](data:image/png;base64,iVBORw0KGgoAAA...)"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 6,
    "completion_tokens": 1120,
    "total_tokens": 1126
  }
}

Extracting the image: message.content is a string — pull the data URI out with a regex.

import re, base64
content = response.choices[0].message.content
m = re.search(r"data:image/\w+;base64,([A-Za-z0-9+/=]+)", content)
if m:
    image_bytes = base64.b64decode(m.group(1))
    open("out.png", "wb").write(image_bytes)

Python SDK

from openai import OpenAI
 
client = OpenAI(
    api_key="sk-nex-your-key-here",
    base_url="https://api.aiin1.ai/v1",
)
 
resp = client.chat.completions.create(
    model="gemini-3.1-flash-image",
    messages=[{"role": "user", "content": "Draw a cute cat"}],
)
print(resp.choices[0].message.content[:80])

Image-to-image

Pass the reference image with the standard OpenAI multimodal content array:

{
  "model": "gemini-3.1-flash-image",
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "Replace the apple in this picture with an orange"},
        {
          "type": "image_url",
          "image_url": {"url": "data:image/png;base64,iVBORw0KGgoAAA..."}
        }
      ]
    }
  ]
}

Reference images may be a data: URI (base64) or a public https:// URL. base64 is recommended: some CDNs apply hotlink protection or format conversion, so a direct link may not be retrievable.

Streaming

"stream": true is supported. This is pseudo-streaming — the finished image is delivered in one SSE event once generation completes, not token by token. The benefit is that data keeps flowing on the connection, so intermediate network devices are less likely to drop it as idle.

curl https://api.aiin1.ai/v1/chat/completions \
  -H "Authorization: Bearer sk-nex-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-image",
    "messages": [{"role": "user", "content": "Draw a cute cat"}],
    "stream": true
  }'

Image size on this endpoint

/v1/chat/completions renders at the model's default size, about 1408×768 (image-to-image follows the reference image — a square reference yields 1024×1024).

To choose a resolution or aspect ratio, use the native endpoint below.


2. Controlling resolution and aspect ratio: the /v1beta native endpoint

POST https://api.aiin1.ai/v1beta/models/{model}:generateContent

The model name goes in the URL path; size parameters go in generationConfig.imageConfig:

curl https://api.aiin1.ai/v1beta/models/gemini-3.1-flash-image:generateContent \
  -H "Authorization: Bearer sk-nex-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {"role": "user", "parts": [{"text": "Draw a cute cat"}]}
    ],
    "generationConfig": {
      "responseModalities": ["IMAGE"],
      "imageConfig": {
        "imageSize": "4K",
        "aspectRatio": "16:9"
      }
    }
  }'

imageSize — resolution tier

Values: 512 / 1K (default) / 2K / 4K. Actual pixel dimensions at 16:9:

imageSize Pixels (16:9) Area
omitted (default 1K) 1376×768 1.06 MP
"2K" 2752×1536 4.23 MP
"4K" 5504×3072 16.9 MP
"512" 688×384 0.26 MP

gemini-2.5-flash-image outputs the default size only (1024×1024) and ignores imageSize.

aspectRatio — aspect ratio

14 values are supported. Actual pixels at the default tier (1K):

Ratio Pixels Ratio Pixels
1:1 1024×1024 9:16 768×1376
3:2 1264×848 16:9 1376×768
2:3 848×1264 21:9 1584×672
4:3 1200×896 1:4 512×2064
3:4 896×1200 4:1 2064×512
5:4 1152×928 1:8 352×2928
4:5 928×1152 8:1 2928×352

imageSize and aspectRatio combine freely — e.g. 4K + 21:9 gives an ultra-wide high-resolution image.

The model renders at the native resolution of the chosen tier and ratio; take the actual pixel size from the returned image.

Response shape

The image is in candidates[0].content.parts[] under inlineData; data is raw base64 with no prefix:

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "inlineData": {
              "mimeType": "image/png",
              "data": "iVBORw0KGgoAAA..."
            }
          }
        ]
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 6,
    "candidatesTokenCount": 1120,
    "totalTokenCount": 1126,
    "candidatesTokensDetails": [{"modality": "IMAGE", "tokenCount": 1120}]
  }
}
import base64, json, requests
 
resp = requests.post(
    "https://api.aiin1.ai/v1beta/models/gemini-3.1-flash-image:generateContent",
    headers={"Authorization": "Bearer sk-nex-your-key-here"},
    json={
        "contents": [{"role": "user", "parts": [{"text": "Draw a cute cat"}]}],
        "generationConfig": {
            "responseModalities": ["IMAGE"],
            "imageConfig": {"imageSize": "2K", "aspectRatio": "16:9"},
        },
    },
    timeout=600,
)
for part in resp.json()["candidates"][0]["content"]["parts"]:
    if "inlineData" in part:
        open("out.png", "wb").write(base64.b64decode(part["inlineData"]["data"]))

parts may also contain non-image entries such as thoughtSignature; when iterating, check for the presence of inlineData.

Image-to-image (native endpoint)

Put the reference image in parts as inlineData, alongside the text. data is raw base64 without the data:image/png;base64, prefix:

{
  "contents": [
    {
      "role": "user",
      "parts": [
        {"inlineData": {"mimeType": "image/png", "data": "iVBORw0KGgoAAA..."}},
        {"text": "Replace the apple in this picture with an orange"}
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["IMAGE"],
    "imageConfig": {"aspectRatio": "1:1"}
  }
}

Add several inlineData parts to blend multiple images.


Billing

Image output is billed per image output token. The token count is determined by the resolution tier, independent of prompt length:

Tier gemini-3.1-flash-image gemini-3-pro-image
512 747
default / 1K 1,120 1,120
2K 1,680 1,120
4K 2,520 2,000

gemini-2.5-flash-image is 1,290 tokens per image.

The image portion follows the table above. usage.completion_tokens (chat endpoint) and usageMetadata.candidatesTokenCount (native endpoint) are the total output tokens for the request and may include a small number of text tokens besides the image; each portion is priced at its own rate. See "Pricing" for unit prices.

Request parameters

/v1/chat/completions

Parameter Type Required Description
model string Yes Image model ID
messages array Yes Standard OpenAI Chat message array; pass reference images as image_url parts
stream boolean No Pseudo-streaming; the image is delivered in one SSE event after generation
temperature number No Sampling temperature

/v1beta/models/{model}:generateContent

Parameter Type Required Description
contents array Yes Conversation content; parts holds text and inlineData
generationConfig.responseModalities array No Recommended: ["IMAGE"]
generationConfig.imageConfig.imageSize string No 512 / 1K / 2K / 4K
generationConfig.imageConfig.aspectRatio string No One of the 14 values above

Notes

  1. Timeouts: high-resolution generation takes longer; set your client HTTP timeout to ≥ 600 seconds.
  2. Image extraction differs by endpoint: on the chat endpoint, extract the Markdown data URI from message.content; on the native endpoint, read parts[].inlineData.data (raw base64, no prefix).
  3. Reference image format: the chat endpoint takes a full data URI with the data: prefix; the native endpoint takes raw base64 without it. The two rules are opposite — do not mix them up.
  4. No Anthropic format: Gemini image models are not available on /v1/messages.
  5. Model access: make sure your API key is allowed to use the image model.