Image Generation
Generate AI images from text prompts via API, with optional reference images provided as URLs or base64-encoded inline data.
Generate Image
POST /v1/images/generation
Generate an AI image from a text prompt. Optionally supply reference images to guide the style or content of the output. The response streams the raw model output (JSON containing base64 image data).
Basic Generation
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"prompt": "A serene mountain landscape at sunset with a reflective lake",
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K"
}
}'const response = await fetch('https://api.marswave.ai/openapi/v1/images/generation', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
prompt: 'A serene mountain landscape at sunset with a reflective lake',
imageConfig: {
aspectRatio: '16:9',
imageSize: '2K',
},
}),
});
const data = await response.json();
// data.candidates[0].content.parts[0].inlineData contains the generated imageimport os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'prompt': 'A serene mountain landscape at sunset with a reflective lake',
'imageConfig': {
'aspectRatio': '16:9',
'imageSize': '2K',
},
}
)
data = response.json()
# data['candidates'][0]['content']['parts'][0]['inlineData'] contains the generated imageTo use GPT-Image-2, set provider to "openai" and model to "gpt-image-2". The request and response format is the same — only provider, model, and the imageConfig differ. See the Model Comparison table for details.
Generation with Reference Images
Supply reference images to guide the output. Each reference image can be provided as either a URL (fileData) or base64-encoded inline data (inlineData). You can mix both formats in a single request.
Using Image URLs
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"prompt": "Transform this scene into a watercolor painting style",
"referenceImages": [
{
"fileData": {
"fileUri": "https://example.com/my-photo.jpg",
"mimeType": "image/jpeg"
}
}
],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "2K"
}
}'const response = await fetch('https://api.marswave.ai/openapi/v1/images/generation', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
prompt: 'Transform this scene into a watercolor painting style',
referenceImages: [
{
fileData: {
fileUri: 'https://example.com/my-photo.jpg',
mimeType: 'image/jpeg',
},
},
],
imageConfig: {
aspectRatio: '1:1',
imageSize: '2K',
},
}),
});
const data = await response.json();import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'prompt': 'Transform this scene into a watercolor painting style',
'referenceImages': [
{
'fileData': {
'fileUri': 'https://example.com/my-photo.jpg',
'mimeType': 'image/jpeg',
}
}
],
'imageConfig': {
'aspectRatio': '1:1',
'imageSize': '2K',
},
}
)
data = response.json()Using Base64 Inline Data
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"prompt": "Create a cartoon version of this portrait",
"referenceImages": [
{
"inlineData": {
"data": "<BASE64_ENCODED_IMAGE>",
"mimeType": "image/png"
}
}
]
}'import { readFileSync } from 'fs';
const imageBase64 = readFileSync('reference.png').toString('base64');
const response = await fetch('https://api.marswave.ai/openapi/v1/images/generation', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
prompt: 'Create a cartoon version of this portrait',
referenceImages: [
{
inlineData: {
data: imageBase64,
mimeType: 'image/png',
},
},
],
}),
});
const data = await response.json();import os
import base64
import requests
with open('reference.png', 'rb') as f:
image_base64 = base64.b64encode(f.read()).decode('utf-8')
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'prompt': 'Create a cartoon version of this portrait',
'referenceImages': [
{
'inlineData': {
'data': image_base64,
'mimeType': 'image/png',
}
}
],
}
)
data = response.json()Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Model provider: google or openai |
model | string | No | Model name: gemini-3-pro-image-preview (default), gemini-3.1-flash-image-preview, or gpt-image-2 (requires provider: "openai") |
prompt | string | Yes | Text description of the image to generate |
referenceImages | array | No | Reference images to guide generation. Max 14 for Gemini models, max 4 for GPT-Image-2 |
referenceImages[].fileData | object | No | Reference image as a URL |
referenceImages[].fileData.fileUri | string | Yes | Image URL (http, https, or gs scheme) |
referenceImages[].fileData.mimeType | string | Yes | MIME type: image/png, image/jpeg, image/webp, image/heic, or image/heif |
referenceImages[].inlineData | object | No | Reference image as base64-encoded data |
referenceImages[].inlineData.data | string | Yes | Base64-encoded image data |
referenceImages[].inlineData.mimeType | string | Yes | MIME type: image/png, image/jpeg, image/webp, image/heic, or image/heif |
imageConfig | object | No | Image output configuration |
imageConfig.imageSize | string | No | Output resolution: 1K, 2K (default), or 4K. For GPT-Image-2 credit costs see the Image Size Tiers table |
imageConfig.aspectRatio | string | No | Aspect ratio (see table below). Optional for GPT-Image-2 — omit to let the model choose automatically |
Each item in referenceImages must contain exactly one of fileData or inlineData, not both.
Supported Aspect Ratios
| Ratio | Description |
|---|---|
1:1 | Square |
2:3 | Portrait |
3:2 | Landscape |
3:4 | Portrait |
4:3 | Landscape |
9:16 | Vertical / mobile |
16:9 | Widescreen |
21:9 | Ultra-wide |
The gemini-3.1-flash-image-preview model supports additional aspect ratios (1:4, 4:1, 1:8, 8:1) that are not available with the default gemini-3-pro-image-preview model.
Image Size Tiers
GPT-Image-2 uses a tiered credit system based on output resolution:
| Size | Tier | Credits | Free Trial |
|---|---|---|---|
1K | Standard | 4 | Yes (100 uses per user) |
2K | HD | 6 | Yes (100 uses per user) |
4K | Ultra HD | 10 | No |
Model Comparison
| Model | Strengths | Notes |
|---|---|---|
gemini-3-pro-image-preview | Higher quality, more detailed output | Default model |
gemini-3.1-flash-image-preview | Faster generation, supports extra aspect ratios | Good for iterative workflows |
gpt-image-2 | OpenAI's latest image model, strong prompt following | Max 4 reference images, supports all standard aspect ratios, aspectRatio is optional (auto mode) |
Response
The response streams the raw model output as JSON. A successful response contains the generated image as base64 data:
{
"candidates": [
{
"content": {
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": "<BASE64_ENCODED_IMAGE>"
}
}
]
}
}
]
}Decode the data field from base64 to obtain the image file.
Rate Limiting and Reference Image Mode
Standard text-to-image requests are subject to per-user and global rate limits.
Reference image mode (referenceImages with inlineData) is subject to additional server-side resource constraints. During peak usage periods, requests may be throttled more aggressively. If you receive a 429 Too Many Requests response, wait a short period before retrying. We recommend implementing exponential backoff in your client.
Error Codes
| HTTP Status | Meaning |
|---|---|
400 | Invalid request parameters (e.g., unsupported aspect ratio for the selected model) |
402 | Insufficient credits |
429 | Rate limit exceeded — retry after a short wait |
500 | Image generation failed — retry the request |