Folders and metadata
Keep a growing video library easy to find and manage.
You will group videos into folders, update titles, control availability, and remove videos you no longer need. Every change is scoped to your own account.
Create a folder
curl --fail-with-body --request POST 'https://api.todayfiles.com/v1/folders' \
--header "Authorization: Bearer $TODAYFILES_API_KEY" \
--header 'Idempotency-Key: replace-with-a-unique-request-key' \
--header 'Content-Type: application/json' \
--data '{"name":"Trailers"}'const response = await fetch("https://api.todayfiles.com/v1/folders", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.TODAYFILES_API_KEY,
"Idempotency-Key": "replace-with-a-unique-request-key",
"Content-Type": "application/json",
},
body: JSON.stringify({"name":"Trailers"}),
});
if (!response.ok) throw new Error(await response.text());
const result = response.status === 204 ? null : await response.json();
console.log(result);import json
import os
import requests
response = requests.request(
"POST", "https://api.todayfiles.com/v1/folders",
headers={
"Authorization": "Bearer " + os.environ["TODAYFILES_API_KEY"],
"Idempotency-Key": "replace-with-a-unique-request-key",
},
json=json.loads("{\"name\":\"Trailers\"}"),
timeout=30,
)
response.raise_for_status()
print(response.json() if response.content else None)<?php
$client = curl_init("https://api.todayfiles.com/v1/folders");
curl_setopt_array($client, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TODAYFILES_API_KEY'),
'Idempotency-Key: replace-with-a-unique-request-key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => "{\"name\":\"Trailers\"}",
]);
$body = curl_exec($client);
if ($body === false) throw new RuntimeException(curl_error($client));
$status = curl_getinfo($client, CURLINFO_RESPONSE_CODE);
curl_close($client);
if ($status >= 400) throw new RuntimeException($body);
$result = $body === '' ? null : json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);package main
import (
"encoding/json"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
request, err := http.NewRequest("POST", "https://api.todayfiles.com/v1/folders", strings.NewReader("{\"name\":\"Trailers\"}"))
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer " + os.Getenv("TODAYFILES_API_KEY"))
request.Header.Set("Idempotency-Key", "replace-with-a-unique-request-key")
request.Header.Set("Content-Type", "application/json")
response, err := (&http.Client{Timeout: 30 * time.Second}).Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(io.LimitReader(response.Body, 1 << 20))
if err != nil { panic(err) }
if response.StatusCode >= 400 { panic(string(body)) }
var result any
if len(body) > 0 {
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
}
if err := json.NewEncoder(os.Stdout).Encode(result); err != nil { panic(err) }
}Keep the returned folder id. Names are 1 to 64 characters and must be unique within your account. List your folders with GET /folders; this short list has no cursor.
Move your videos
curl --fail-with-body --request POST 'https://api.todayfiles.com/v1/folders/fld_3/videos' \
--header "Authorization: Bearer $TODAYFILES_API_KEY" \
--header 'Idempotency-Key: replace-with-a-unique-request-key' \
--header 'Content-Type: application/json' \
--data '{"video_ids":["h87x","q2m8"]}'const response = await fetch("https://api.todayfiles.com/v1/folders/fld_3/videos", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.TODAYFILES_API_KEY,
"Idempotency-Key": "replace-with-a-unique-request-key",
"Content-Type": "application/json",
},
body: JSON.stringify({"video_ids":["h87x","q2m8"]}),
});
if (!response.ok) throw new Error(await response.text());
const result = response.status === 204 ? null : await response.json();
console.log(result);import json
import os
import requests
response = requests.request(
"POST", "https://api.todayfiles.com/v1/folders/fld_3/videos",
headers={
"Authorization": "Bearer " + os.environ["TODAYFILES_API_KEY"],
"Idempotency-Key": "replace-with-a-unique-request-key",
},
json=json.loads("{\"video_ids\":[\"h87x\",\"q2m8\"]}"),
timeout=30,
)
response.raise_for_status()
print(response.json() if response.content else None)<?php
$client = curl_init("https://api.todayfiles.com/v1/folders/fld_3/videos");
curl_setopt_array($client, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TODAYFILES_API_KEY'),
'Idempotency-Key: replace-with-a-unique-request-key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => "{\"video_ids\":[\"h87x\",\"q2m8\"]}",
]);
$body = curl_exec($client);
if ($body === false) throw new RuntimeException(curl_error($client));
$status = curl_getinfo($client, CURLINFO_RESPONSE_CODE);
curl_close($client);
if ($status >= 400) throw new RuntimeException($body);
$result = $body === '' ? null : json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);package main
import (
"encoding/json"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
request, err := http.NewRequest("POST", "https://api.todayfiles.com/v1/folders/fld_3/videos", strings.NewReader("{\"video_ids\":[\"h87x\",\"q2m8\"]}"))
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer " + os.Getenv("TODAYFILES_API_KEY"))
request.Header.Set("Idempotency-Key", "replace-with-a-unique-request-key")
request.Header.Set("Content-Type", "application/json")
response, err := (&http.Client{Timeout: 30 * time.Second}).Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(io.LimitReader(response.Body, 1 << 20))
if err != nil { panic(err) }
if response.StatusCode >= 400 { panic(string(body)) }
var result any
if len(body) > 0 {
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
}
if err := json.NewEncoder(os.Stdout).Encode(result); err != nil { panic(err) }
}The response reports how many of your videos moved. A video belongs to one folder. To make videos uncategorised, send the same video_ids array to POST /folders/remove-videos. You can also set a video's folder_id to null.
Update a title or availability
curl --fail-with-body --request PATCH 'https://api.todayfiles.com/v1/videos/h87x' \
--header "Authorization: Bearer $TODAYFILES_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"title":"Launch trailer","enabled":true}'const response = await fetch("https://api.todayfiles.com/v1/videos/h87x", {
method: "PATCH",
headers: {
Authorization: "Bearer " + process.env.TODAYFILES_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({"title":"Launch trailer","enabled":true}),
});
if (!response.ok) throw new Error(await response.text());
const result = response.status === 204 ? null : await response.json();
console.log(result);import json
import os
import requests
response = requests.request(
"PATCH", "https://api.todayfiles.com/v1/videos/h87x",
headers={
"Authorization": "Bearer " + os.environ["TODAYFILES_API_KEY"],
},
json=json.loads("{\"title\":\"Launch trailer\",\"enabled\":true}"),
timeout=30,
)
response.raise_for_status()
print(response.json() if response.content else None)<?php
$client = curl_init("https://api.todayfiles.com/v1/videos/h87x");
curl_setopt_array($client, [
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TODAYFILES_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => "{\"title\":\"Launch trailer\",\"enabled\":true}",
]);
$body = curl_exec($client);
if ($body === false) throw new RuntimeException(curl_error($client));
$status = curl_getinfo($client, CURLINFO_RESPONSE_CODE);
curl_close($client);
if ($status >= 400) throw new RuntimeException($body);
$result = $body === '' ? null : json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);package main
import (
"encoding/json"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
request, err := http.NewRequest("PATCH", "https://api.todayfiles.com/v1/videos/h87x", strings.NewReader("{\"title\":\"Launch trailer\",\"enabled\":true}"))
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer " + os.Getenv("TODAYFILES_API_KEY"))
request.Header.Set("Content-Type", "application/json")
response, err := (&http.Client{Timeout: 30 * time.Second}).Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(io.LimitReader(response.Body, 1 << 20))
if err != nil { panic(err) }
if response.StatusCode >= 400 { panic(string(body)) }
var result any
if len(body) > 0 {
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
}
if err := json.NewEncoder(os.Stdout).Encode(result); err != nil { panic(err) }
}Titles are 1 to 200 characters. Set enabled to false to disable a video, or true to enable it again. A video disabled by moderation cannot be enabled through this API. Check disabled_by_moderation and contact support when appropriate.
Use GET /videos?folder_id=fld_3&q=trailer to search titles in one folder. Follow the returned cursor with the same filters. An insertion between pages can shift a result; a cursor expires when the serving process restarts, so restart from the first page if it is rejected.
Delete a video or folder
curl --fail-with-body --request DELETE 'https://api.todayfiles.com/v1/videos/h87x' \
--header "Authorization: Bearer $TODAYFILES_API_KEY"const response = await fetch("https://api.todayfiles.com/v1/videos/h87x", {
method: "DELETE",
headers: {
Authorization: "Bearer " + process.env.TODAYFILES_API_KEY,
},
});
if (!response.ok) throw new Error(await response.text());
const result = response.status === 204 ? null : await response.json();
console.log(result);import json
import os
import requests
response = requests.request(
"DELETE", "https://api.todayfiles.com/v1/videos/h87x",
headers={
"Authorization": "Bearer " + os.environ["TODAYFILES_API_KEY"],
},
timeout=30,
)
response.raise_for_status()
print(response.json() if response.content else None)<?php
$client = curl_init("https://api.todayfiles.com/v1/videos/h87x");
curl_setopt_array($client, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TODAYFILES_API_KEY'),
],
]);
$body = curl_exec($client);
if ($body === false) throw new RuntimeException(curl_error($client));
$status = curl_getinfo($client, CURLINFO_RESPONSE_CODE);
curl_close($client);
if ($status >= 400) throw new RuntimeException($body);
$result = $body === '' ? null : json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);package main
import (
"encoding/json"
"io"
"net/http"
"os"
"time"
)
func main() {
request, err := http.NewRequest("DELETE", "https://api.todayfiles.com/v1/videos/h87x", nil)
if err != nil { panic(err) }
request.Header.Set("Authorization", "Bearer " + os.Getenv("TODAYFILES_API_KEY"))
response, err := (&http.Client{Timeout: 30 * time.Second}).Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(io.LimitReader(response.Body, 1 << 20))
if err != nil { panic(err) }
if response.StatusCode >= 400 { panic(string(body)) }
var result any
if len(body) > 0 {
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
}
if err := json.NewEncoder(os.Stdout).Encode(result); err != nil { panic(err) }
}A successful delete returns 204 with no body. The video then returns 404 through this API. Deleting a folder keeps its videos and makes them uncategorised. Changing a deleted video returns video_deleted.