> ## Documentation Index
> Fetch the complete documentation index at: https://www.tella.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Media library API

> Upload reusable media, browse Tella's curated sound effects and background music, and reuse them across your videos.

The media library API lets you keep images, videos, and sound effects available independently of any one video. You can also browse Tella's curated sound effects and background music without uploading your own audio. Library items appear in the same **Media library**, **Sound effects** and **Background music** panels used in the Tella editor.

## Upload and save media

Saving new media is a three-step process:

1. Create a source with `POST /v1/sources`.
2. Upload the file bytes to the returned `uploadUrl` before it expires.
3. Save the returned `sourceId` with `POST /v1/library`.

#### Create a source

Include `width` and `height` for an image or video. Include `duration` in seconds for a video or audio file.

```bash theme={null}
curl -X POST https://api.tella.com/v1/sources \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "video",
    "width": 1920,
    "height": 1080,
    "duration": 12.4
  }'
```

The response contains a `sourceId`, an `uploadUrl`, and the time when that upload URL expires.

#### Upload the file

Upload the original file as a single `PUT` request. Common image, video, and audio formats are accepted.

```bash theme={null}
curl -X PUT "UPLOAD_URL" --upload-file ./intro.mp4
```

#### Add the source to the library

Use `private` for media only you can access, or `workspace` to share it with everyone in your workspace. If you omit `scope`, the item is saved to your private library.

```bash theme={null}
curl -X POST https://api.tella.com/v1/library \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceId": "su_abc123def456",
    "name": "Product intro",
    "scope": "workspace"
  }'
```

Tella infers whether the item is an image, video, or sound effect from the source. You can optionally send `type` to verify the expected type; the request fails if it does not match the source.

<Note>
  Adding items to a workspace library requires an owner or member role. Workspace viewers can list shared items but cannot add or remove them.
</Note>

## List saved media

List the private and workspace libraries separately by setting the required `scope` query parameter:

```bash theme={null}
curl "https://api.tella.com/v1/library?scope=workspace&type=video&limit=24" \
  -H "Authorization: Bearer $TELLA_API_KEY"
```

You can filter by `image`, `video`, `sound-effect`, `music`, or `lut`. When the response includes a `cursor`, pass it in the next request and continue until no cursor is returned.

<Note>
  `limit` is a target page size. A response can contain slightly more items because Tella reads a storage page before filtering unavailable items. Follow `cursor` rather than relying on the item count.
</Note>

## Browse curated sound effects

Set `scope` to `default` to list the same curated sound effects available in the editor:

```bash theme={null}
curl "https://api.tella.com/v1/library?scope=default&type=sound-effect" \
  -H "Authorization: Bearer $TELLA_API_KEY"
```

Each item includes a `presetId`, `category`, `durationMs`, and a public `url` you can use to preview the audio. The catalog is returned as one page without a `cursor`.

Use the `presetId` to add an effect to a clip without creating or uploading a source:

```bash theme={null}
curl -X POST \
  "https://api.tella.com/v1/videos/vid_abc123/clips/cl_abc123/sound-effects" \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "presetId": "cha-ching",
    "startTimeMs": 2000,
    "durationMs": 1680
  }'
```

Pass exactly one of `presetId` or `sourceId`. Use the item's `durationMs` to play the full effect.

## Browse curated background music

Set `scope` to `default` and `type` to `music` to list the same curated tracks available in the editor's background music panel:

```bash theme={null}
curl "https://api.tella.com/v1/library?scope=default&type=music" \
  -H "Authorization: Bearer $TELLA_API_KEY"
```

Each item includes a `presetId`, `category` (`Calm`, `Energetic`, `Focused` or `Playful`), `durationMs`, and a public `url` you can use to preview the track. Omitting `type` returns sound effects and music together.

Use the `presetId` to set the video's background music without creating or uploading a source:

```bash theme={null}
curl -X PUT "https://api.tella.com/v1/videos/vid_abc123/background-music" \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "presetId": "calm-product-tour",
    "volume": 0.2
  }'
```

Pass exactly one of `presetId` or `sourceId`. The track's name defaults to the preset's name.

<Note>
  The default catalog contains sound effects and music only and is read-only. Use `private` or `workspace` when adding or removing your own library items.
</Note>

## Reuse a library item

Items added through the API include a `sourceId`. Pass it to any compatible endpoint, including clips, layouts, overlays, backgrounds, and sound effects. API-added images also include a hosted `url`, but use their `sourceId` when placing them in a video.

Images uploaded in the editor may return only a hosted `url`. Without a `sourceId`, those images can be used in the editor but cannot be placed through the public API. Saved videos, sound effects and AI-generated items include a `sourceId`; curated sound effects and music tracks use `presetId` instead. Music and LUT items saved from the editor return a hosted URL instead of a source ID.

<Tip>
  Save a source to the library as soon as you want to reuse it. A source that is not saved still exists after its video is deleted, but it may no longer be discoverable through the API.
</Tip>

## Generate media with AI

When there is nothing to upload, generate it. `POST /v1/library/generations` starts the same AI image or sound effect generator the editor's media panels use, and saves the result as a private library item.

```bash theme={null}
curl -X POST https://api.tella.com/v1/library/generations \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "image",
    "prompt": "A watercolor illustration of a lighthouse at dawn"
  }'
```

The response is `202 Accepted` with a `generation` whose `id` is the library item being filled in, plus your weekly allowance (`limit`, `remaining`, `resetAt`). Pass `"type": "sound-effect"` for a sound effect. For an image, an optional `referenceSourceId` — the `sourceId` of an image source you uploaded, or of an `image` library item — guides the generation.

Generation is asynchronous. Poll `GET /v1/library/generations/{id}` every few seconds (images usually take 30-90 seconds, sound effects 10-30) until `status` is `completed`:

```bash theme={null}
curl "https://api.tella.com/v1/library/generations/mi_abc123def456" \
  -H "Authorization: Bearer $TELLA_API_KEY"
```

On `completed`, `generation.item` is the finished library item. Pass its `sourceId` anywhere a source is accepted — an image overlay, a layout's b-roll `media`, or a clip's sound effects — and it also appears in `GET /v1/library?scope=private`.

On `failed`, `generation.error` provides a sanitized, human-readable reason. It may identify a content-safety rejection or timeout, or report a generic failure. Do not parse this text for machine handling. A failed generation cannot be resumed, so start a new one.

<Note>
  Each generation counts against your plan's weekly AI generation allowance, the same one the editor uses. Once it is exhausted the endpoint answers `403` with the reset time in the message.
</Note>

## Remove a library item

Pass both the library item ID and its scope:

```bash theme={null}
curl -X DELETE \
  "https://api.tella.com/v1/library/media_abc123def456?scope=workspace" \
  -H "Authorization: Bearer $TELLA_API_KEY"
```

Removing a library item removes only its entry from the library. Existing clips and videos that use the underlying source continue to work.

<Card title="Library API reference" icon="photo-film" href="/docs/api-reference/library/list-library-items">
  Review all request parameters and response fields for the library endpoints.
</Card>


## Related topics

- [Public API and webhooks](/docs/help/integrations/public-api-and-webhooks.md)
- [Product Changelog](/docs/changelog.md)
- [Add media (B-roll)](/docs/help/editing/use-media.md)
- [Remix & reuse videos and clips](/docs/help/editing/remix-and-reuse-videos-and-clips.md)
- [Library](/docs/mcp-tools/library.md)
