Image Generation and Editing API
Last updated: October 17, 2026 (Asia/Shanghai)
Related: Help Center · LLM API · Video Generation
This guide explains how to use tokenexplore's text-to-image and image editing capabilities. If you only want the model to "look at and understand an image," see LLM API · Multimodal; do not use the endpoints on this page.
1. Choose a Protocol
The models tokenexplore currently offers explicitly for image generation are the Gemini image series:
gemini-3-pro-imagegemini-3.1-flash-image
| Protocol | Path | Notes |
|---|---|---|
| Gemini native (recommended) | POST https://ai.afp.net/v1beta/models/{model}:generateContent | Parameters map most closely to Gemini's image capabilities; suitable for production batches |
| OpenAI Images-compatible | POST https://ai.afp.net/v1/images/generations, /v1/images/edits | Reuse the OpenAI SDK; available models are subject to /v1/models and the "supported endpoints" shown in the console |
INFO
Do not assume that gpt-image-*, dall-e-*, or Imagen :predict models are available on the platform. If the console does not list them, do not invent model names to call them. For image generation, prefer the *-image models above.
Auth: for OpenAI paths use Authorization: Bearer sk-xxx; for Gemini native, x-goog-api-key: sk-xxx is recommended (Bearer also works).
Warning
Protect your API key; never put it in frontend code, screenshots, or public repositories.
2. List Models
curl "$CIYUAN_BASE_URL/v1/models" \
-H "Authorization: Bearer $CIYUAN_API_KEY"Look for gemini-3-pro-image and gemini-3.1-flash-image in the returned list, along with any other models that the console marks as supporting images/generations (if any). For pricing, see the console pricing page.
3. Gemini Native: Text-to-Image
curl "$CIYUAN_BASE_URL/v1beta/models/gemini-3-pro-image:generateContent" \
-H "x-goog-api-key: $CIYUAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [{"text": "An orange cat sitting by the window watching the rain, watercolor style"}]
}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {"aspectRatio": "16:9"}
}
}'In the returned candidates[0].content.parts[], the part with inlineData (mimeType + Base64 data) is the image.
# pip install -U google-genai
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["CIYUAN_API_KEY"],
http_options=types.HttpOptions(base_url=os.environ["CIYUAN_BASE_URL"]),
)
resp = client.models.generate_content(
model="gemini-3-pro-image",
contents="An orange cat sitting by the window watching the rain, watercolor style",
config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)
for part in resp.candidates[0].content.parts:
if part.inline_data:
with open("cat.png", "wb") as f:
f.write(part.inline_data.data)
elif part.text:
print(part.text)Common generationConfig fields (depending on model support):
| Field | Notes |
|---|---|
responseModalities | ["TEXT","IMAGE"] is recommended |
imageConfig.aspectRatio | e.g. 1:1, 16:9, 9:16, 3:4, 4:3 |
imageConfig.imageSize | Semantic sizes such as 1K, supported by some models |
candidateCount | Number of candidates; rely on what is actually returned and iterate over the array |
4. Gemini Native: Image Editing / Reference Images
Put the reference image (inlineData) and the text instruction in parts at the same time:
IMAGE_BASE64="$(base64 -w0 reference.png 2>/dev/null || base64 < reference.png | tr -d '\n')"
curl "$CIYUAN_BASE_URL/v1beta/models/gemini-3.1-flash-image:generateContent" \
-H "x-goog-api-key: $CIYUAN_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"contents\": [{
\"role\": \"user\",
\"parts\": [
{\"inlineData\": {\"mimeType\": \"image/png\", \"data\": \"$IMAGE_BASE64\"}},
{\"text\": \"Change the background to a snowy scene, keep the subject composition unchanged, and generate a new image; do not copy the reference image as-is\"}
]
}],
\"generationConfig\": {
\"responseModalities\": [\"TEXT\", \"IMAGE\"],
\"imageConfig\": {\"aspectRatio\": \"1:1\"}
}
}"State clearly in the prompt that the model should "generate a new image, not copy the reference as-is" to reduce results that are nearly identical to the reference image.
5. OpenAI Images-Compatible API
curl "$CIYUAN_BASE_URL/v1/images/generations" \
-H "Authorization: Bearer $CIYUAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<a model the console marks as supporting images/generations>",
"prompt": "An orange cat sitting by the window watching the rain, watercolor style",
"n": 1,
"size": "1024x1024",
"response_format": "b64_json"
}'from openai import OpenAI
import base64
from pathlib import Path
client = OpenAI(
api_key="sk-xxxxxxxx",
base_url="https://ai.afp.net/v1",
)
result = client.images.generate(
model="<model supporting images/generations>",
prompt="An orange cat sitting by the window watching the rain, watercolor style",
size="1024x1024",
n=1,
response_format="b64_json",
)
Path("image.png").write_bytes(base64.b64decode(result.data[0].b64_json))Editing endpoint: POST https://ai.afp.net/v1/images/edits (multipart/form-data or JSON). Use curl -F or a standard multipart library; do not hand-write the Content-Type boundary.
Notes:
- Generation is synchronous; the result exists only in this response, so save it to disk promptly. If it takes too long, you may get
504 task_timeout. nis the number of output images;image[]in multipart is the input reference image. They mean different things.- If you call a Gemini image model through the OpenAI-compatible wrapper, some OpenAI-specific fields (such as certain
stylevalues,background=transparent, ormoderationset to anything other than auto) may have no effect or return errors—putting style requirements in thepromptis more reliable. - You can also call
*-imagemodels via/v1/chat/completions, but how images are returned incontent(Markdown / Data URL, etc.) depends on the platform version; for batch production, use Gemini native.
6. FAQ for This Page
What if no image is returned?
Check whether parts contains inlineData; it may have been filtered by safety policies, or only text was returned. Reduce sensitive or copyright-related wording and retry.
Can I generate multiple images at once?
For OpenAI paths, use n; for Gemini native, use candidateCount. Be sure to iterate over the returned array, not just read the first image.
The edited image looks almost identical to the reference?
State explicitly in the prompt: "regenerate a new image; do not copy the reference image."
Multipart returns "invalid request body" or NextPart: EOF?
This is usually because the boundary/body was mangled by middleware. Use curl -F or the official SDK instead of hand-writing multipart.
Can I use Imagen :predict?
Only if the console and /v1/models actually provide the corresponding model. This guide does not use Imagen as the primary path.
How is billing calculated?
Per call or per specification, subject to console pricing and "Usage Logs"; this guide does not list numbers.
Previous: LLM API · Next: Video Generation