Videos
Start a video upload
POST
/
v1
/
videos
Start a video upload
curl --request POST \
--url https://api.vturb.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Landing hero",
"filename": "hero.mp4",
"type": "video/mp4",
"size": 12582912,
"folder_id": "6890000000000000000000a1",
"part_size": 104857600
}
'import requests
url = "https://api.vturb.com/v1/videos"
payload = {
"name": "Landing hero",
"filename": "hero.mp4",
"type": "video/mp4",
"size": 12582912,
"folder_id": "6890000000000000000000a1",
"part_size": 104857600
}
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({
name: 'Landing hero',
filename: 'hero.mp4',
type: 'video/mp4',
size: 12582912,
folder_id: '6890000000000000000000a1',
part_size: 104857600
})
};
fetch('https://api.vturb.com/v1/videos', 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.vturb.com/v1/videos",
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([
'name' => 'Landing hero',
'filename' => 'hero.mp4',
'type' => 'video/mp4',
'size' => 12582912,
'folder_id' => '6890000000000000000000a1',
'part_size' => 104857600
]),
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.vturb.com/v1/videos"
payload := strings.NewReader("{\n \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\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.vturb.com/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vturb.com/v1/videos")
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 \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\n}"
response = http.request(request)
puts response.read_body{
"id": "652f2b1e8f1b2c3d4e5f6a7b",
"status": "awaiting_upload",
"upload": {
"expires_at": "2026-07-30T12:15:00Z",
"part_size": 1073741824,
"parts": [
{
"part_number": 1,
"url": "https://s3.amazonaws.com/vturb-uploads/org_123/x/original.mp4?partNumber=1&uploadId=mpu1&X-Amz-Signature=abc"
}
]
},
"complete_url": "/v1/videos/652f2b1e8f1b2c3d4e5f6a7b/upload/completion"
}{
"type": "https://docs.vturb.com/errors/bad_request",
"code": "bad_request",
"message": "The request includes fields this endpoint does not accept.",
"field": "nope",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/unauthorized",
"code": "unauthorized",
"message": "Missing or invalid API credential. Send a vt_ token in the Authorization header.",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/forbidden",
"code": "forbidden",
"message": "The credential is missing the scope this action requires.",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/unprocessable_content",
"code": "unprocessable_content",
"message": "The request is invalid. See errors for the fields that failed.",
"request_id": "00000000-0000-0000-0000-000000000000",
"errors": [
{
"field": "type",
"message": "is not a supported video type"
},
{
"field": "size",
"message": "must be an integer number of bytes"
}
]
}Authorizations
Paste your VTurb API token (vt_...). Sent as Authorization: Bearer <token>.
Body
application/json
Display name for the video.
Maximum string length:
255Example:
"Landing hero"
Original filename; only its extension is kept for the stored object.
Maximum string length:
255Example:
"hero.mp4"
Video MIME type (allowlist); set on the stored object.
Available options:
video/mp4, video/quicktime, video/webm Example:
"video/mp4"
Declared size of the file in bytes (max 15GB). The upload is split into part_size slices — one presigned URL per part in upload.parts.
Required range:
1 <= x <= 16106127360Example:
12582912
Optional folder to place the video in.
Optional slice size in bytes (default 1GB). Each part URL only accepts exactly this many bytes (the last part takes the remainder). Browser clients usually want smaller slices.
Required range:
10485760 <= x <= 5368709120Example:
104857600
Was this page helpful?
⌘I
Start a video upload
curl --request POST \
--url https://api.vturb.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Landing hero",
"filename": "hero.mp4",
"type": "video/mp4",
"size": 12582912,
"folder_id": "6890000000000000000000a1",
"part_size": 104857600
}
'import requests
url = "https://api.vturb.com/v1/videos"
payload = {
"name": "Landing hero",
"filename": "hero.mp4",
"type": "video/mp4",
"size": 12582912,
"folder_id": "6890000000000000000000a1",
"part_size": 104857600
}
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({
name: 'Landing hero',
filename: 'hero.mp4',
type: 'video/mp4',
size: 12582912,
folder_id: '6890000000000000000000a1',
part_size: 104857600
})
};
fetch('https://api.vturb.com/v1/videos', 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.vturb.com/v1/videos",
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([
'name' => 'Landing hero',
'filename' => 'hero.mp4',
'type' => 'video/mp4',
'size' => 12582912,
'folder_id' => '6890000000000000000000a1',
'part_size' => 104857600
]),
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.vturb.com/v1/videos"
payload := strings.NewReader("{\n \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\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.vturb.com/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vturb.com/v1/videos")
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 \"name\": \"Landing hero\",\n \"filename\": \"hero.mp4\",\n \"type\": \"video/mp4\",\n \"size\": 12582912,\n \"folder_id\": \"6890000000000000000000a1\",\n \"part_size\": 104857600\n}"
response = http.request(request)
puts response.read_body{
"id": "652f2b1e8f1b2c3d4e5f6a7b",
"status": "awaiting_upload",
"upload": {
"expires_at": "2026-07-30T12:15:00Z",
"part_size": 1073741824,
"parts": [
{
"part_number": 1,
"url": "https://s3.amazonaws.com/vturb-uploads/org_123/x/original.mp4?partNumber=1&uploadId=mpu1&X-Amz-Signature=abc"
}
]
},
"complete_url": "/v1/videos/652f2b1e8f1b2c3d4e5f6a7b/upload/completion"
}{
"type": "https://docs.vturb.com/errors/bad_request",
"code": "bad_request",
"message": "The request includes fields this endpoint does not accept.",
"field": "nope",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/unauthorized",
"code": "unauthorized",
"message": "Missing or invalid API credential. Send a vt_ token in the Authorization header.",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/forbidden",
"code": "forbidden",
"message": "The credential is missing the scope this action requires.",
"request_id": "00000000-0000-0000-0000-000000000000"
}{
"type": "https://docs.vturb.com/errors/unprocessable_content",
"code": "unprocessable_content",
"message": "The request is invalid. See errors for the fields that failed.",
"request_id": "00000000-0000-0000-0000-000000000000",
"errors": [
{
"field": "type",
"message": "is not a supported video type"
},
{
"field": "size",
"message": "must be an integer number of bytes"
}
]
}