Image Generation
Generate brand-new images from a prompt or edit existing ones with a mask.
Some models support native image generation directly in chat completions. When a model has image output capability, it can generate images inline as part of the conversation - no separate endpoint needed.
Native image generation (Chat Completions)
Models with image output capability can generate images directly in the
/v1/chat/completions response. The image appears in message.images
alongside the text content.
Request
Use the standard chat completions endpoint with a model that supports image output:
curl https://api.aivene.com/v1/chat/completions \
-H "Authorization: Bearer $AIVENE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-2.5-flash-image-generation",
"messages": [
{
"role": "user",
"content": "Generate an image of a cute orange cat wearing sunglasses"
}
]
}'Response
The response includes both text and images in the assistant message:
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1715000000,
"model": "gemini-2.5-flash-image-generation",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Here's a cute orange cat wearing sunglasses for you!",
"images": [
{
"type": "image_url",
"image_url": {
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 1300,
"total_tokens": 1312,
"completion_tokens_details": {
"reasoning_tokens": 0,
"image_tokens": 1290,
"audio_tokens": 0
}
}
}Image tokens
Image output tokens are tracked separately in completion_tokens_details.image_tokens.
Using the SDK
import OpenAI from 'openai';
import { writeFile } from 'node:fs/promises';
const client = new OpenAI({
apiKey: process.env.AIVENE_API_KEY,
baseURL: 'https://api.aivene.com/v1'
});
const response = await client.chat.completions.create({
model: 'gemini-2.5-flash-image-generation',
messages: [
{ role: 'user', content: 'Draw a landscape with mountains and a lake' }
]
});
const message = response.choices[0].message;
console.log(message.content);
// Access images (extended field, not in OpenAI types)
const images = (message as any).images;
if (images?.length > 0) {
for (let i = 0; i < images.length; i++) {
const dataUrl = images[i].image_url.url;
const base64 = dataUrl.split(',')[1];
await writeFile(`image-${i}.png`, Buffer.from(base64, 'base64'));
}
}Conversational image editing
Since this works through chat completions, you can have multi-turn conversations to refine images:
const messages = [
{ role: 'user', content: 'Generate an image of a red sports car' }
];
// First generation
let response = await client.chat.completions.create({
model: 'gemini-2.5-flash-image-generation',
messages
});
// Add assistant response to history
messages.push(response.choices[0].message);
// Request modification
messages.push({
role: 'user',
content: 'Make the car blue instead and add a sunset background'
});
// Get modified image
response = await client.chat.completions.create({
model: 'gemini-2.5-flash-image-generation',
messages
});Images API (Dedicated Endpoint)
For standalone image generation without conversation context, use the dedicated images endpoint:
POST /v1/images/generations - JSON in, image out.
This follows the OpenAI image API contract, so the official SDK works without changes.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | Image model id, e.g. gpt-image-1 or dall-e-3. |
prompt | string | yes | Description of the desired image. |
n | integer | no | Number of images. Defaults to 1. |
size | string | no | E.g. '1024x1024', '1792x1024'. Model-dependent. |
quality | string | no | E.g. 'standard', 'hd'. Model-dependent. |
style | string | no | E.g. 'vivid', 'natural'. Model-dependent. |
background | string | no | 'transparent' for supported models. |
response_format | string | no | 'url' (default) or 'b64_json'. |
safety_identifier | string | no | End-user identifier for safety tracking. |
Example
curl https://api.aivene.com/v1/images/generations \
-H "Authorization: Bearer $AIVENE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-1",
"prompt": "Studio photo of an orange tabby cat wearing sunglasses",
"size": "1024x1024",
"n": 1
}'Response:
{
"created": 1715000000,
"data": [
{
"url": "https://cdn.aivene.com/img/abc123.png",
"revised_prompt": "Studio portrait of an orange tabby cat ..."
}
]
}Download URLs are short-lived
Hosted URLs typically expire after 1 hour. Save the bytes or set
response_format: 'b64_json' if you need long-term storage.
Base64 response
{
"model": "gpt-image-1",
"prompt": "A logo for a coffee app",
"response_format": "b64_json"
}Each entry now has a b64_json field instead of url. Decode and write
to disk yourself:
import { writeFile } from 'node:fs/promises';
const res = await client.images.generate({
model: 'gpt-image-1',
prompt: 'A logo for a coffee app',
response_format: 'b64_json'
});
await writeFile('logo.png', Buffer.from(res.data[0].b64_json, 'base64'));Pricing
Native image generation (Chat Completions): Image output tokens are billed separately from text tokens. Check the model's pricing for image output token rate per million tokens.
Images API:
Image endpoints do not bill on tokens. The price depends on model,
size, and quality. See the Console usage page for exact rates per
request.
Safety
Prompts pass through the downstream provider's content filter. Disallowed
prompts return 400 invalid_request_error with the rejection reason in
error.message. The gateway does not silently rewrite prompts - if a
model returns revised_prompt, that came from the provider.
Errors
| Status | error.type | Meaning |
|---|---|---|
400 | invalid_request_error | Prompt rejected, unsupported size, or bad params. |
401 | authentication_error | Missing or invalid API key. |
402 | billing_error | Account out of credit or hit a spend limit. |
413 | invalid_request_error | Image file too large. |
429 | rate_limit_error | RPM exceeded. |
500 | internal_server_error | Unexpected gateway failure. |
502 / 503 | upstream_error | Downstream provider failure. |