Generate Images

April 6, 2026

Table of contents

  1. Model Compatibility Matrix
  2. Request Headers
  3. Request Body
  4. Responses
  5. Model
  6. Webhook Callback (replyUrl)
  7. Examples
  8. 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

Request Body

{
  "prompt": "A photorealistic portrait of an astronaut on Mars",
  "model": "photon-v2",
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}
  • prompt is required. Text description of the images to generate. Maximum 2000 characters.
  • email is optional. Specific account to use. Auto-selected (random with available capacity) if omitted. When imageRef1..4 is provided, the account is automatically inferred from the asset reference — email is not required. If provided, it must match the asset’s account. All references must belong to the same account.
  • model is optional, the AI model to use (default: photon-v2). Supported values: photon-v2, image-v2.
  • resolution is optional, image resolution (default: 720p). Supported values: 720p, 1080p. When using image-v2 with references, resolution is locked to 720p.
  • aspect_ratio is optional, image aspect ratio (default: 16:9). Supported values: 9:16, 3:4, 1:1, 4:3, 16:9, 21:9.
  • imageRef1 is optional. assetRef from POST /assets/email — reference image for style/character guidance.
  • imageRef2, imageRef3, imageRef4 are optional. Additional reference images (up to 4 total).
  • replyUrl is optional, webhook URL for job status callbacks. Receives POST requests with the job record on submission and on completion/failure.
  • replyRef is optional, custom reference string passed back in webhook callbacks.

Responses

  • 200 OK

    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/jobid for each individual image job, or use replyUrl for webhook callbacks.

  • 400 Bad Request

    Validation error.

    {
      "error": "Parameter model (invalid-model) valid values: photon-v2, image-v2"
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "Unauthorized"
    }
    
  • 402 Payment Required

    Subscription expired or insufficient credits.

    {
      "error": "Account has no subscription or subscription expired"
    }
    
  • 422 Unprocessable Entity

    Content moderation rejection.

    {
      "error": "Content moderation: prompt rejected",
      "code": 422
    }
    
  • 429 Too Many Requests

    All accounts at maximum capacity. Wait for current jobs to complete or use DELETE /jobs/jobid to 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)
    

Try It