---
title: "Generate media with AI"
method: POST
path: "/v1/library/generations"
tags: ["Library"]
---

# Generate media with AI

`POST /v1/library/generations`

Starts generating an image or a sound effect from a text prompt with the same AI generators the editor's media panels use. Generation is asynchronous: the response is a `generation` whose `id` is the private library item the result is saved as. Poll `GET /v1/library/generations/{id}` every few seconds (images usually take 30-90 seconds, sound effects 10-30) until `status` is `completed`, then pass `item.sourceId` anywhere a source is accepted — `POST /v1/videos/{id}/clips/{clipId}/overlays` for an image overlay, `POST /v1/videos/{id}/clips/{clipId}/layouts` with `media` for b-roll, `POST /v1/videos/{id}/clips/{clipId}/sound-effects` for a sound effect. The finished item also appears in `GET /v1/library?scope=private`. Each generation counts against the caller's weekly AI generation allowance, which depends on the plan; exceeding it answers 403 with the reset time.

## Request body

- CreateGenerationRequest — Start generating media from a prompt
  - `prompt` string, required — What to generate. Up to 4000 characters for an image, 2000 for a sound effect.
  - `referenceSourceId` string — For `image` only: the `sourceId` of an image source to guide the generation — from `POST /v1/sources` (`kind: "image"`) after uploading the bytes, or an `image` library item's `sourceId`.
  - `type` 'image' | 'sound-effect', required — The kind of media to generate

## Response `202`

Accepted

- CreateGenerationResponse — The generation that was started, plus the weekly allowance
  - `generation` Generation, required — An AI media generation and, once finished, its library item
    - `error` string — A sanitized, human-readable reason when `status` is `failed`. It may identify a content-safety rejection or timeout, or report a generic failure. Do not parse this text for machine handling.
    - `id` string, required — Generation ID. It is also the ID of the private library item the result is saved as, so it can be passed to `GET /v1/library/generations/{id}` to poll and shows up in `GET /v1/library?scope=private` once finished.
    - `item` LibraryItem — A placeable piece of media — either saved to a workspace's library, or an entry in Tella's curated catalog
      - `category` string — Catalog grouping, for `default` items only — the same grouping the editor's sound effects and background music panels show
      - `createdAt` string — ISO-8601 creation timestamp. Absent for `default` catalog items, which are served from Tella's catalog rather than stored as rows.
      - `dimensions` object — Pixel dimensions, for visual media
        - `height` integer, required
        - `width` integer, required
      - `durationMs` number — Duration in milliseconds, for time-based media
      - `id` string, required — Unique library item identifier
      - `name` string, required — Display name shown in the library
      - `presetId` string — Preset ID, for `default` catalog items only. A preset has no source, so pass this instead of `sourceId`: a `sound-effect` preset goes to `POST /v1/videos/{id}/clips/{clipId}/sound-effects` (placing it copies the effect into a source owned by your workspace), a `music` preset to `PUT /v1/videos/{id}/background-music`.
      - `scope` 'private' | 'workspace' | 'default', required — Which set of media to read: `private` (only visible to their creator), `workspace` (shared with everyone in the workspace), or `default` (Tella's curated sound effect and background music catalogs, which hold no other media type)
      - `sourceId` string — Source ID. Pass it anywhere a `sourceId` is accepted — clips, layouts, overlays, sound effects. Present for every item added through this API, including images. Absent for items added in the editor, which have no source, for music and LUT items, and for `default` catalog items, which use `presetId` instead.
      - `type` 'image' | 'video' | 'sound-effect' | 'music' | 'lut' | 'screenshot', required — The kind of media the item holds
      - `updatedAt` string — ISO-8601 update timestamp. Absent for `default` catalog items.
      - `url` string — Hosted media URL, for `image`, `screenshot`, `music` and `lut` items, and for `default` catalog items, where it is a publicly fetchable preview of the audio (for `music` presets it is also the track the video will play). API-created images expose this alongside `sourceId`; use `sourceId` to place the image on a clip, since overlays and layout media do not accept URLs. Editor-created `screenshot` items have a URL but no sourceId; use POST /v1/library/screenshots to capture a new placeable image or video.
    - `prompt` string, required — The prompt the media is being generated from
    - `status` 'pending' | 'running' | 'completed' | 'failed', required — `pending` and `running` mean the generator is still working — poll again in a few seconds. `completed` means `item` is ready to place. `failed` is final; start a new generation.
    - `type` 'image' | 'sound-effect', required — The kind of media to generate
  - `limit` integer, required — The caller's weekly AI generation allowance for this media type, which depends on the plan
  - `remaining` integer, required — Generations left in the current week, after this one
  - `resetAt` number, required — When the weekly allowance resets, as a millisecond epoch

## Other responses

- `400` — The request was malformed or contained invalid parameters.
- `401` — Authentication is required. Provide a valid API key.
- `403` — You don't have permission to access this resource.
- `404` — The requested resource was not found.
- `409` — The request conflicts with the resource's current state, e.g. an Idempotency-Key whose first request is still in progress. Retry once it settles.
- `429` — You have exceeded the rate limit. Please slow down.
- `500` — An unexpected error occurred
- `501` — The requested operation is not implemented.
- `503` — A dependency was unavailable and the request was not executed. Safe to resend unchanged after the Retry-After delay.

## Changes

> 20 revisions in range; 1 not diffed.

- **2026-09-28** `ac47c99c144f` — 9 warning
  - added the new `edit_conflict` enum value to the `error` response property for the response status `400`
  - added the new `edit_conflict` enum value to the `error` response property for the response status `401`
  - added the new `edit_conflict` enum value to the `error` response property for the response status `403`
  - added the new `edit_conflict` enum value to the `error` response property for the response status `404`
  - …5 more
- **2026-09-19** `64764729bd60` — 1 warning
  - added the new `screenshot` enum value to the `generation/item/allOf[#/components/schemas/LibraryItem]/type` response property for the response status `202`
- **2026-09-10** `2740bcedaa3b` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/withchima/apis/tella-public-api/changes/v1/library/generations/post.md)

---

[API](https://skmtc.dev/withchima/apis/tella-public-api.md) · [All operations](https://skmtc.dev/withchima/apis/tella-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/withchima/apis/tella-public-api/revisions/d3eafbc27bf9?raw)
