curl --request POST \
--url https://api.tella.com/v1/library/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "A watercolor illustration of a lighthouse at dawn",
"type": "image",
"model": "flare",
"referenceSourceId": "su_abc123def456"
}
'import requests
url = "https://api.tella.com/v1/library/generations"
payload = {
"prompt": "A watercolor illustration of a lighthouse at dawn",
"type": "image",
"model": "flare",
"referenceSourceId": "su_abc123def456"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: 'A watercolor illustration of a lighthouse at dawn',
type: 'image',
model: 'flare',
referenceSourceId: 'su_abc123def456'
})
};
fetch('https://api.tella.com/v1/library/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tella.com/v1/library/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'A watercolor illustration of a lighthouse at dawn',
'type' => 'image',
'model' => 'flare',
'referenceSourceId' => 'su_abc123def456'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.tella.com/v1/library/generations"
payload := strings.NewReader("{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.tella.com/v1/library/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/library/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}"
response = http.request(request)
puts response.read_body{
"generation": {
"id": "mi_abc123def456",
"prompt": "A watercolor illustration of a lighthouse at dawn",
"status": "completed",
"type": "image",
"error": "<string>",
"item": {
"id": "media_abc123def456",
"name": "Intro camera take",
"scope": "private",
"type": "video",
"category": "Everyday",
"createdAt": "<string>",
"dimensions": {
"height": 0,
"width": 0
},
"durationMs": 4200,
"presetId": "cha-ching",
"sourceId": "su_abc123def456",
"updatedAt": "<string>",
"url": "<string>"
}
},
"limit": 20,
"remaining": 19,
"resetAt": 1760000000000
}{
"docsUrl": "https://docs.tella.com/",
"error": "bad_request",
"message": "The request was malformed or contained invalid parameters."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unauthorized",
"message": "Authentication is required. Provide a valid API key."
}{
"docsUrl": "https://docs.tella.com/",
"error": "forbidden",
"message": "You don't have permission to access this resource."
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_found",
"message": "The requested resource was not found."
}{
"docsUrl": "https://docs.tella.com/",
"error": "conflict",
"message": "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."
}{
"docsUrl": "https://docs.tella.com/",
"error": "rate_limited",
"message": "You have exceeded the rate limit. Please slow down."
}{
"docsUrl": "https://docs.tella.com/",
"error": "server_error",
"message": "An unexpected error occurred"
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_implemented",
"message": "The requested operation is not implemented."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unavailable",
"message": "A dependency was unavailable and the request was not executed. Safe to resend unchanged after the Retry-After delay."
}Generate media with AI
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.
curl --request POST \
--url https://api.tella.com/v1/library/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "A watercolor illustration of a lighthouse at dawn",
"type": "image",
"model": "flare",
"referenceSourceId": "su_abc123def456"
}
'import requests
url = "https://api.tella.com/v1/library/generations"
payload = {
"prompt": "A watercolor illustration of a lighthouse at dawn",
"type": "image",
"model": "flare",
"referenceSourceId": "su_abc123def456"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: 'A watercolor illustration of a lighthouse at dawn',
type: 'image',
model: 'flare',
referenceSourceId: 'su_abc123def456'
})
};
fetch('https://api.tella.com/v1/library/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tella.com/v1/library/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'A watercolor illustration of a lighthouse at dawn',
'type' => 'image',
'model' => 'flare',
'referenceSourceId' => 'su_abc123def456'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.tella.com/v1/library/generations"
payload := strings.NewReader("{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.tella.com/v1/library/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/library/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"A watercolor illustration of a lighthouse at dawn\",\n \"type\": \"image\",\n \"model\": \"flare\",\n \"referenceSourceId\": \"su_abc123def456\"\n}"
response = http.request(request)
puts response.read_body{
"generation": {
"id": "mi_abc123def456",
"prompt": "A watercolor illustration of a lighthouse at dawn",
"status": "completed",
"type": "image",
"error": "<string>",
"item": {
"id": "media_abc123def456",
"name": "Intro camera take",
"scope": "private",
"type": "video",
"category": "Everyday",
"createdAt": "<string>",
"dimensions": {
"height": 0,
"width": 0
},
"durationMs": 4200,
"presetId": "cha-ching",
"sourceId": "su_abc123def456",
"updatedAt": "<string>",
"url": "<string>"
}
},
"limit": 20,
"remaining": 19,
"resetAt": 1760000000000
}{
"docsUrl": "https://docs.tella.com/",
"error": "bad_request",
"message": "The request was malformed or contained invalid parameters."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unauthorized",
"message": "Authentication is required. Provide a valid API key."
}{
"docsUrl": "https://docs.tella.com/",
"error": "forbidden",
"message": "You don't have permission to access this resource."
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_found",
"message": "The requested resource was not found."
}{
"docsUrl": "https://docs.tella.com/",
"error": "conflict",
"message": "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."
}{
"docsUrl": "https://docs.tella.com/",
"error": "rate_limited",
"message": "You have exceeded the rate limit. Please slow down."
}{
"docsUrl": "https://docs.tella.com/",
"error": "server_error",
"message": "An unexpected error occurred"
}{
"docsUrl": "https://docs.tella.com/",
"error": "not_implemented",
"message": "The requested operation is not implemented."
}{
"docsUrl": "https://docs.tella.com/",
"error": "unavailable",
"message": "A dependency was unavailable and the request was not executed. Safe to resend unchanged after the Retry-After delay."
}Authorizations
API key obtained from your Tella account settings
Body
Start generating media from a prompt
What to generate. Up to 4000 characters for an image, 2000 for a sound effect.
1"A watercolor illustration of a lighthouse at dawn"
The kind of media to generate
image, sound-effect "image"
For image only: which GPT Image 2.5 model to use. sunburst (default) is the most capable and follows reference images most precisely; flare is faster.
sunburst, flare "flare"
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.
"su_abc123def456"
Response
Accepted
The generation that was started, plus the weekly allowance
An AI media generation and, once finished, its library item
Hide child attributes
Hide child attributes
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.
"mi_abc123def456"
The prompt the media is being generated from
"A watercolor illustration of a lighthouse at dawn"
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.
pending, running, completed, failed "completed"
The kind of media to generate
image, sound-effect "image"
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.
The finished library item, present once status is completed. Pass its sourceId anywhere a source is accepted — overlays, layout media, sound effects.
Hide child attributes
Hide child attributes
Unique library item identifier
"media_abc123def456"
Display name shown in the library
"Intro camera take"
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)
private, workspace, default "private"
The kind of media the item holds
image, video, sound-effect, music, lut, screenshot "video"
Catalog grouping, for default items only — the same grouping the editor's sound effects and background music panels show
"Everyday"
ISO-8601 creation timestamp. Absent for default catalog items, which are served from Tella's catalog rather than stored as rows.
Duration in milliseconds, for time-based media
4200
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.
"cha-ching"
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.
"su_abc123def456"
ISO-8601 update timestamp. Absent for default catalog items.
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.
The caller's weekly AI generation allowance for this media type, which depends on the plan
-9007199254740991 <= x <= 900719925474099120
Generations left in the current week, after this one
-9007199254740991 <= x <= 900719925474099119
When the weekly allowance resets, as a millisecond epoch
1760000000000
Was this page helpful?