Skip to content

Get a generation

client.generations.get(generationID, options?): Generation { id, created_at, model, 6 more }
GET/generations/{generation_id}

Poll for generation status and output. On completion, the response includes presigned URLs to download the generated images. When usage reporting is enabled, usage.credits_charged carries the credits actually charged once billing settles, which can be after the generation reaches a terminal state. Poll with backoff up to a cutoff you choose; some generations keep a null charge permanently.

Parameters
generationID: string
format: uuid
Returns
Generation { id, created_at, model, 6 more }

Generation status and output

id: string

Generation identifier

format: uuid
created_at: string

Creation timestamp

model: Model

Model used

One of the following:
"uni-1"
"uni-1-max"
"ray-3.2"
state: "queued" | "processing" | "completed" | "failed"

Current state of the generation

One of the following:
"queued"
"processing"
"completed"
"failed"
type: "image" | "image_edit" | "video" | 3 more

The kind of generation to perform

One of the following:
"image"
"image_edit"
"video"
"video_edit"
"video_reframe"
"layering"
failure_code?: GenerationFailureCode | null

Machine-readable failure code for programmatic handling

One of the following:
"content_moderated"
"generation_failed"
"budget_exhausted"
"output_not_found"
"image_too_large"
"unsupported_format"
"corrupt_input"
"invalid_request"
"rate_limited"
failure_reason?: string | null

Human-readable failure description

output?: Array<GenerationOutput { type, url, layer } >

Generated outputs (populated on completion)

type: string

Media type (e.g. image, video)

url: string

Presigned URL (1hr expiry)

format: uri
layer?: Layer | null

Per-layer semantics for a type=layering output

alpha_hint: string

Edge treatment of the layer's transparency — soft (hair/fur/glass), hard (solid edges), or none (the opaque background)

description: string

Complete-element caption for the layer's content

index: number

Layer position, front-to-back; the last layer is the background

label: string

Short (1-2 word) layer name

bounds?: Bounds | null

Where a layer's returned pixels sit inside the full composite frame. Layer images are cropped to their visible-alpha bounding box, so layers of one stack have differing pixel dimensions. Composite onto a transparent canvas_width x canvas_height image by pasting each layer at (x, y), iterating the output list in reverse (back-to-front), to reconstruct the source frame.

canvas_height: number

Height of the full composite canvas the layers reassemble into

canvas_width: number

Width of the full composite canvas the layers reassemble into

height: number

Pixel height of the returned layer image

width: number

Pixel width of the returned layer image

x: number

Left offset of this layer's pixels within the composite canvas

y: number

Top offset of this layer's pixels within the composite canvas

contains_text?: boolean | null

Whether the layer was planned as typeset text (a headline, caption, or label) rather than an image element. Null when not reported for this generation.

text?: Text | null

The text on one live-text layer, as a string plus how it is styled. Placement is the owning layer's bounds — the text fills that box.

content: string

The text as shown, preserving capitalization; one line per line (newline-separated)

decorated?: boolean

True when the lettering is ornamental (outlines, patterned fills, bevels, drop shadows), so plain typeset text will not reproduce its look.

font?: Font | null

Described letterform traits of a text layer — enough to pick a matching font.

category: "sans serif" | "serif" | "slab serif" | 6 more

Letterform style

One of the following:
"sans serif"
"serif"
"slab serif"
"display sans"
"display serif"
"display slab"
"display decorative"
"handwriting"
"monospace"
families: Array<string>

Up to three Google Fonts family names that resemble the lettering, closest first. Empty when none of the offered families fit.

italic: boolean

Whether the letters are slanted or cursive

weight: "thin" | "light" | "regular" | 3 more

Stroke weight

One of the following:
"thin"
"light"
"regular"
"medium"
"bold"
"black"
width: "condensed" | "normal" | "wide"

Letter width for its height

One of the following:
"condensed"
"normal"
"wide"
match?: Match

The font in your font catalog that the lettering matches, so you can re-set the text in it. Absent when no catalog font matches closely enough, or matching is not enabled. The image itself is not rendered in this font.

face_id: string

Typed ref of the matched face (one weight and style), font_face:

family_id: string

Typed ref of the matched font family, font_family:

family_name: string

Name of the matched font family

style: "normal" | "italic"

Style of the matched face

One of the following:
"normal"
"italic"
weight: number

CSS font weight of the matched face, e.g. 400 or 700

usage?: GenerationUsage { credits_charged } | null

What one generation actually cost, as billing settled it

credits_charged: number | null

Credits actually charged for this generation. Null until billing has settled it; a confirmed no-charge outcome is 0. Stays null for a generation whose charge could not be confirmed, including ones settled before this field existed. Never an estimate or the reserved amount.

minimum: 0

Get a generation

import Luma from 'luma-agents';
const client = new Luma({
authToken: process.env['LUMA_AGENTS_API_KEY'], // This is the default and can be omitted
});
const generation = await client.generations.get('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');
console.log(generation.id);
200 example
{
"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"created_at": "created_at",
"model": "uni-1",
"state": "queued",
"type": "image",
"failure_code": "content_moderated",
"failure_reason": "failure_reason",
"output": [
{
"type": "type",
"url": "https://example.com",
"layer": {
"alpha_hint": "alpha_hint",
"description": "description",
"index": 0,
"label": "label",
"bounds": {
"canvas_height": 0,
"canvas_width": 0,
"height": 0,
"width": 0,
"x": 0,
"y": 0
},
"contains_text": true,
"text": {
"content": "content",
"decorated": true,
"font": {
"category": "sans serif",
"families": [
"string"
],
"italic": true,
"weight": "thin",
"width": "condensed",
"match": {
"face_id": "face_id",
"family_id": "family_id",
"family_name": "family_name",
"style": "normal",
"weight": 0
}
}
}
}
}
],
"usage": {
"credits_charged": 0
}
}
Returns Examples
200 example
{
"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
"created_at": "created_at",
"model": "uni-1",
"state": "queued",
"type": "image",
"failure_code": "content_moderated",
"failure_reason": "failure_reason",
"output": [
{
"type": "type",
"url": "https://example.com",
"layer": {
"alpha_hint": "alpha_hint",
"description": "description",
"index": 0,
"label": "label",
"bounds": {
"canvas_height": 0,
"canvas_width": 0,
"height": 0,
"width": 0,
"x": 0,
"y": 0
},
"contains_text": true,
"text": {
"content": "content",
"decorated": true,
"font": {
"category": "sans serif",
"families": [
"string"
],
"italic": true,
"weight": "thin",
"width": "condensed",
"match": {
"face_id": "face_id",
"family_id": "family_id",
"family_name": "family_name",
"style": "normal",
"weight": 0
}
}
}
}
}
],
"usage": {
"credits_charged": 0
}
}