curl --request PATCH \
--url https://api.tella.com/v1/videos/{id}/clips/{clipId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"animatedCursor": true,
"borderStyle": "subtle-shadow",
"corners": "squircle",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"microphoneVolume": 0.4,
"name": "Updated intro",
"order": 2,
"studioSound": false,
"systemAudioVolume": 1.5,
"transition": "default"
}
'import requests
url = "https://api.tella.com/v1/videos/{id}/clips/{clipId}"
payload = {
"animatedCursor": True,
"borderStyle": "subtle-shadow",
"corners": "squircle",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"microphoneVolume": 0.4,
"name": "Updated intro",
"order": 2,
"studioSound": False,
"systemAudioVolume": 1.5,
"transition": "default"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
animatedCursor: true,
borderStyle: 'subtle-shadow',
corners: 'squircle',
cuts: [{durationMs: 750, startTimeMs: 1500}],
microphoneVolume: 0.4,
name: 'Updated intro',
order: 2,
studioSound: false,
systemAudioVolume: 1.5,
transition: 'default'
})
};
fetch('https://api.tella.com/v1/videos/{id}/clips/{clipId}', 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}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'animatedCursor' => true,
'borderStyle' => 'subtle-shadow',
'corners' => 'squircle',
'cuts' => [
[
'durationMs' => 750,
'startTimeMs' => 1500
]
],
'microphoneVolume' => 0.4,
'name' => 'Updated intro',
'order' => 2,
'studioSound' => false,
'systemAudioVolume' => 1.5,
'transition' => 'default'
]),
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}"
payload := strings.NewReader("{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.tella.com/v1/videos/{id}/clips/{clipId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/videos/{id}/clips/{clipId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\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."
}Update a clip
Update a clip’s name, ordering, cuts, background, transition, audio, or frame styling (corner rounding and border style). At least one field must be provided.
curl --request PATCH \
--url https://api.tella.com/v1/videos/{id}/clips/{clipId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"animatedCursor": true,
"borderStyle": "subtle-shadow",
"corners": "squircle",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"microphoneVolume": 0.4,
"name": "Updated intro",
"order": 2,
"studioSound": false,
"systemAudioVolume": 1.5,
"transition": "default"
}
'import requests
url = "https://api.tella.com/v1/videos/{id}/clips/{clipId}"
payload = {
"animatedCursor": True,
"borderStyle": "subtle-shadow",
"corners": "squircle",
"cuts": [
{
"durationMs": 750,
"startTimeMs": 1500
}
],
"microphoneVolume": 0.4,
"name": "Updated intro",
"order": 2,
"studioSound": False,
"systemAudioVolume": 1.5,
"transition": "default"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
animatedCursor: true,
borderStyle: 'subtle-shadow',
corners: 'squircle',
cuts: [{durationMs: 750, startTimeMs: 1500}],
microphoneVolume: 0.4,
name: 'Updated intro',
order: 2,
studioSound: false,
systemAudioVolume: 1.5,
transition: 'default'
})
};
fetch('https://api.tella.com/v1/videos/{id}/clips/{clipId}', 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}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'animatedCursor' => true,
'borderStyle' => 'subtle-shadow',
'corners' => 'squircle',
'cuts' => [
[
'durationMs' => 750,
'startTimeMs' => 1500
]
],
'microphoneVolume' => 0.4,
'name' => 'Updated intro',
'order' => 2,
'studioSound' => false,
'systemAudioVolume' => 1.5,
'transition' => 'default'
]),
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}"
payload := strings.NewReader("{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.tella.com/v1/videos/{id}/clips/{clipId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tella.com/v1/videos/{id}/clips/{clipId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"animatedCursor\": true,\n \"borderStyle\": \"subtle-shadow\",\n \"corners\": \"squircle\",\n \"cuts\": [\n {\n \"durationMs\": 750,\n \"startTimeMs\": 1500\n }\n ],\n \"microphoneVolume\": 0.4,\n \"name\": \"Updated intro\",\n \"order\": 2,\n \"studioSound\": false,\n \"systemAudioVolume\": 1.5,\n \"transition\": \"default\"\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
Request body for updating a clip. At least one field must be provided.
Draw an animated cursor from captured mouse data on this clip's screen recording. Returns 400 when the clip has no screen recording.
true
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. solid-shadow-left and solid-shadow-right are the solid shadow and its direction; snake keeps the clip's current snake settings, else the editor's default. Applies to this clip only, across all of its layouts.
none, subtle-shadow, deep-shadow, transparent, solid-shadow-left, solid-shadow-right, snake "subtle-shadow"
Corner rounding of the clip's frames (screen and camera) — the editor Style panel's Shape: none (square), regular (rounded) or squircle (very rounded). Applies to this clip only, like the editor's "Apply to this clip only", across all of its layouts. A circle camera stays a circle.
none, regular, squircle "squircle"
Replaces the clip's cuts. Total cut duration must be less than maxDurationSeconds.
Microphone volume for this clip only, overriding the video's microphoneVolume. 1 is the recorded level, 0 mutes it, 2 doubles it. Pass null to clear the override so the clip follows the video again. Null is a no-op when the clip has no microphone audio. Non-null values return 400 when the clip has no microphone audio to control, i.e. whenever a read reports the field as absent.
0 <= x <= 20.4
New clip name
1 - 255"Updated intro"
New position of the clip within the video
0 <= x <= 90071992547409912
Per-clip Studio Sound opt-out. false disables enhanced audio for this clip while the video-level switch (see PATCH /v1/videos/{id} studioSound) stays on; true re-enables it.
false
System audio (screen or uploaded footage) volume for this clip only, overriding the video's systemAudioVolume. Same range and null-to-clear behaviour as microphoneVolume. Null is a no-op when the clip has no system audio. Non-null values return 400 when the clip has no such audio to control, i.e. whenever a read reports the field as absent.
0 <= x <= 21.5
How this clip enters from the previous one. default drops the override and follows the video's defaultClipTransition.
default, smooth, hard_cut "default"
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?