References and assets

Guide a generation with a previous generation, an uploaded asset, or inline media.

How-to guide · Assumes you have completed the Image & Video quickstart.

Overview

Most Image & Video models accept media alongside the prompt: a first frame for a video, images to edit, audio to lip-sync against. Every media-valued field on the API takes a reference object rather than raw bytes in a fixed shape, and each reference is tagged with a type that says where the media comes from.

typePoints atFields
generationThe output of an earlier generation.generation_id
assetA file uploaded to the assets API.asset_id
inline_base64Media encoded directly into the request body.content_base64, mime_type

The three kinds are interchangeable wherever a reference is accepted, so the same field can take a generation on one request and an uploaded asset on the next.

Chain one generation into the next

A generation reference is the cheapest way to build a pipeline: nothing is uploaded, and the output of the first generation is used directly as the input of the second. This example generates a still image, then animates it as the first frame of a video.

1import time
2
3from elevenlabs import (
4 ImageGenerationRequest_Gemini3ProImage,
5 ImageReference_Generation,
6 VideoGenerationRequest_Veo31FastGenerate001,
7)
8
9
10def wait_for(client, generation_id):
11 while True:
12 result = client.flows.image.get(generation_id)
13 if result.status in ("completed", "failed"):
14 return result
15 time.sleep(2)
16
17
18still = elevenlabs.flows.image.create(
19 request=ImageGenerationRequest_Gemini3ProImage(
20 prompt="A lighthouse on a cliff at dawn, heavy fog rolling in from the sea",
21 aspect_ratio="16:9",
22 )
23)
24wait_for(elevenlabs, still.id)
25
26clip = elevenlabs.flows.video.create(
27 request=VideoGenerationRequest_Veo31FastGenerate001(
28 prompt="The fog thickens and the beam sweeps across the water",
29 start_frame=ImageReference_Generation(generation_id=still.id),
30 duration_secs=8,
31 )
32)

If the referenced generation has not completed, the dependent generation fails with a dependency_failed reason, so wait for the first generation before submitting the second.

Upload media as an asset

Upload a file to the assets API when the media comes from outside ElevenLabs and you want to reuse it across generations. Assets belong to the workspace and persist until you delete them.

1from elevenlabs import ImageReference_Asset, VideoGenerationRequest_Veo31FastGenerate001
2
3with open("lighthouse.png", "rb") as f:
4 asset = elevenlabs.assets.create(asset=f, name="lighthouse.png")
5
6print(asset.asset_id)
7
8clip = elevenlabs.flows.video.create(
9 request=VideoGenerationRequest_Veo31FastGenerate001(
10 prompt="The beam sweeps across the water as the fog thickens",
11 start_frame=ImageReference_Asset(asset_id=asset.asset_id),
12 )
13)

The upload response describes the stored asset:

1{
2 "asset_id": "5xM2KqOnZyce22SPZ9d4",
3 "name": "lighthouse.png",
4 "mime_type": "image/png",
5 "created_at_unix": 1721520000,
6 "content_url": "https://storage.googleapis.com/assets/5xM2KqOnZyce22SPZ9d4"
7}

content_url is a signed URL valid for about an hour, and is null while the upload is still being processed. Fetch the asset again for a fresh URL.

Reaching the assets API with an API key requires a Pro plan or above, the same tier as the generation endpoints.

Storage limits

Uploaded assets count against a total storage limit for the workspace, which depends on your plan:

PlanAsset storage
Pro11 GB
Scale33 GB
Business111 GB
Enterprise333 GB

Only the files you upload count toward the limit; generated outputs do not. An upload that would take the workspace over its limit is rejected with an asset_storage_limit_exceeded error before the file is read. Delete assets you no longer need to free space, or contact support to have the limit raised.

Manage assets

List assets newest first, optionally filtering by name, and page through results with the cursor from the previous response. page_size accepts 1 to 100 and defaults to 30.

1page = elevenlabs.assets.list(page_size=20, search="lighthouse")
2
3for asset in page.assets:
4 print(asset.asset_id, asset.name, asset.mime_type)
5
6if page.has_more:
7 page = elevenlabs.assets.list(page_size=20, search="lighthouse", cursor=page.next_cursor)

Retrieve or delete a single asset by ID. Deleting an asset does not affect generations that already used it.

1asset = elevenlabs.assets.get("5xM2KqOnZyce22SPZ9d4")
2elevenlabs.assets.delete("5xM2KqOnZyce22SPZ9d4")

Pass media inline

An inline_base64 reference carries the media in the request body, which avoids a separate upload for one-off inputs. Encode the file with the standard base64 alphabet and declare its MIME type.

1import base64
2
3from elevenlabs import ImageGenerationRequest_GptImage2, ImageReference_InlineBase64
4
5with open("headshot.jpg", "rb") as f:
6 encoded = base64.b64encode(f.read()).decode()
7
8generation = elevenlabs.flows.image.create(
9 request=ImageGenerationRequest_GptImage2(
10 prompt="Replace the background with a softly lit studio backdrop",
11 images=[
12 ImageReference_InlineBase64(
13 content_base64=encoded,
14 mime_type="image/jpeg",
15 )
16 ],
17 )
18)

Inline media is stored as an ephemeral asset with no retention guarantee and may be deleted once the generation completes. Upload the file to the assets API instead when you need to reference the same input more than once.

Inline content is capped at 25MB per reference after decoding. Larger files belong on the assets API, which accepts much bigger uploads and does not pay the base64 size penalty. Each modality accepts a fixed set of MIME types:

ReferenceAccepted mime_type
Imageimage/jpeg, image/png, image/webp, image/heic, image/heif
Audioaudio/mpeg, audio/wav
Videovideo/mp4, video/quicktime, video/webm

Reference fields by model

Reference fields are named for the role the media plays. start_frame and end_frame are single images that bound a video, image and audio are the required inputs of a lip-sync model, and the bare plurals images, videos, and audios are free-form reference material the model draws from.

Which fields a model accepts, and which combinations are valid, differ per model. An end_frame always requires a start_frame. Violating a constraint returns a validation error naming the offending field, so the generation never starts and is never charged.

Veo 3.1

Both Veo models accept start_frame, end_frame, and up to three entries in images. Unlike other models, each entry in images wraps the reference together with the role it plays:

1{
2 "images": [
3 {
4 "image": { "type": "asset", "asset_id": "5xM2KqOnZyce22SPZ9d4" },
5 "role": "subject"
6 },
7 {
8 "image": { "type": "asset", "asset_id": "7pQ4LnBvXkR2mT9wYcHd" },
9 "role": "style"
10 }
11 ]
12}

A subject reference places the image’s subject or scene elements into the video; a style reference transfers its visual style. Reference images cannot be combined with start_frame or end_frame, and require the eight-second duration.

Seedance

The ByteDance models are disabled by default and require explicit approval before use. Contact support to request access.

The three Seedance 2.0 tiers accept start_frame, end_frame, up to 9 images, up to 3 videos, and up to 3 audios, subject to these constraints:

  • References cannot be combined with start_frame or end_frame.
  • Reference audio requires at least one reference image or video, for example to drive lip-sync.
  • The combined number of reference files must not exceed 12.

Seedance 2.5 raises the caps to 30 images, 10 videos, and 10 audios with no combined total, and drops the rule that reference audio needs an accompanying image or video, so audio-only input is accepted. References still cannot be combined with start_frame or end_frame.

GPT Image

The GPT Image models accept a mask alongside images. Fully transparent areas of the mask mark where the first reference image may be edited. A mask without reference images is rejected.

Next steps