Authentication
Create a key under API keys and send it in the Authorization header. Keys are shown once; store them as secrets and never ship them in a public web page.
Authorization: Bearer sk-...
Quick start
By default the call waits and returns the finished image. A typical image takes 5 to 40 seconds.
JavaScript
const res = await fetch("https://api.xelentapi.com/v1/api/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "nano-banana-2",
prompt: "a paper boat on a puddle, overcast light",
aspectRatio: "16:9",
imageSize: "2K",
}),
});
const job = await res.json();
console.log(job.status, job.results?.[0]?.url);
Python
import os, requests
r = requests.post(
"https://api.xelentapi.com/v1/api/generate",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"model": "gpt-image-2",
"prompt": "a vintage travel poster of Lisbon",
"aspectRatio": "2:3",
},
timeout=600,
)
job = r.json()
print(job["status"], job.get("results", [{}])[0].get("url"))
Generate
POST /v1/api/generate creates one image or one video.
A successful response:
{
"id": "gen_7QmXv2...",
"status": "succeeded",
"progress": 100,
"model": "nano-banana-2",
"results": [{ "url": "https://api.xelentapi.com/files/gen_7QmXv2.../0.png", "type": "image/png" }],
"cost_usd": 0.016,
"created_at": 1790000000
}
status is one of running, succeeded, failed or violation (blocked by content moderation). Only succeeded is charged.
Parameters
Every model
| Field | Type | Notes |
|---|---|---|
model | string | Required. See models. |
prompt | string | Required. Up to 10,000 characters. |
images | string[] | Reference images as URLs or base64. Up to 14 for image models, 9 for video. |
replyType | string | json (default), stream or async. See reply types. |
Nano Banana models
aspectRatio | auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 5:4, 4:5, 21:9, 1:4, 4:1, 1:8, 8:1. Default auto. |
imageSize | 1K, 2K or 4K where the model supports it (see pricing). Same price at every size. |
GPT Image models
aspectRatio | A ratio such as 16:9, or pixels such as 1024x1024. On VIP, Flare and Sunburst, a ratio is combined with imageSize (1K/2K/4K) to pick the pixel size. |
quality | gpt-image-2.5-flare: low, medium, high. gpt-image-2.5-sunburst: low to max. Others: fixed. |
background | transparent on VIP, Flare and Sunburst. |
mask | Image URL marking the area to edit. |
MiniMax H3 video
aspectRatio | landscape or portrait. |
resolution | 480p, 768p (default) or 1080p. |
duration | Whole seconds, 1 to 15 (1 to 10 at 1080p). Default 5. Billed per second. |
audios | Up to 3 reference audio clips, URL or base64. |
seed | Integer, for repeatable results. |
Reply types
json waits and returns the finished result. If a job runs past 6 minutes (20 for video) you get it back with status: "running"; poll it with its id.
stream returns text/event-stream with one event per progress change. The last event is the finished result.
data: {"id":"gen_...","status":"running","progress":0}
data: {"id":"gen_...","status":"running","progress":30}
data: {"id":"gen_...","status":"succeeded","progress":100,"results":[{"url":"https://api.xelentapi.com/files/gen_.../0.png","type":"image/png"}],"cost_usd":0.016}
async returns the id straight away. Use it for video and for batches.
# 1. submit
curl https://api.xelentapi.com/v1/api/generate -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"minimax-h3","prompt":"waves at dusk","resolution":"768p","duration":6,"replyType":"async"}'
# → {"id":"gen_...","status":"running"}
# 2. poll every few seconds
curl "https://api.xelentapi.com/v1/api/result?id=gen_..." -H "Authorization: Bearer $API_KEY"
# → {"id":"gen_...","status":"running","progress":40}
# → {"id":"gen_...","status":"succeeded","results":[{"url":"https://api.xelentapi.com/files/gen_.../0.mp4","type":"video/mp4"}],"cost_usd":0.12}
Get a result
GET /v1/api/result?id=gen_... (or POST with {"id": "..."}) returns the current state of a generation made with your account. Results stay available for as long as your files do.
OpenAI-compatible images
POST /v1/images/generations accepts the OpenAI request shape: model, prompt, size, quality, background, response_format (url or b64_json). n must be 1. For Nano Banana models, size is mapped to the nearest aspect ratio.
from openai import OpenAI
client = OpenAI(base_url="https://api.xelentapi.com/v1", api_key=os.environ["API_KEY"])
img = client.images.generate(model="gpt-image-2", prompt="an isometric tiny kitchen", size="1024x1024")
print(img.data[0].url)
Models and balance
GET /v1/models lists every model with its price. GET /v1/account returns your balance and the key's spend.
{"balance_usd": 12.4, "held_usd": 0.05, "key": {"name": "prod", "spent_usd": 3.2, "spend_limit_usd": 50}}
Errors
Errors return a non-2xx status with {"status": "failed", "error": "message", "code": "machine_code"}. You are never charged for an error.
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is missing or not allowed for this model. The message says which. |
| 400 | content_policy_violation | The prompt or a reference image was blocked. |
| 401 | invalid_api_key | Missing, wrong or revoked key. |
| 402 | insufficient_balance | Top up to continue. |
| 402 | key_limit_reached | This key hit the spending limit you set. |
| 403 | account_suspended | Contact support. |
| 429 | rate_limited | More than 120 requests a minute on one key. |
| 429 | too_many_running | Too many jobs running at once on your account. Wait for some to finish. |
| 503 | upstream_unavailable | Temporary. Retry with backoff. |
Limits and files
- 120 requests per minute per key.
- 10 jobs running at once per account by default. Contact us to raise it.
- Request bodies up to 40 MB. Send large reference images as URLs.
- Output files are kept for 7 days. Download anything you want to keep.