---
updatedAt: 2026-07-10T19:01:19.000Z
---

Fetch the complete documentation index at: https://docs.lumalabs.ai/llms.txt. Use this file to discover all available pages before exploring further.

# Image Generation

<Callout icon="🚀" theme="default">
  ### Looking for the latest Luma API?

  Create and manage API access in the [Luma API Platform](https://platform.lumalabs.ai/). For current API guides and reference, visit the [Luma Agents API documentation](https://docs.agents.lumalabs.ai/).
</Callout>

<Image align="center" width="512px" src="https://framerusercontent.com/assets/3IjOoxs6yoGLBJKel8227Abzc.jpg" />

# Installation

```python
npm install lumaai
```

<https://www.npmjs.com/package/lumaai>

# Authentication

1. Get a key from <https://platform.lumalabs.ai/>

In JavaScript, you can pass the API key using the `authToken` parameter when creating the client

```javascript
const { LumaAI } = require('lumaai');

const client = new LumaAI({
  authToken: process.env.LUMAAI_API_KEY
});
```

# Polling for Generation Status and Retrieving Image

* Right now the only supported way is via polling
* The `create` endpoint returns an id which is an UUID V4
* You can use it to poll for updates (you can see the image at `generation.assets.image`)

### Usage Example

```Text Javascript
npm install node-fetch
```

<br />

```coffeescript Javascript
const fetch = require('node-fetch');
const fs = require('fs');
const { LumaAI } = require('lumaai');

const client = new LumaAI({ authToken: process.env.LUMAAI_API_KEY });

async function generateImage() {
    let generation = await client.generations.image.create({
        prompt: "A teddy bear in sunglasses playing electric guitar and dancing"
    });

    let completed = false;

    while (!completed) {
        generation = await client.generations.get(generation.id);

        if (generation.state === "completed") {
            completed = true;
        } else if (generation.state === "failed") {
            throw new Error(`Generation failed: ${generation.failure_reason}`);
        } else {
            console.log("Dreaming...");
            await new Promise(r => setTimeout(r, 3000)); // Wait for 3 seconds
        }
    }

    const imageUrl = generation.assets.image;

    const response = await fetch(imageUrl);
    const fileStream = fs.createWriteStream(`${generation.id}.jpg`);
    await new Promise((resolve, reject) => {
        response.body.pipe(fileStream);
        response.body.on('error', reject);
        fileStream.on('finish', resolve);
    });

    console.log(`File downloaded as ${generation.id}.jpg`);
}

generateImage();
```

<br />

# Aspect Ratio and Model

For all your requests, you can specify the aspect ratio you want and also the model to be used.

## Aspect ratio

You can choose between the following aspect ratios:

* 1:1
* 3:4
* 4:3
* 9:16
* 16:9 (default)
* 9:21
* 21:9

To use it, simply include a new key under your payload:

```
  prompt: "A teddy bear in sunglasses playing electric guitar and dancing",
  aspect_ratio: "3:4"
```

## Model

You can choose from our two model versions:

* photon-1 (default)
* photon-flash-1

To use it, simply include a new key under your payload:

```
  prompt: "A teddy bear in sunglasses playing electric guitar and dancing",
  model: "photon-flash-1"
```

# Text to Image

```javascript
const generation = await client.generations.image.create({
  prompt: "A teddy bear in sunglasses playing electric guitar and dancing"
});
```

<Image align="center" width="512px" src="https://files.readme.io/35fc85755a99eba889ebd196ed5891b11e52813393249c334c377b6c30e8f2f3-teddy.jpg" />

## With aspect ratio and model

```javascript
const generation = await client.generations.image.create({
    prompt: "A teddy bear in sunglasses playing electric guitar and dancing",
    aspect_ratio: "3:4",
    model: "photon-1"
});
```

<Image align="center" width="256px" src="https://files.readme.io/8ff32db256fc4862b9ef1313f4ea4fc090fc8f3ca9339bfaf8829442b0639480-teddy43.jpg" />

# Image Reference

<Callout icon="☁️" theme="default">
  ### Image URL

  You should upload and use your own cdn image urls, currently this is the only way to pass an image
</Callout>

This feature allows you to guide your generation using a combination between images and prompt. You can use up to 4 images as references. This feature is very useful when you want to create variations of an image or when you have a concept that is hard to describe, but easy to visualize. You can use the `weight` key to tune the influence of the images.

```javascript
const generation = await client.generations.image.create({
    prompt: "sunglasses",
    image_ref: [
      {
        "url": "https://storage.cdn-luma.com/dream_machine/7e4fe07f-1dfd-4921-bc97-4bcf5adea39a/video_0_thumb.jpg",
        "weight": 0.85
      }
    ]
});
```

![](https://files.readme.io/c1c293c4eeaae0ca84562f277cbbe3f18e282d9d10a373f6f1bf2821853c8388-image.png)

# Style Reference

<Callout icon="☁️" theme="default">
  ### Image URL

  You should upload and use your own cdn image urls, currently this is the only way to pass an image
</Callout>

As the name suggests, this feature is used when you want to apply an specific style to your generation. You can use the `weight` key to tune the influence of the style image reference.

```javascript
const generation = await client.generations.image.create({
    prompt: "dog",
    style_ref: [
      {
        "url": "https://staging.storage.cdn-luma.com/dream_machine/400460d3-cc24-47ae-a015-d4d1c6296aba/38cc78d7-95aa-4e6e-b1ac-4123ce24725e_image0c73fa8a463114bf89e30892a301c532e.jpg",
        "weight": 0.8
      }
    ]
});
```

![](https://files.readme.io/a89531b1cd890109b9f5d8571d5de9f1f75d9031c457f00ffb1ce68e7b0aee4f-image.png)

# Character Reference

<Callout icon="☁️" theme="default">
  ### Image URL

  You should upload and use your own cdn image urls, currently this is the only way to pass an image
</Callout>

Character Reference is a feature that allows you to create consistent and personalized characters. Below, you can see how to use it. One thing important to say is that you can use up to 4 images of the same person to build one identity. More images, better the character representation will be.

```javascript
const generation = await client.generations.image.create({
    prompt: "man as a warrior",
    character_ref: {
        "identity0": {
          "images": [
            "https://staging.storage.cdn-luma.com/dream_machine/400460d3-cc24-47ae-a015-d4d1c6296aba/38cc78d7-95aa-4e6e-b1ac-4123ce24725e_image0c73fa8a463114bf89e30892a301c532e.jpg"
          ]
        }
      }
});
```

![](https://files.readme.io/9d569454df4b42bb8db22b53871d95071ed89d61b34bf9ab30df89a19783a563-image.png)

<br />

# Modify Image

<Callout icon="☁️" theme="default">
  ### Image URL

  You should upload and use your own cdn image urls, currently this is the only way to pass an image
</Callout>

> 🚧 Changing colors of images
>
> This feature works really well to change objects, shapes, etc. But when it comes to changing colors, it is harder to get it right. One recommendation is to use a lower `weight` value, something between 0.0 and 0.1.

Modify feature allows you to refine your images by simply prompting what change you want to make. You can use the `weight` key to specify the influence of the input image. Higher the weight, closer to the input image but less diverse (and creative).

```javascript
const generation = await client.generations.image.create({
    prompt: "transform all the flowers to sunflowers",
    modify_image_ref: {
      "url": "https://staging.storage.cdn-luma.com/dream_machine/400460d3-cc24-47ae-a015-d4d1c6296aba/38cc78d7-95aa-4e6e-b1ac-4123ce24725e_image0c73fa8a463114bf89e30892a301c532e.jpg",
      "weight": 1.0
    }
});
```

![](https://files.readme.io/548527a1f9856d3973efabb3123631c7c13e739f2aef670a89667200a7043489-image.png)

# Generations

## Get generation with id

```coffeescript Javascript
const generation = await client.generations.get("4fac0ef4-b336-45bf-a5dc-6de436cfbd62");
```

## List all generations

```coffeescript Javascript
const generation = await client.generations.list();
```

## Delete generation

```coffeescript Javascript
const generation = await client.generations.delete("4fac0ef4-b336-45bf-a5dc-6de436cfbd62");
```

# Docs

<https://www.npmjs.com/package/lumaai>

Please see [API](./api) docs for API reference.

<br />

# How to get a callback when generation has an update

* It will get status updates (dreaming/completed/failed)
* It will also get the video url as part of it when completed
* It's a `POST` endpoint you can pass, and request body will have the generation [object](https://github.com/lumalabs/lumaai-api/blob/35768db34e52600e319cb799e4488249e61eef17/openapi.yaml#L258) in it
* It expected to be called multiple times for a status
* If the endpoint returns a status code other than 200, it will be retried max 3 times with 100ms delay and the request has a 5s timeout

example

```typescript
const generation = await client.generations.create({
  prompt: "A teddy bear in sunglasses playing electric guitar and dancing",
  callback_url: "<your_api_endpoint_here>"
});
```