curl --request POST \
--url https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"wordRanges": [
{
"fromWordIndex": 12,
"toWordIndex": 17
}
]
}
'import requests
url = "https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript"
payload = { "wordRanges": [
{
"fromWordIndex": 12,
"toWordIndex": 17
}
] }
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({wordRanges: [{fromWordIndex: 12, toWordIndex: 17}]})
};
fetch('https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript', 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/videos/{id}/clips/{clipId}/cut-by-transcript",
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([
'wordRanges' => [
[
'fromWordIndex' => 12,
'toWordIndex' => 17
]
]
]),
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/videos/{id}/clips/{clipId}/cut-by-transcript"
payload := strings.NewReader("{\n \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\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/videos/{id}/clips/{clipId}/cut-by-transcript")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript")
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 \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"clip": {
"background": {
"type": "solid",
"color": "#000000ff",
"gradientAngle": 45,
"gradientColor1": "#ff0080ff",
"gradientColor2": "#7928caff",
"imageUrl": "<string>",
"sourceId": "su_abc123",
"videoDurationSeconds": 12.4,
"videoUrl": "<string>"
},
"borderStyle": "subtle-shadow",
"corners": "regular",
"createdAt": "2026-01-15T10:30:00.000Z",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"durationSeconds": 12.5,
"id": "cl_xyz789ghi012",
"layoutSceneType": "combi",
"maxDurationSeconds": 14.2,
"name": "Intro",
"order": 0,
"studioSound": false,
"transition": "default",
"updatedAt": "2026-01-15T14:45:00.000Z",
"videoId": "vid_abc123def456",
"animatedCursor": true,
"microphoneVolume": 0.4,
"systemAudioVolume": null
}
}{
"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."
}Cut clip ranges by transcript word indices
Cut one or more ranges from a clip by referencing word indices in the transcript. The server reads each word’s exact startTimeMs / endTimeMs and merges the resulting cuts — no padding is applied to word boundaries.
curl --request POST \
--url https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"wordRanges": [
{
"fromWordIndex": 12,
"toWordIndex": 17
}
]
}
'import requests
url = "https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript"
payload = { "wordRanges": [
{
"fromWordIndex": 12,
"toWordIndex": 17
}
] }
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({wordRanges: [{fromWordIndex: 12, toWordIndex: 17}]})
};
fetch('https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript', 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/videos/{id}/clips/{clipId}/cut-by-transcript",
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([
'wordRanges' => [
[
'fromWordIndex' => 12,
'toWordIndex' => 17
]
]
]),
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/videos/{id}/clips/{clipId}/cut-by-transcript"
payload := strings.NewReader("{\n \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\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/videos/{id}/clips/{clipId}/cut-by-transcript")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/videos/{id}/clips/{clipId}/cut-by-transcript")
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 \"wordRanges\": [\n {\n \"fromWordIndex\": 12,\n \"toWordIndex\": 17\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"clip": {
"background": {
"type": "solid",
"color": "#000000ff",
"gradientAngle": 45,
"gradientColor1": "#ff0080ff",
"gradientColor2": "#7928caff",
"imageUrl": "<string>",
"sourceId": "su_abc123",
"videoDurationSeconds": 12.4,
"videoUrl": "<string>"
},
"borderStyle": "subtle-shadow",
"corners": "regular",
"createdAt": "2026-01-15T10:30:00.000Z",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"durationSeconds": 12.5,
"id": "cl_xyz789ghi012",
"layoutSceneType": "combi",
"maxDurationSeconds": 14.2,
"name": "Intro",
"order": 0,
"studioSound": false,
"transition": "default",
"updatedAt": "2026-01-15T14:45:00.000Z",
"videoId": "vid_abc123def456",
"animatedCursor": true,
"microphoneVolume": 0.4,
"systemAudioVolume": null
}
}{
"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
Path Parameters
Video identifier
"vid_abc123def456"
Clip identifier
"cl_xyz789ghi012"
Body
Cut one or more ranges from the clip by referencing word indices in the transcript. Indices are stable across cuts (already-cut words are simply absent). The server resolves each range to exact word times and merges the resulting cuts.
Word ranges to cut. Each range's start and end ms are read directly from the transcript — no padding is applied.
1Hide child attributes
Hide child attributes
Index of the first word to cut (inclusive), as reported by the transcript.
0 <= x <= 900719925474099112
Index of the last word to cut (inclusive), as reported by the transcript.
0 <= x <= 900719925474099117
Response
OK
Response shape for a single clip
A section of a video
Hide child attributes
Hide child attributes
Clip background. Use type = 'solid' with color, type = 'image' or 'video' with sourceId (from POST /v1/sources) or an exact catalog URL from GET /v1/backgrounds, or type = 'gradient' with gradientColor1, gradientColor2, gradientAngle.
Hide child attributes
Hide child attributes
Background variant. shaderGradient is read-only: responses include its two colors but no angle. Echoing the unchanged background preserves it; creating or modifying a shaderGradient through this API is not supported.
solid, gradient, image, video, shaderGradient "solid"
Hex color string. Required when type = 'solid'.
"#000000ff"
Linear gradient angle in degrees. Required when type = 'gradient'.
-9007199254740991 <= x <= 900719925474099145
Hex color string. Required when type = 'gradient'.
"#ff0080ff"
Hex color string. Required when type = 'gradient'.
"#7928caff"
Hosted image URL. Present in responses and accepted as input only when copied exactly from GET /v1/backgrounds; otherwise pass sourceId.
Source ID from POST /v1/sources (kind: image for type = 'image', kind: video for type = 'video'). Required for image/video backgrounds unless using an exact URL from GET /v1/backgrounds. Input-only.
"su_abc123"
Video background duration in seconds. Read-only: derived from the uploaded source or catalog entry on input.
x >= 012.4
Hosted video URL. Present in responses and accepted as input only when copied exactly from GET /v1/backgrounds; otherwise pass sourceId.
Border and shadow around the clip's frames — the editor Style panel's Border style. The clip's own value, else the video's. custom means the layers were styled one by one or with a retired preset; it can't be written.
none, subtle-shadow, deep-shadow, transparent, solid-shadow-left, solid-shadow-right, snake, custom "subtle-shadow"
Corner rounding of the clip's frames — the editor Style panel's Shape: none (square), regular (rounded) or squircle (very rounded). The clip's own value, else the video's.
none, regular, squircle "regular"
ISO 8601 datetime
"2026-01-15T10:30:00.000Z"
Time ranges cut from the clip's playback
Effective playback duration of the clip after cuts, in seconds
x >= 012.5
Unique clip identifier
"cl_xyz789ghi012"
Determines which layouts can be applied to this clip via add_layout. See BasicSubjectLayoutName, CameraSubjectLayoutName, CombiLayoutName.
basicSubject, cameraSubject, combi "combi"
Total length of the underlying source, in seconds
x >= 014.2
Clip display name
"Intro"
Position of the clip within the video
0 <= x <= 90071992547409910
Effective Studio Sound (AI audio enhancement) state for this clip: the video-level switch minus this clip's opt-out.
false
How a clip enters from the previous one. default inherits the video's defaultClipTransition; smooth and hard_cut override it for this clip. The first clip in a video has nothing to transition from.
default, smooth, hard_cut "default"
ISO 8601 datetime
"2026-01-15T14:45:00.000Z"
Video identifier
"vid_abc123def456"
Whether the clip draws an animated cursor from captured mouse data. Absent when the clip has no screen recording.
true
This clip's microphone volume override: a number when the clip overrides the video's microphoneVolume, null when it follows it, and absent when the clip has no microphone audio to control — either no such track, or a track whose recording carries no audio (a muted mic, or a screen recording made without sharing system audio).
0 <= x <= 20.4
This clip's system audio (screen or uploaded footage) volume override, with the same three states as microphoneVolume.
0 <= x <= 2null
Was this page helpful?