Generate Images
April 6, 2026
Table of contents
- Model Compatibility Matrix
- Request Headers
- Request Body
- Responses
- Model
- Webhook Callback (
replyUrl) - Examples
- Try It
Generate images using Luma AI models from text prompts. Each request produces a batch of 4 images. All image generation is asynchronous — this endpoint returns immediately with job IDs. Poll GET /jobs/jobid for completion, or use replyUrl webhook for automatic callbacks.
Each image batch uses 1 concurrency slot regardless of the number of images (4) in the batch.
Image generation typically completes within 30-60 seconds depending on the model and resolution.
Model Compatibility Matrix
photon-v2 (default) | image-v2 | |
|---|---|---|
| Resolutions | 720p, 1080p | 720p, 1080p |
| Image references | up to 4, all resolutions | up to 4, 720p only |
https://api.useapi.net/v1/luma/images
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
API tokenis required, see Setup useapi.net for details.
Request Body
{
"prompt": "A photorealistic portrait of an astronaut on Mars",
"model": "photon-v2",
"resolution": "1080p",
"aspect_ratio": "16:9"
}
promptis required. Text description of the images to generate. Maximum 2000 characters.emailis optional. Specific account to use. Auto-selected (random with available capacity) if omitted. WhenimageRef1..4is provided, the account is automatically inferred from the asset reference —emailis not required. If provided, it must match the asset’s account. All references must belong to the same account.modelis optional, the AI model to use (default:photon-v2). Supported values:photon-v2,image-v2.resolutionis optional, image resolution (default:720p). Supported values:720p,1080p. When usingimage-v2with references, resolution is locked to720p.aspect_ratiois optional, image aspect ratio (default:16:9). Supported values:9:16,3:4,1:1,4:3,16:9,21:9.imageRef1is optional.assetReffrom POST /assets/email— reference image for style/character guidance.imageRef2,imageRef3,imageRef4are optional. Additional reference images (up to 4 total).replyUrlis optional, webhook URL for job status callbacks. Receives POST requests with the job record on submission and on completion/failure.replyRefis optional, custom reference string passed back in webhook callbacks.
Responses
-
Job created successfully. A batch of 4 images is generating in the background.
{ "jobid": "j0326140530123456789i-u12345-email:[email protected]:a1b2c3d4-e5f6-7890-abcd-ef1234567890-bot:luma", "jobids": [ "j0326140530123456789i-u12345-email:[email protected]:b2c3d4e5-f6a7-8901-bcde-f23456789012-bot:luma", "j0326140530123456789i-u12345-email:[email protected]:c3d4e5f6-a7b8-9012-cdef-345678901234-bot:luma", "j0326140530123456789i-u12345-email:[email protected]:d4e5f6a7-b890-1234-defa-456789012345-bot:luma", "j0326140530123456789i-u12345-email:[email protected]:e5f6a7b8-9012-3456-efab-567890123456-bot:luma" ], "type": "image", "status": "created", "count": 4, "created": "2026-03-26T14:05:30.123Z", "request": { "prompt": "A photorealistic portrait of an astronaut on Mars", "model": "photon-v2", "resolution": "1080p", "aspect_ratio": "16:9" } }jobid- Primary job identifier (parent job).jobids- Array of 4 individual image job IDs. Poll each via GET /jobs/jobid.count- Number of images in the batch (always 4).
Poll GET /jobs/
jobidfor each individual image job, or usereplyUrlfor webhook callbacks. -
Validation error.
{ "error": "Parameter model (invalid-model) valid values: photon-v2, image-v2" } -
Invalid API token.
{ "error": "Unauthorized" } -
Subscription expired or insufficient credits.
{ "error": "Account has no subscription or subscription expired" } -
Content moderation rejection.
{ "error": "Content moderation: prompt rejected", "code": 422 } -
All accounts at maximum capacity. Wait for current jobs to complete or use DELETE /jobs/
jobidto free slots.{ "error": "All configured accounts are running at maximum capacity", "code": 429 } -
596 Session Error
Account session expired. Re-add the account using POST /accounts with correct credentials.
{ "error": "Luma account has an error. Please check your account configuration via GET /v1/luma/accounts or re-add the account via POST /v1/luma/accounts" }
Model
{
jobid: string // Primary job identifier
jobids: string[] // Array of 4 individual image job IDs
type: 'image' // Job type
status: 'created' // Initial status
count: 4 // Number of images in batch
created: string // ISO 8601 timestamp
request: {
prompt: string
model: string // "photon-v2" | "image-v2"
resolution?: string // "720p" | "1080p"
aspect_ratio?: string // "9:16" | "3:4" | "1:1" | "4:3" | "16:9" | "21:9"
imageRefs?: string[] // Array of assetRef IDs (when references provided)
}
}
Webhook Callback (replyUrl)
When replyUrl is provided, the API sends a POST request to that URL on completion or failure. The callback wraps individual image results in an images array — overall status is completed if any image in the batch succeeded. See Webhook Callbacks for full type definitions.
Examples
-
curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A photorealistic portrait of an astronaut on Mars", "model": "photon-v2", "resolution": "1080p", "aspect_ratio": "16:9" }' \ "https://api.useapi.net/v1/luma/images" -
const token = 'YOUR_API_TOKEN' const apiUrl = 'https://api.useapi.net/v1/luma/images' const response = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A photorealistic portrait of an astronaut on Mars', model: 'photon-v2', resolution: '1080p', aspect_ratio: '16:9' }) }) const result = await response.json() console.log('Batch created:', result.jobid) console.log('Image jobs:', result.jobids) // Poll each image job for completion const pollJob = async (jobid) => { while (true) { const res = await fetch(`https://api.useapi.net/v1/luma/jobs/${jobid}`, { headers: { 'Authorization': `Bearer ${token}` } }) const job = await res.json() if (job.status === 'completed') { console.log('Image URL:', job.response.image.url) return job } if (job.status === 'failed') throw new Error(job.error) await new Promise(r => setTimeout(r, 5000)) } } const images = await Promise.all(result.jobids.map(pollJob)) -
import requests import time token = 'YOUR_API_TOKEN' api_url = 'https://api.useapi.net/v1/luma/images' headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' } data = { 'prompt': 'A photorealistic portrait of an astronaut on Mars', 'model': 'photon-v2', 'resolution': '1080p', 'aspect_ratio': '16:9' } response = requests.post(api_url, headers=headers, json=data) result = response.json() print(f"Batch created: {result['jobid']}") print(f"Image jobs: {result['jobids']}") # Poll each image job for completion for jobid in result['jobids']: while True: job = requests.get( f'https://api.useapi.net/v1/luma/jobs/{jobid}', headers={'Authorization': f'Bearer {token}'} ).json() print(f"Job {jobid}: {job['status']}") if job['status'] == 'completed': print(f"Image URL: {job['response']['image']['url']}") break if job['status'] == 'failed': raise Exception(job.get('error')) time.sleep(5)