curl --request POST \
--url https://api.deapi.ai/api/v2/videos/descriptions \
--header 'Accept: <accept>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'video_url=https://www.youtube.com/watch?v=jNQXAC9IVRw' \
--form model=Marlin_2B \
--form 'video_file=<string>' \
--form preset=balanced \
--form include_metadata=false \
--form return_result_in_response=false \
--form webhook_url=https://your-server.com/webhooks/deapi \
--form webhook_secret=a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5 \
--form 0.video_file='@example-file' \
--form 1.video_file='@example-file'import requests
url = "https://api.deapi.ai/api/v2/videos/descriptions"
files = {
"0.video_file": ("example-file", open("example-file", "rb")),
"1.video_file": ("example-file", open("example-file", "rb"))
}
payload = {
"video_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"model": "Marlin_2B",
"video_file": "<string>",
"preset": "balanced",
"include_metadata": "false",
"return_result_in_response": "false",
"webhook_url": "https://your-server.com/webhooks/deapi",
"webhook_secret": "a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5"
}
headers = {
"Accept": "<accept>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('video_url', 'https://www.youtube.com/watch?v=jNQXAC9IVRw');
form.append('model', 'Marlin_2B');
form.append('video_file', '<string>');
form.append('preset', 'balanced');
form.append('include_metadata', 'false');
form.append('return_result_in_response', 'false');
form.append('webhook_url', 'https://your-server.com/webhooks/deapi');
form.append('webhook_secret', 'a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5');
form.append('0.video_file', '{
"fileName": "example-file"
}');
form.append('1.video_file', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Accept: '<accept>', Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.deapi.ai/api/v2/videos/descriptions', 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.deapi.ai/api/v2/videos/descriptions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Accept: <accept>",
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.deapi.ai/api/v2/videos/descriptions"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Accept", "<accept>")
req.Header.Add("Authorization", "Bearer <token>")
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.deapi.ai/api/v2/videos/descriptions")
.header("Accept", "<accept>")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.deapi.ai/api/v2/videos/descriptions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = '<accept>'
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"request_id": "c08a339c-73e5-4d67-a4d5-231302fbff9a"
}
}{
"data": {},
"message": "<string>",
"errors": [
"<unknown>"
],
"statusCode": 123
}{
"message": "Client account is suspended. If you believe this is a mistake, contact us."
}{
"message": "The selected model does not support Text To Image.",
"errors": {
"model": [
"This model is not available on your plan. Please upgrade to access it."
]
}
}{
"message": "Too Many Attempts."
}Video Description
Produce a timestamped index of what happens on screen — a list of events, each with start, end (seconds) and a description — plus scene boundaries and source metadata. Reads the picture, not the audio track; for speech use POST /api/v2/audio/transcriptions. Accepts either a video URL (YouTube, Twitter/X, Twitch, Kick, TikTok) or a file upload. The result is a JSON document: {"events": [{"start", "end", "description", "merged?", "edge_distance"}], "scenes": [...], "meta": {"duration", "preset", ...}}, delivered as result_url on the job (and as a serialized JSON string in result when return_result_in_response is set). Priced on machine time at the model’s hourly rate — longer videos and higher presets cost more — or, for TikTok, on a fixed card by length capped at 10 minutes; see POST /api/v2/videos/descriptions/price.
curl --request POST \
--url https://api.deapi.ai/api/v2/videos/descriptions \
--header 'Accept: <accept>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'video_url=https://www.youtube.com/watch?v=jNQXAC9IVRw' \
--form model=Marlin_2B \
--form 'video_file=<string>' \
--form preset=balanced \
--form include_metadata=false \
--form return_result_in_response=false \
--form webhook_url=https://your-server.com/webhooks/deapi \
--form webhook_secret=a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5 \
--form 0.video_file='@example-file' \
--form 1.video_file='@example-file'import requests
url = "https://api.deapi.ai/api/v2/videos/descriptions"
files = {
"0.video_file": ("example-file", open("example-file", "rb")),
"1.video_file": ("example-file", open("example-file", "rb"))
}
payload = {
"video_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"model": "Marlin_2B",
"video_file": "<string>",
"preset": "balanced",
"include_metadata": "false",
"return_result_in_response": "false",
"webhook_url": "https://your-server.com/webhooks/deapi",
"webhook_secret": "a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5"
}
headers = {
"Accept": "<accept>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('video_url', 'https://www.youtube.com/watch?v=jNQXAC9IVRw');
form.append('model', 'Marlin_2B');
form.append('video_file', '<string>');
form.append('preset', 'balanced');
form.append('include_metadata', 'false');
form.append('return_result_in_response', 'false');
form.append('webhook_url', 'https://your-server.com/webhooks/deapi');
form.append('webhook_secret', 'a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5');
form.append('0.video_file', '{
"fileName": "example-file"
}');
form.append('1.video_file', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Accept: '<accept>', Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.deapi.ai/api/v2/videos/descriptions', 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.deapi.ai/api/v2/videos/descriptions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Accept: <accept>",
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.deapi.ai/api/v2/videos/descriptions"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Accept", "<accept>")
req.Header.Add("Authorization", "Bearer <token>")
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.deapi.ai/api/v2/videos/descriptions")
.header("Accept", "<accept>")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.deapi.ai/api/v2/videos/descriptions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = '<accept>'
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_url\"\r\n\r\nhttps://www.youtube.com/watch?v=jNQXAC9IVRw\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMarlin_2B\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"video_file\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"preset\"\r\n\r\nbalanced\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"include_metadata\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"return_result_in_response\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_url\"\r\n\r\nhttps://your-server.com/webhooks/deapi\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"webhook_secret\"\r\n\r\na1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"0.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"1.video_file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"request_id": "c08a339c-73e5-4d67-a4d5-231302fbff9a"
}
}{
"data": {},
"message": "<string>",
"errors": [
"<unknown>"
],
"statusCode": 123
}{
"message": "Client account is suspended. If you believe this is a mistake, contact us."
}{
"message": "The selected model does not support Text To Image.",
"errors": {
"model": [
"This model is not available on your plan. Please upgrade to access it."
]
}
}{
"message": "Too Many Attempts."
}request_id for status polling.
slug and check supported presets and duration limits.Authorizations
Sanctum personal access token, sent as Authorization: Bearer <token>. The token is opaque — it carries no claims and no embedded expiry, so do not attempt to decode it. Issue and revoke tokens from your account dashboard.
Headers
application/json Body
Video description parameters. Provide exactly one of video_url or video_file.
- From a video URL
- From an uploaded file
A source is MANDATORY and comes in exactly one of two shapes — video_url for a hosted video, or video_file for an upload. Sending neither is a 422, and sending both is a 422 as well; the oneOf below is that choice, not a pair of optional fields. Everything else applies to both. The /price twin of this endpoint accepts a third shape, duration_seconds, which this one does not.
URL of the video to describe (YouTube, Twitter/X, Twitch, Kick, TikTok — the same platforms as transcription). Audio-only sources such as Twitter Spaces are rejected. Live streams are rejected. Mutually exclusive with video_file.
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
The model to use. Available models can be retrieved via the GET /api/v2/models endpoint; a model lists video2desc (URL sources) and/or video_file2desc (uploads) in its inference_types. Its info.limits.max_video_duration_seconds, when present, is the longest source it accepts.
"Marlin_2B"
Video file to describe. Supported: mp4, mpeg, quicktime, avi, wmv, ogg, webm, mkv. Must contain a video stream. Mutually exclusive with video_url.
Detail level. A preset is the per-frame pixel budget the model reads the video at: fast reads a small frame over long windows, detail a large frame over short windows, so higher presets read more of what is on screen (small text, brand names) and cost more — roughly ×1 / ×3 / ×7 machine time for fast / balanced / detail (×0.75 / ×1 / ×1.5 on the TikTok card). Omit for the default (balanced, or the cheapest preset the model offers if it does not offer balanced). Only honoured on a model whose info.features.supports_presets is true; such a model publishes the presets it offers as info.limits.available_presets and rejects any other. On a model without the flag the field is ignored.
fast, balanced, detail, null "balanced"
If true, the job-status response carries a metadata object describing the source — title, channel, uploader, upload date and engagement counts such as views, likes and comments — exactly as on POST /api/v2/audio/transcriptions. Only URL sources have any; an uploaded file returns null and is never charged for the flag. Carries the same flat surcharge as transcription metadata.
false
If true, the completed job-status response includes the description as a serialized JSON string in data.result, in addition to data.result_url. Parse the string as JSON to read events, scenes and meta.
false
Optional HTTPS URL to receive webhook notifications for job status changes (processing, completed, failed). Must be HTTPS. Max 2048 characters. A per-request URL is self-contained: it is delivered even when the account has no webhook configuration, or the account webhook is disabled. See the webhooks block at the top level of this document for the event payloads and the headers each delivery carries.
2048"https://your-server.com/webhooks/deapi"
Optional per-request HMAC secret (min. 32 chars) used to sign the webhook callback. Overrides the account-default secret for this job only. If omitted, the account-default secret signs the callback; if no secret exists at all, the callback is still delivered but UNSIGNED (empty X-DeAPI-Signature header). Requires webhook_url to also be set.
32 - 255"a1b2c3d4e5f60708091a2b3c4d5e6f7081920a1b2c3d4e5f60708091a2b3c4d5"
Response
ID of the inference request.
Information from success endpoint
Show child attributes
Show child attributes
Was this page helpful?