Technical Documentation: Chocobozzz/PeerTube
โน๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference
Overview (`README.md`)
Website
| Join an instance
| Create an instance
| Chat with us
| Donate
Introduction
PeerTube is a free, decentralized and federated video platform developed as an alternative to other platforms that centralize our data and attention, such as YouTube, Dailymotion or Vimeo. :clapper:
To learn more:
- This two-minute video (hosted on PeerTube) explaining what PeerTube is and how it works
- PeerTube's project homepage, joinpeertube.org
- Demonstration instances:
- peertube.cpy.re (stable)
- peertube2.cpy.re (Nightly)
- peertube3.cpy.re (RC)
- This video demonstrating the communication between PeerTube and Mastodon (a decentralized Twitter alternative)
:sparkles: Features
All features for viewers
| All features for content creators
| All features for administrators
Video streaming, even in live!
Just upload your videos, and be sure they will stream anywhere. Add a description, some tags and your video will be discoverable by the entire video fediverse, not just your instance. You can even embed a player on your favorite website!
You are used to hosting live events? We got you covered too! Start livestreaming from your favorite client, and even host permanent streams!
Keep in touch with video creators
Follow your favorite channels from PeerTube or really any other place. No need to have an account on the instance you watched a video to follow its author, you can do all of that from the Fediverse (Mastodon, Pleroma, and plenty others), or just with good ol' RSS.
An interface to call home
Be it as a user or an instance administrator, you can decide what your experience will be like. Don't like the colors? They are easy to change. Don't want to list videos of an instance but let your users subscribe to them? Don't like the regular web client? All of that can be changed, and much more. No UX dark pattern, no mining your data, no video recommendation bullshitโข.
Communities that help each other
In addition to visitors using P2P with WebRTC to share the load among them, instances can help each other by caching one another's videos. This way even small instances have a way to show content to a wider audience, as they will be shouldered by friend instances (more about that in our redundancy guide).
Content creators can get help from their viewers in the simplest way possible: a support button showing a message linking to their donation accounts or really anything else. No more pay-per-view and advertisements that hurt visitors and alter creativity (more about that in our FAQ).
:raised_hands: Contributing
You don't need to be a programmer to help!
You can give us your feedback, report bugs, help us translate PeerTube, write documentation, and more. Check out the contributing
guide to know how, it takes less than 2 minutes to get started. :wink:
You can also join the cheerful bunch that makes our community:
- Matrix (bridged on Discord): #peertube:matrix.org
- Forum: https://framacolibri.org/c/peertube
Feel free to reach out if you have any questions or ideas! :speech_balloon:
:package: Create your own instance
See the production guide, which is the recommended way to install or upgrade PeerTube. For hardware requirements, see Should I have a big server to run PeerTube? in the FAQ.
See the community packages, which cover various platforms (including YunoHost and Docker).
:book: Documentation
If you have a question, please try to find the answer in the FAQ first.
User documentation
See the user documentation.
Admin documentation
See how to create your own instance.
See the more general admin documentation.
Tools documentation
Learn how to import/upload videos from CLI or admin your PeerTube instance with the tools documentation.
Technical documentation
See the architecture blueprint for a more detailed explanation of the architectural choices.
See our REST API documentation:
- OpenAPI 3.0.0 schema: /support/doc/api/openapi.yaml
- Spec explorer: docs.joinpeertube.org/api-rest-reference.html
See our ActivityPub documentation.
License
Logo
Code
Copyright (C) 2015-2025 PeerTube Contributors (see CREDITS.md)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
Overview (`apps/peertube-cli/README.md`)
PeerTube CLI
Usage
See https://docs.joinpeertube.org/maintain/tools#remote-tools
Dev
Install dependencies
cd peertube-root
npm run install-node-dependenciesDevelop
cd peertube-root
npm run dev:peertube-cliBuild
cd peertube-root
npm run build:peertube-cliRun
cd peertube-root
node apps/peertube-cli/dist/peertube.js --helpPublish on NPM
cd peertube-root
(cd apps/peertube-cli && npm version patch) && npm run build:peertube-cli && (cd apps/peertube-cli && npm login && npm publish --access=public)Overview (`apps/peertube-runner/README.md`)
PeerTube runner
Runner program to execute jobs (transcoding...) of remote PeerTube instances.
Commands below has to be run at the root of PeerTube git repository.
Dev
Install dependencies
cd peertube-root
npm run install-node-dependenciesDevelop
cd peertube-root
npm run dev:peertube-runnerBuild
cd peertube-root
npm run build:peertube-runnerRun
cd peertube-root
node apps/peertube-runner/dist/peertube-runner.mjs --helpPublish on NPM
cd peertube-root
(cd apps/peertube-runner && npm version patch) && npm run build:peertube-runner && (cd apps/peertube-runner && npm login && npm publish --access=public)Overview (`packages/transcription-devtools/README.md`)
Transcription DevTools
Includes:
- JiWER CLI NodeJS wrapper
- Benchmark tool to test multiple transcription engines
- TypeScript classes to evaluate word-error-rate of files generated by the transcription
Build
npm run buildBenchmark
A benchmark of available transcribers might be run with:
npm run benchmarkโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ (index) โ WER โ CER โ duration โ model โ engine โ
โโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโค
โ 5yZGBYqojXe7nuhq1TuHvz โ '28.39506172839506%' โ '9.62457337883959%' โ '41s' โ 'tiny' โ 'openai-whisper' โ
โ x6qREJ2AkTU4e5YmvfivQN โ '29.75206611570248%' โ '10.46195652173913%' โ '15s' โ 'tiny' โ 'whisper-ctranslate2' โ
โโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโThe benchmark may be run with multiple model builtin sizes:
MODELS=tiny,small,large npm run benchmarkJiwer
JiWER is a python tool for computing the word-error-rate of ASR systems.
https://jitsi.github.io/jiwer/cli/
JiWER serves as a reference implementation to calculate errors rates between 2 text files:
- WER (Word Error Rate)
- CER (Character Error Rate)
Usage
const jiwerCLI = new JiwerClI('./reference.txt', './hypothesis.txt')
// WER as a percentage, ex: 0.03 -> 3%
console.log(await jiwerCLI.wer())
// CER as a percentage: 0.01 -> 1%
console.log(await jiwerCLI.cer())
// Detailed comparison report
console.log(await jiwerCLI.alignment())Resources
Overview (`packages/transcription/README.md`)
Transcription
Video transcription consists in transcribing the audio content of a video to a text.
This process might be called Automatic Speech Recognition or Speech to Text in more general context.
Provide a common API to many transcription backend, currently:
openai-whisperCLIfaster-whisper(viawhisper-ctranslate2CLI)
Potential candidates could be: whisper-cpp, vosk, ...
Requirements
- Python 3
- PIP
And at least one of the following transcription backend:
- Python:
openai-whisperwhisper-ctranslate2>=0.4.3
Usage
Create a transcriber manually:
import { OpenaiTranscriber } from '@peertube/peertube-transcription'
(async () => {
// Optional if you want to use a local installation of transcribe engines
const binDirectory = 'local/pip/path/bin'
// Create a transcriber powered by OpenAI Whisper CLI
const transcriber = new OpenaiTranscriber({
name: 'openai-whisper',
command: 'whisper',
languageDetection: true,
binDirectory
});
// If not installed globally, install the transcriber engine (use pip under the hood)
await transcriber.install('local/pip/path')
// Transcribe
const transcriptFile = await transcriber.transcribe({
mediaFilePath: './myVideo.mp4',
model: 'tiny',
format: 'txt'
});
console.log(transcriptFile.path);
console.log(await transcriptFile.read());
})();Using a local model file:
import { WhisperBuiltinModel } from '@peertube/peertube-transcription/dist'
const transcriptFile = await transcriber.transcribe({
mediaFilePath: './myVideo.mp4',
model: await WhisperBuiltinModel.fromPath('./models/large.pt'),
format: 'txt'
});You may use the builtin Factory if you're happy with the default configuration:
import { transcriberFactory } from '@peertube/peertube-transcription'
transcriberFactory.createFromEngineName({
engineName: transcriberName,
logger: compatibleWinstonLogger,
transcriptDirectory: '/tmp/transcription'
})For further usage ../tests/src/transcription/whisper/transcriber/openai-transcriber.spec.ts
Lexicon
- ONNX: Open Neural Network eXchange. A specification, the ONNX Runtime run these models.
- GPTs: Generative Pre-Trained Transformers
- LLM: Large Language Models
- NLP: Natural Language Processing
- MLP: Multilayer Perceptron
- ASR: Automatic Speech Recognition
- WER: Word Error Rate
- CER: Character Error Rate
Overview (`packages/types-generator/README.md`)
PeerTube typings
These Typescript types are mainly used to write PeerTube plugins.
Installation
Npm:
npm install --save-dev @peertube/peertube-typesUsage
See contribute-plugins Typescript section of the doc.
Overview (`client/src/standalone/embed-player-api/README.md`)
@peertube/embed-api
See https://docs.joinpeertube.org/api/embed-player
Support Doc Api Quickstart (`support/doc/api/quickstart.md`)
REST API quick start
Detect a PeerTube instance
There are several ways to know if a website uses the PeerTube software:
- The server exposes NodeInfo information: https://peertube2.cpy.re/nodeinfo/2.0.json
- The server sends a
x-powered-by: PeerTubeheader response to API requests - HTML pages include a
<meta property="og:platform" content="PeerTube">tag
Authentication
Get client
Some endpoints need authentication. We use OAuth 2.0 so first fetch the client tokens:
::: code-group
curl https://peertube.example.com/api/v1/oauth-clients/localconst { client_id, client_secret } = await fetch('https://peertube.example.com/api/v1/oauth-clients/local', {
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json()):::
Response example:
{
"client_id": "v1ikx5hnfop4mdpnci8nsqh93c45rldf",
"client_secret": "AjWiOapPltI6EnsWQwlFarRtLh4u8tDt"
}Get user token
Now you can fetch the user token:
::: code-group
curl -X POST \
-d "client_id=v1ikx5hnfop4mdpnci8nsqh93c45rldf&client_secret=AjWiOapPltI6EnsWQwlFarRtLh4u8tDt&grant_type=password&response_type=code&username=your_user&password=your_password" \
https://peertube.example.com/api/v1/users/tokenconst { access_token } = await fetch('https://peertube.example.com/api/v1/users/token', {
contentType: 'application/x-www-form-urlencoded',
method: 'POST',
body: new URLSearchParams({
client_id: '...',
client_secret: '...',
username: '...',
password: '...',
grant_type: 'password'
})
}).then(res => res.json()):::
Response example:
{
"access_token": "90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0",
"token_type": "Bearer",
"expires_in": 14399,
"refresh_token": "2e0d675df9fc96d2e4ec8a3ebbbf45eca9137bb7"
}Just use the access_token in the Authorization header:
curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https://peertube.example.com/api/v1/jobs/completedList videos
curl https://peertube.example.com/api/v1/videosLibraries
Convenience libraries can be generated automatically from the OpenAPI specification for languages supported by the OpenAPI generator.
Support Doc Dependencies (`support/doc/dependencies.md`)
Dependencies
:warning: Warning: dependencies guide is maintained by the community. Some parts may be outdated! :warning:
Main dependencies supported by PeerTube:
nodeLTS (>= 22.12 and <25)pnpm>= 12.xpostgres>=14.xredis-server>=6.2ffmpeg>=4.3 (using a ffmpeg static build is not recommended)python>=3.8pip
note: only LTS versions of external dependencies are supported. If no LTS version matching the version constraint is available, only release versions are supported.
note: some distributions still ship a PostgreSQL older than 14 in their default repositories. Check with psql --version after
installing, and if it is too old, install a supported release from the
PostgreSQL official repositories instead of the distribution package.
[[toc]]
Debian / Ubuntu and derivatives
On a fresh Debian/Ubuntu, as root user, install basic utility programs needed for the installation
shsudo apt-get install curl sudo unzip vimIt would be wise to disable root access and to continue this tutorial with a user with sudoers group access. You can see a guide for how to do this in Debian/Ubuntu here.
Install NodeJS 22.x: https://nodesource.com/products/distributions
Install PNPM:
shsudo npm install pnpmInstall Python:
shsudo apt update sudo apt install python3-dev python3-pip python-is-python3 python --version # Should be >= 3.8Install common dependencies:
shsudo apt update sudo apt install certbot nginx ffmpeg postgresql postgresql-contrib openssl g++ make redis-server git cron wget ffmpeg -version # Should be >= 4.1 g++ -v # Should be >= 5.x redis-server --version # Should be >= 6.x psql --version # Should be >= 14Debian 11 (bullseye) and Ubuntu 20.04 ship PostgreSQL 13 or older: on these releases install PostgreSQL from the
PostgreSQL APT repository instead.
Now that dependencies are installed, before running PeerTube you should start PostgreSQL and Redis:
sudo systemctl start redis postgresqlArch Linux
Run:
sudo pacman -S nodejs-lts-iron ffmpeg postgresql openssl redis git wget unzip python python-pip base-devel npm nginx pnpmNow that dependencies are installed, before running PeerTube you should start PostgreSQL and Redis:
sudo systemctl start redis postgresqlCentOS 7
Install NodeJS 22.x: https://nodesource.com/products/distributions
Install PNPM:
shsudo npm install pnpmInstall or compile ffmpeg:
Install Packages:
shsudo yum update sudo yum install epel-release centos-release-scl sudo yum update sudo yum install nginx postgresql postgresql-server postgresql-contrib openssl gcc-c++ make wget redis git devtoolset-7:warning: The CentOS 7 base repository provides PostgreSQL 9.2, which is too old for PeerTube. Install PostgreSQL >= 14 from
the PostgreSQL Yum repository instead of thepostgresql*packages above.You need to use a more up to date version of G++ in order to run the
npm run install-node-dependenciescommand, hence the installation of devtoolset-7.shsudo scl enable devtoolset-7 bashLater when you invoke any node command, please prefix them with
CC=/opt/rh/devtoolset-7/root/usr/bin/gcc CXX=/opt/rh/devtoolset-7/root/usr/bin/g++, such as with:shsudo -H -u peertube CC=/opt/rh/devtoolset-7/root/usr/bin/gcc CXX=/opt/rh/devtoolset-7/root/usr/bin/g++ npm run install-node-dependencies -- --productionInitialize the PostgreSQL database:
shsudo PGSETUP_INITDB_OPTIONS='--auth-host=md5' postgresql-setup --initdb --unit postgresql
Now that dependencies are installed, before running PeerTube you should enable and start PostgreSQL and Redis:
sudo systemctl enable --now redis
sudo systemctl enable --now postgresqlCentos 8
Install NodeJS 22.x: https://nodesource.com/products/distributions
Install PNPM:
shsudo npm install pnpmInstall or compile ffmpeg:
shsudo dnf install epel-release dnf-utils sudo yum-config-manager --set-enabled powertools sudo yum-config-manager --add-repo=https://negativo17.org/repos/epel-multimedia.repo sudo dnf install ffmpegInstall packages:
shsudo dnf update sudo dnf install epel-release sudo dnf update sudo dnf module enable postgresql:16 # Default stream is PostgreSQL 10, too old for PeerTube sudo dnf install nginx postgresql postgresql-server postgresql-contrib openssl gcc-c++ make wget redis git unzip psql --version # Should be >= 14Use
sudo dnf module list postgresqlto see the streams available on your release, and pick the most recent one >= 14.You'll need a symlink for python3 to python for youtube-dl to work
shsudo ln -s /usr/bin/python3 /usr/bin/pythonInitialize the PostgreSQL database:
shsudo PGSETUP_INITDB_OPTIONS='--auth-host=md5' postgresql-setup --initdb --unit postgresql
Now that dependencies are installed, before running PeerTube you should enable and start PostgreSQL and Redis:
sudo systemctl enable --now redis
sudo systemctl enable --now postgresqlRocky Linux 8.4
Pull the latest updates:
shsudo dnf update -yInstall NodeJS 22.x:
shsudo dnf module install -y nodejs:22Install PNPM:
shsudo npm install pnpmInstall or compile ffmpeg (if you want to compile... enjoy):
shsudo dnf install -y epel-release sudo dnf --enablerepo=powertools install -y SDL2 SDL2-devel sudo dnf install -y --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm sudo dnf install -y ffmpeg sudo dnf update -yInstall PostgreSQL and Python3 and other stuff:
shsudo dnf module enable -y postgresql:16 # Default stream is PostgreSQL 10, too old for PeerTube sudo dnf install -y nginx postgresql postgresql-server postgresql-contrib openssl gcc-c++ make wget redis git python3 python3-pip psql --version # Should be >= 14 sudo ln -s /usr/bin/python3 /usr/bin/python sudo PGSETUP_INITDB_OPTIONS='--auth-host=md5' postgresql-setup --initdb --unit postgresql sudo systemctl enable --now redis sudo systemctl enable --now postgresqlUnknown missing steps:
- Steps missing here... these were adapted from the CentOS 8 steps which abruptly ended.
- /var/www/peertube does not exist yet (expected? done in future steps? documentation?).
- Nothing about Certbot, NGINX, Firewall settings, and etc.
- Hopefully someone can suggest what is missing here with some hints so I can add it?
Fedora
Upgrade your packages:
shdnf upgrade(Optional) Install certbot (choose instructions for your distribution):
https://certbot.eff.org/all-instructionsInstall NodeJS 22.x: https://nodesource.com/products/distributions
Install PNPM:
shsudo npm install pnpmEnable RPM Fusion for Fedora (available for x86, x86_64, armhfp)
shsudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpmThis is necessary because
ffmpegis not in the Fedora repos.Run:
shsudo dnf install nginx ffmpeg postgresql-server postgresql-contrib openssl gcc-c++ make redis git vim ffmpeg -version # Should be >= 4.1 g++ -v # Should be >= 5.x redis-server --version # Should be >= 6.xConfigure nginx
shsudo mkdir /etc/nginx/sites-available sudo mkdir /etc/nginx/sites-enabled sudo ln -s /etc/nginx/sites-enabled/peertube /etc/nginx/conf.d/peertube.confPost-installation
from PostgreSQL documentation:
Due to policies for Red Hat family distributions, the PostgreSQL installation will not be enabled for automatic start or have the database initialized automatically.
sh# PostgreSQL sudo PGSETUP_INITDB_OPTIONS='--auth-host=md5' postgresql-setup --initdb --unit postgresql sudo systemctl enable postgresql.service sudo systemctl start postgresql.service # Nginx sudo systemctl enable nginx.service sudo systemctl start nginx.service # Redis sudo systemctl enable redis.service sudo systemctl start redis.serviceFirewall
By default, you cannot access your server via public IP. To do so, you must configure the firewall.
Ports used by peertube dev setup:
shsudo firewall-cmd --permanent --zone=public --add-port=3000/tcp sudo firewall-cmd --permanent --zone=public --add-port=9000/tcp- Optional
shsudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https- Reload firewall
shsudo firewall-cmd --reloadConfigure max ports
This is necessary if you are running dev setup, otherwise you will have errors with
nodemonshecho fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
Red Hat Enterprise Linux 8
Register system as root user to Red Hat Subscription Management (create a free Red Hat account if you don't have one yet).
shsubscription-manager register --username <username> --password <password> --auto-attach dnf upgrade rebootInstall NodeJS
shsudo dnf module install nodejs:22Install PNPM:
shsudo npm install pnpmInstall FFmpeg
shsudo subscription-manager repos --enable "codeready-builder-for-rhel-8-$(arch)-rpms" sudo dnf install --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm sudo dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm sudo dnf upgrade sudo dnf install ffmpegRun:
shsudo dnf module enable postgresql:16 # Default stream is PostgreSQL 10, too old for PeerTube sudo dnf install nginx postgresql postgresql-server postgresql-contrib openssl gcc-c++ make wget redis git psql --version # Should be >= 14You'll need a symlink for python3 to python for youtube-dl to work
shsudo alternatives --set python3 /usr/bin/pythonInitialize the PostgreSQL database:
shsudo PGSETUP_INITDB_OPTIONS='--auth-host=md5' postgresql-setup --initdb --unit postgresqlNow that dependencies are installed, before running PeerTube you should enable and start PostgreSQL and Redis:
shsudo systemctl enable --now redis sudo systemctl enable --now postgresqlIf you are running the production guide, you also need to slightly pre-configure nginx, because nginx is packaged differently in the Red Hat family distributions:
Configure nginx
shsudo mkdir /etc/nginx/sites-available sudo mkdir /etc/nginx/sites-enabled sudo ln -s /etc/nginx/sites-enabled/peertube /etc/nginx/conf.d/peertube.conf sudo systemctl enable --now nginxFirewall
By default, you cannot access your server via public IP. To do so, you must configure firewall:
- Ports used by peertube dev setup:
shsudo firewall-cmd --permanent --zone=public --add-port=3000/tcp sudo firewall-cmd --permanent --zone=public --add-port=9000/tcp- Optional
shsudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https- Reload firewall
shsudo firewall-cmd --reloadConfigure max ports
This is necessary if you are running dev setup, otherwise you will have errors with
nodemonshecho fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
FreeBSD
On a fresh install of FreeBSD, new system or new jail:
bootstrap pkg, initialize db and install peertube's dependencies, always as root (sudo not yet installed):
shpkg pkg update pkg install -y sudo bash wget git python nginx pkgconf postgresql16-server postgresql16-contrib redis openssl node npm ffmpeg unzipinstall
sharpbuild dependencies: https://sharp.pixelplumbing.com/install/#building-from-sourceInstall PNPM:
shsudo npm install pnpmAllow users in the wheel group (hope you don't forgot to add your user on wheel group!) to use sudo.
shvisudoUncomment the line 90
text%wheel ALL=(ALL) ALLEnable nginx, redis, postgresql services and initialize database.
shsysrc postgresql_enable="YES" sysrc redis_enable="YES" sysrc nginx_enable="YES"Initialize database and start services
shservice postgresql initdb service postgresql start service redis start service nginx start
macOS
Add the packages:
shbrew install ffmpeg nginx postgresql@16 openssl gcc make redis git brew install pnpmRun the services:
shbrew services run postgresql@16 brew services run redisOn macOS, the
postgresqluser can be_postgresinstead ofpostgres.
Ifsudo -u postgres createuser -P peertubegives you anunknown user: postgreserror, you can trysudo -u _postgres createuser -U peertube.
Gentoo
Add this to
/etc/portage/sets/peertube:textnet-libs/nodejs sys-apps/pnpm media-video/ffmpeg[x264] # Optionally add vorbis,vpx dev-db/postgresql:16 # Any slot >= 14 works dev-db/redis dev-vcs/git app-arch/unzip dev-lang/python dev-lang/python-exec www-servers/nginx # Optional, client for Letโs Encrypt: # app-crypt/certbotIf you are on a "stable" Gentoo you need to accept the testing keyword ~amd64 pnpm:
shmkdir -p /etc/portage/package.keywords cat << EOF >> /etc/portage/package.keywords/peertube # required by pnpm (argument) for PeerTube sys-apps/pnpm ~amd64 EOFCompile the peertube set:
shemerge -a @peertubeInitialize the PostgreSQL database if you just merged it:
shemerge --config postgresql(For OpenRC) Enable and then start the services (replace with the correct PostgreSQL slot):
shrc-update add redis rc-update add postgresql-16 rc-service redis start rc-service postgresql-16 startCreate Python version symlink for youtube-dl:
shemerge -1 python-exec
OpenBSD
Install Packages:
shpkg_add sudo bash wget git python nginx pkgconf postgresql-server postgresql-contrib redis opensslInstall PNPM:
shsudo npm install pnpmAllow users in the wheel group to use sudo
shvisudoUncomment line #43:
text%wheel ALL=(ALL) ALLEnable services:
shrcctl enable postgresql redis nginx
Other distributions
Feel free to update this file in a pull request!
Support Doc Docker (`support/doc/docker.md`)
Docker guide
This guide requires docker and
docker-compose V2.
docker compose version # Must be > 2.x.xInstall
PeerTube does not support webserver host change. Keep in mind your domain
name is definitive after your first PeerTube start.
Go to your workdir
:::info
The guide that follows assumes an empty workdir, but you can also clone the repository, use the master branch and cd support/docker/production.
:::
cd /your/peertube/directoryGet the latest Compose file
curl https://raw.githubusercontent.com/chocobozzz/PeerTube/master/support/docker/production/docker-compose.yml > docker-compose.ymlView the source of the file you're about to download: docker-compose.yml
Get the latest env_file
curl https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/docker/production/.env > .envView the source of the file you're about to download: .env
Tweak the `docker-compose.yml` file there according to your needs
sudo nano docker-compose.ymlThen tweak the `.env` file to change the environment variables settings
sudo nano .envIn the downloaded example .env, you must replace:
<MY POSTGRES USERNAME><MY POSTGRES PASSWORD><MY DOMAIN>without 'https://'<MY EMAIL ADDRESS><MY PEERTUBE SECRET>
Other environment variables are used in
/support/docker/production/config/custom-environment-variables.yaml and can be
intuited from usage.
Webserver
::: info
The docker compose file includes a configured web server. You can skip this part and comment the appropriate section in the docker compose if you use another webserver/proxy.
:::
Install the template that the nginx container will use.
The container will generate the configuration by replacing ${WEBSERVER_HOST} and ${PEERTUBE_HOST} using your docker compose env file.
mkdir -p docker-volume/nginx docker-volume/nginx-logs
curl https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/nginx/peertube > docker-volume/nginx/peertubeYou need to manually generate the first SSL/TLS certificate using Let's Encrypt:
mkdir -p docker-volume/certbot
docker run -it --rm --name certbot -p 80:80 -v "$(pwd)/docker-volume/certbot/conf:/etc/letsencrypt" certbot/certbot certonly --standaloneA dedicated container in the docker-compose will automatically renew this certificate and reload nginx.
Test your setup
note: Newer versions of compose are called with docker compose instead of docker-compose, so remove the dash in all steps that use this command if you are getting errors.
Run your containers:
docker compose upObtaining your automatically-generated admin credentials
You can change the automatically created password for user root by running this command from peertube's root directory:
docker compose exec -u peertube peertube npm run reset-password -- -u rootYou can also grep your peertube container's logs for the default root password. You're going to want to run docker-compose logs peertube | grep -A1 root to search the log output for your new PeerTube's instance admin credentials which will look something like this.
docker compose logs peertube | grep -A1 root
peertube_1 | [example.com:443] 2019-11-16 04:26:06.082 info: Username: root
peertube_1 | [example.com:443] 2019-11-16 04:26:06.083 info: User password: abcdefghijklmnopObtaining Your Automatically Generated DKIM DNS TXT Record
DKIM signature sending and RSA keys generation are enabled by the default Postfix image mwader/postfix-relay with OpenDKIM.
Run cat ./docker-volume/opendkim/keys/*/*.txt to display your DKIM DNS TXT Record containing the public key to configure to your domain :
cat ./docker-volume/opendkim/keys/*/*.txt
peertube._domainkey.mydomain.tld. IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Dx7wLGPFVaxVQ4TGym/eF89aQ8oMxS9v5BCc26Hij91t2Ci8Fl12DHNVqZoIPGm+9tTIoDVDFEFrlPhMOZl8i4jU9pcFjjaIISaV2+qTa8uV1j3MyByogG8pu4o5Ill7zaySYFsYB++cHJ9pjbFSC42dddCYMfuVgrBsLNrvEi3dLDMjJF5l92Uu8YeswFe26PuHX3Avr261n"
"j5joTnYwat4387VEUyGUnZ0aZxCERi+ndXv2/wMJ0tizq+a9+EgqIb+7lkUc2XciQPNuTujM25GhrQBEKznvHyPA6fHsFheymOuB763QpkmnQQLCxyLygAY9mE/5RY+5Q6J9oDOQIDAQAB" ) ; ----- DKIM key peertube for mydomain.tldAdministrator password
See the production guide "Administrator" section
What now?
See the production guide "What now" section.
Upgrade
::: warning
Check the changelog (in particular the IMPORTANT NOTES section): https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md
:::
Pull the latest images:
cd /your/peertube/directory
docker compose pullStop, delete the containers and internal volumes (to invalidate static client files shared by peertube and webserver containers):
docker compose down -vUpdate the nginx configuration:
mv docker-volume/nginx/peertube docker-volume/nginx/peertube.bak
curl https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/nginx/peertube > docker-volume/nginx/peertubeRerun PeerTube:
docker compose up -dUpgrade PostgreSQL container
If you want to upgrade your PostgreSQL container version (for example because your current version is about to no longer be supported),
you need to plan downtime (to export current cluster and re-import data in new one).
When you're ready, go inside your PeerTube docker compose directory:
cd /docker-compose/directoryPrepare the backups directory and stop all containers except the database:
mkdir -p backups
docker compose stop peertube webserver certbotGo inside the database container:
docker compose exec -it postgres /bin/bashAnd export the database (you don't need to replace $POSTGRES_* variables, they are automatically set by your env file from docker compose):
export PGUSER="$POSTGRES_USER"
export PGDATABASE="$POSTGRES_DB"
export PGPASSWORD="$POSTGRES_PASSWORD"
pg_dumpall > "/tmp/pg.dump"Exit the container:
exitCopy the dump from the container:
docker compose cp postgres:/tmp/pg.dump backups/pg.dumpStop the database container and prepare the data for the new cluster:
docker compose stop postgres
mv ./docker-volume/db ./docker-volume/db.bak
mkdir ./docker-volume/db && chmod 700 ./docker-volume/dbUpgrade your PostgreSQL container version (for example replace postgres:13-alpine by postgres:17-alpine):
vim docker-compose.ymlPull new PostgreSQL Docker image:
docker compose pullRestart PostgreSQL only container and wait until you see: database system is ready to accept connections
docker compose up -d postgres
docker compose logs -f postgresCopy the database dump inside the container:
docker compose cp "backups/pg.dump" postgres:/tmp/pg.dumpGo inside the container
docker compose exec -it postgres /bin/bashCheck the PostgreSQL version and re-import database data.
Then, reset the PeerTube database user password to fix a potential authentication issue if the old password hash algorithm has been deprecated.
export PGUSER="$POSTGRES_USER"
export PGDATABASE="$POSTGRES_DB"
export PGPASSWORD="$POSTGRES_PASSWORD"
psql -U "$POSTGRES_USER" -c "SELECT version();"
psql -U "$POSTGRES_USER" -f /tmp/pg.dump
psql -U "$POSTGRES_USER" -c "ALTER USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD';"Exit the container:
exitRestart other services and check everything is fine:
docker compose up -d peertube webserver certbot
docker compose logs -f peertubeIf you're happy with the results, you can remove backups directory and old data directories:
rm -rf ./docker-volume/db.bak backupsBuild
Production
git clone https://github.com/chocobozzz/PeerTube /tmp/peertube
cd /tmp/peertube
docker build . -f ./support/docker/production/DockerfileDevelopment
We don't have a Docker image for development. See the CONTRIBUTING guide for more information on how you can hack PeerTube!
Support Doc Production (`support/doc/production.md`)
Production guide
Installation
Please don't install PeerTube for production on a device behind a low bandwidth connection (example: your ADSL link).
If you want information about the appropriate hardware to run PeerTube, please see the FAQ.
:hammer: Dependencies
Follow the steps of the dependencies guide.
:construction_worker: PeerTube user
Create a peertube user with /var/www/peertube home:
::: code-group
sudo useradd -m -d /var/www/peertube -s /usr/sbin/nologin peertubesudo pw useradd -n peertube -d /var/www/peertube -s /usr/sbin/nologin -m:::
Ensure the peertube root directory is traversable by nginx:
sudo chmod 755 /var/www/peertube:card_file_box: Database
Create the production database and a peertube user inside PostgreSQL:
cd /var/www/peertube
sudo -u postgres createuser -P peertubeHere you should enter a password for PostgreSQL peertube user, that should be copied in production.yaml file.
Don't just hit enter else it will be empty.
sudo -u postgres createdb -O peertube -E UTF8 -T template0 peertube_prodThen enable extensions PeerTube needs:
sudo -u postgres psql -c "CREATE EXTENSION pg_trgm;" peertube_prod
sudo -u postgres psql -c "CREATE EXTENSION unaccent;" peertube_prod:page_facing_up: Prepare PeerTube directory
Fetch the latest tagged version of Peertube:
VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"Open the peertube directory, create a few required directories:
cd /var/www/peertube
sudo -u peertube mkdir config storage versions
sudo -u peertube chmod 750 config/Download the latest version of the Peertube client, unzip it and remove the zip:
cd /var/www/peertube/versions
# Releases are also available on https://builds.joinpeertube.org/release
sudo -u peertube wget -q "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip"
sudo -u peertube unzip -q peertube-${VERSION}.zip && sudo -u peertube rm peertube-${VERSION}.zipInstall Peertube:
::: code-group
cd /var/www/peertube
sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
cd ./peertube-latest && sudo -H -u peertube npm run install-node-dependencies -- --productioncd /var/www/peertube
sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
cd ./peertube-latest && sudo -H -u peertube npm run install-node-dependencies -- --production
sudo -u peertube pnpm add --workspace-root --no-lockfile --prod node-addon-api node-gyp
sudo -u peertube SHARP_FORCE_GLOBAL_LIBVIPS=1 npm explore sharp -- npm run build:::
:wrench: PeerTube configuration
Copy the default configuration file that contains the default configuration provided by PeerTube.
You must not update this file.
cd /var/www/peertube
sudo -u peertube cp peertube-latest/config/default.yaml config/default.yamlNow copy the production example configuration:
cd /var/www/peertube
sudo -u peertube cp peertube-latest/config/production.yaml.example config/production.yamlThen edit the config/production.yaml file according to your webserver and database configuration. In particular:
webserver: Reverse proxy public informationsecrets: Secret strings you must generate manually (PeerTube version >= 5.0)database: PostgreSQL settingsredis: Redis settingssmtp: If you want to use emailsadmin.email: To correctly fillrootuser email
Keys defined in config/production.yaml will override keys defined in config/default.yaml.
PeerTube does not support webserver host change. Even though PeerTube CLI can help you to switch hostname there's no official support for that since it is a risky operation that might result in unforeseen errors.
:truck: Webserver
We only provide official configuration files for Nginx.
Copy the nginx configuration template:
sudo cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertubeSet the domain for the webserver configuration file by replacing [peertube-domain] with the domain for the peertube server:
sudo sed -i 's/${WEBSERVER_HOST}/[peertube-domain]/g' /etc/nginx/sites-available/peertube
sudo sed -i 's/${PEERTUBE_HOST}/127.0.0.1:9000/g' /etc/nginx/sites-available/peertubeThen modify the webserver configuration file. Please pay attention to:
- the
aliasandrootdirectives paths, the paths must correspond to your PeerTube filesystem location - the
proxy_limit_rateandlimit_ratedirectives if you plan to stream high bitrate videos (like 4K at 60FPS)
sudo vim /etc/nginx/sites-available/peertubeActivate the configuration file:
sudo ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertubeTo generate the certificate for your domain as required to make https work you can use Let's Encrypt:
sudo systemctl stop nginx
sudo certbot certonly --standalone --post-hook "systemctl restart nginx"
sudo systemctl restart nginxCertbot should have installed a cron to automatically renew your certificate.
Since our nginx template supports webroot renewal, we suggest you to update the renewal config file to use the webroot authenticator:
# Replace authenticator = standalone by authenticator = webroot
# Add webroot_path = /var/www/certbot
sudo vim /etc/letsencrypt/renewal/your-domain.com.confIf you plan to have many concurrent viewers on your PeerTube instance, consider increasing worker_connections value: https://nginx.org/en/docs/ngx_core_module.html#worker_connections.
If using FreeBSD
On FreeBSD you can use Dehydrated security/dehydrated for Let's Encrypt
sudo pkg install dehydrated:alembic: Linux TCP/IP Tuning
sudo cp /var/www/peertube/peertube-latest/support/sysctl.d/30-peertube-tcp.conf /etc/sysctl.d/
sudo sysctl -p /etc/sysctl.d/30-peertube-tcp.confYour distro may enable this by default, but at least Debian 9 does not, and the default FIFO
scheduler is quite prone to "Buffer Bloat" and extreme latency when dealing with slower client
links as we often encounter in a video server.
:bricks: systemd
If your OS uses systemd, copy the configuration template:
sudo cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/Check the service file (PeerTube paths and security directives):
sudo vim /etc/systemd/system/peertube.serviceTell systemd to reload its config:
sudo systemctl daemon-reloadIf you want to start PeerTube on boot:
sudo systemctl enable peertubeRun:
sudo systemctl start peertube
sudo journalctl -feu peertubeIf using FreeBSD
On FreeBSD, copy the startup script and update rc.conf:
sudo install -m 0555 /var/www/peertube/peertube-latest/support/freebsd/peertube /usr/local/etc/rc.d/
sudo sysrc peertube_enable="YES"Run:
sudo service peertube startIf using OpenRC
If your OS uses OpenRC, copy the service script:
sudo cp /var/www/peertube/peertube-latest/support/init.d/peertube /etc/init.d/
sudo cp /var/www/peertube/peertube-latest/support/conf.d/peertube /etc/conf.d/If you want to start PeerTube on boot:
sudo rc-update add peertube defaultRun and print last logs:
sudo /etc/init.d/peertube start
tail -f /var/log/peertube/peertube.log:technologist: Administrator
The administrator username is root and the password is automatically generated. It can be found in PeerTube
logs (path defined in production.yaml). You can also set another password with:
cd /var/www/peertube/peertube-latest && sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u rootAlternatively you can set the environment variable PT_INITIAL_ROOT_PASSWORD,
to your own administrator password, although it must be 6 characters or more.
:tada: What now?
Now your instance is up you can:
- Add your instance to the public PeerTube instances index if you want to: https://instances.joinpeertube.org/
- Check available CLI tools
Upgrade
PeerTube instance
Check the changelog (in particular the IMPORTANT NOTES section): https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md
Run the upgrade script (the password it asks is PeerTube's database user password):
::: code-group
cd /var/www/peertube/peertube-latest/scripts && sudo -H -u peertube ./upgrade.shcd /var/www/peertube/peertube-latest/scripts && sudo -H -u peertube ./upgrade.sh
sudo -u peertube pnpm add --workspace-root --no-lockfile --prod node-addon-api node-gyp
sudo -u peertube SHARP_FORCE_GLOBAL_LIBVIPS=1 npm explore sharp -- npm run build:::
If you have git installed on your system, the upgrade will create a production.yaml.new file with differences marked as merge conflicts.
Review this file and replace your existing production.yaml with it before restarting.
# Make sure you first updated your configuration per the note above
sudo systemctl restart peertube # Or use your OS command to restart PeerTube if you don't use systemdYou may want to run sudo -u peertube pnpm store prune after several upgrades to free up disk space.
Prefer manual upgrade?
Make a SQL backup
SQL_BACKUP_PATH="backup/sql-peertube_prod-$(date -Im).bak" && \
cd /var/www/peertube && sudo -u peertube mkdir -p backup && \
sudo -u postgres pg_dump -F c peertube_prod | sudo -u peertube tee "$SQL_BACKUP_PATH" >/dev/nullFetch the latest tagged version of Peertube:
VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"Download the new version and unzip it:
cd /var/www/peertube/versions && \
sudo -u peertube wget -q "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip" && \
sudo -u peertube unzip -o peertube-${VERSION}.zip && \
sudo -u peertube rm peertube-${VERSION}.zipInstall node dependencies:
cd /var/www/peertube/versions/peertube-${VERSION} && \
sudo -H -u peertube npm run install-node-dependencies -- --productionCopy new configuration defaults values and update your configuration file:
sudo -u peertube cp /var/www/peertube/versions/peertube-${VERSION}/config/default.yaml /var/www/peertube/config/default.yaml
diff -u /var/www/peertube/versions/peertube-${VERSION}/config/production.yaml.example /var/www/peertube/config/production.yamlChange the link to point to the latest version:
cd /var/www/peertube && \
sudo unlink ./peertube-latest && \
sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latestUpdate PeerTube configuration
If your system has git installed, the auto upgrade script should have created a config/production.yaml.new file that merges your current configuration file with the new configuration keys introduced by the new PeerTube version.
Review the file, check and fix any potential conflicts:
cd /var/www/peertube && sudo -u peertube diff config/production.yaml config/production.yaml.newThen replace your current configuration file by the new one:
cd /var/www/peertube && sudo -u peertube cp config/production.yaml.new config/production.yamlUpdate nginx configuration
Check changes in nginx configuration:
cd /var/www/peertube/versions
diff -u "$(ls -t | head -2 | tail -1)/support/nginx/peertube" "$(ls -t | head -1)/support/nginx/peertube"Update systemd service
Check changes in systemd configuration:
cd /var/www/peertube/versions
diff -u "$(ls -t | head -2 | tail -1)/support/systemd/peertube.service" "$(ls -t | head -1)/support/systemd/peertube.service"If using OpenRC
cd /var/www/peertube/versions
diff -u "$(ls -t | head -2 | tail -1)/support/init.d/peertube" "$(ls -t | head -1)/support/init.d/peertube"
diff -u "$(ls -t | head -2 | tail -1)/support/conf.d/peertube" "$(ls -t | head -1)/support/conf.d/peertube"Restart PeerTube
If you changed your nginx configuration:
sudo systemctl reload nginxIf you changed your systemd configuration:
sudo systemctl daemon-reloadRestart PeerTube and check the logs:
sudo systemctl restart peertube && sudo journalctl -fu peertubeThings went wrong?
Change peertube-latest destination to the previous version and restore your SQL backup:
OLD_VERSION="v0.42.42" && SQL_BACKUP_PATH="backup/sql-peertube_prod-20180119-1018.bak" && \
cd /var/www/peertube && sudo -u peertube unlink ./peertube-latest && \
sudo -u peertube ln -s "versions/peertube-$OLD_VERSION" peertube-latest && \
sudo -u postgres pg_restore -c -C -d peertube_prod "$SQL_BACKUP_PATH" && \
sudo systemctl restart peertubeSupport Doc Tools (`support/doc/tools.md`)
CLI tools guide
[[toc]]
Remote PeerTube CLI
peertube-cli is a tool that communicates with a PeerTube instance using its REST API.
It can be launched from a remote server/computer to easily upload videos, manage plugins, redundancies etc.
Installation
Ensure you have node installed on your system:
node --version # Should be >= 22.xThen install the CLI:
sudo npm install @peertube/peertube-cliCLI wrapper
The wrapper provides a convenient interface to the following sub-commands.
Usage: peertube-cli [command] [options]
Options:
-v, --version output the version number
-h, --help display help for command
Commands:
auth Register your accounts on remote instances to use them with other commands
upload|up [options] Upload a video on a PeerTube instance
redundancy|r Manage instance redundancies
plugins|p Manage instance plugins/themes
get-access-token|token [options] Get a peertube access token
help [command] display help for commandThe wrapper can keep track of instances you have an account on. We limit to one account per instance for now.
peertube-cli auth add -u 'PEERTUBE_URL' -U 'PEERTUBE_USER' --password 'PEERTUBE_PASSWORD'Now list the account(s) you've created
peertube-cli auth listโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ instance โ login โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 'PEERTUBE_URL' โ 'PEERTUBE_USER' โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโYou can now use that account to execute sub-commands without feeding the --url, --username and --password parameters:
peertube-cli upload <videoFile>peertube-cli plugins list
...peertube-cli upload
You can use this script to upload videos directly from the CLI.
Videos will be publicly available after transcoding (you can see them before that in your account on the web interface).
cd ${CLONE}
peertube-cli upload --helppeertube-cli plugins
Install/update/uninstall or list local or NPM PeerTube plugins:
cd ${CLONE}
peertube-cli plugins --help
peertube-cli plugins list --help
peertube-cli plugins install --help
peertube-cli plugins update --help
peertube-cli plugins uninstall --help
peertube-cli plugins install --path /my/plugin/path
peertube-cli plugins install --npm-name peertube-theme-examplepeertube-cli redundancy
Manage (list/add/remove) video redundancies:
To list your videos that are duplicated by remote instances:
peertube-cli redundancy list-remote-redundanciesTo list remote videos that your instance duplicated:
peertube-cli redundancy list-my-redundanciesTo duplicate a specific video in your redundancy system:
peertube-cli redundancy add --video 823To remove a video redundancy:
peertube-cli redundancy remove --video 823PeerTube runner
PeerTube supports VOD/Live transcoding and VOD transcription (PeerTube >= 6.2) by a remote PeerTube runner.
The runner communicates with the PeerTube instance using HTTP and WebSocket and doesn't need to have a public IP.
So you can run a runner on a classic server, a non-public server or even on your own computer!
You can read the admin documentation on how to use PeerTube runners on https://docs.joinpeertube.org/admin/remote-runners
Runner installation
Ensure you have node, ffmpeg and ffprobe installed on your system:
node --version # Should be >= 22.x
ffprobe -version # Should be >= 4.3
ffmpeg -version # Should be >= 4.3If you want to use video transcription:
pip install whisper-ctranslate2 # or pipx install whisper-ctranslate2 depending on your distributionThen install the CLI:
sudo npm install @peertube/peertube-runnerConfiguration
The runner uses env paths like ~/.config, ~/.cache and ~/.local/share directories to store runner configuration or temporary files.
Multiple PeerTube runners can run on the same OS by using the --id CLI option (each runner uses its own config/tmp directories):
peertube-runner [commands] --id instance-1
peertube-runner [commands] --id instance-2
peertube-runner [commands] --id instance-3You can change the runner configuration (jobs concurrency, ffmpeg threads/nice, whisper engines/models, etc.) by editing ~/.config/peertube-runner-nodejs/[id]/config.toml.
The runner TOML config template consists of:
[jobs]
# How much concurrent jobs the runner can execute in parallel
concurrency = 2
[ffmpeg]
# How much threads a ffmpeg process can use
# 0 -> let ffmpeg automatically choose
threads = 0
nice = 20
[transcription]
# Choose between "openai-whisper" or "whisper-ctranslate2"
# Engine binary has to be installed manually (unlike the PeerTube instance that can install whisper automatically)
engine = "whisper-ctranslate2"
# Optional whisper binary path if not available in global path
enginePath = "/var/prunner/.local/pipx/venvs/whisper-ctranslate2/bin/whisper-ctranslate2"
# Whisper model: "tiny", "base", "small", "medium", "large-v2" or "large-v3"
model = "large-v2"
# Registered instances are saved in the config file
[[registeredInstances]]
url = "..." # URL of the instance
runnerToken = "..." # Shared runner token secret
runnerName = "..." # Runner name declared to the PeerTube instance
[[registeredInstances]]
url = "..."
runnerToken = "..."
runnerName = "..."Run the server
In a shell
You need to run the runner in server mode first so it can run transcoding jobs of registered PeerTube instances:
peertube-runner serverYou can also decide which kind of job the runner can execute with --enable-job <type> option.
This way you can have one dedicated runner for transcription tasks (on a GPU machine for example) and another one for transcoding tasks.
Only transcription tasks
peertube-runner server --enable-job video-transcriptionOnly VOD transcoding tasks
peertube-runner server --enable-job vod-web-video-transcoding --enable-job vod-hls-transcoding --enable-job vod-audio-merge-transcodingOnly "studio" transcoding
peertube-runner server --enable-job video-studio-transcodingOnly "live" transcoding
peertube-runner server --enable-job live-rtmp-hls-transcodingAs a Systemd service
If your OS uses systemd, you can also configure a service so that the runner starts automatically.
To do so, first create a dedicated user. Here, we are calling it prunner, but you can choose whatever name you want.
We are using /srv/prunner as his home dir, but you can choose any other path.
useradd -m -d /srv/prunner -s /usr/sbin/nologin prunner::: info Note
If you want to use /home/prunner, you have to set ProtectHome=false in the systemd configuration (see below).
:::
Now, you can create the /etc/systemd/system/prunner.service file (don't forget to adapt path and user/group names if you changed it):
[Unit]
Description=PeerTube runner daemon
After=network.target
[Service]
Type=simple
Environment=NODE_ENV=production
User=prunner
Group=prunner
ExecStart=peertube-runner server
WorkingDirectory=/srv/prunner
SyslogIdentifier=prunner
Restart=always
; Some security directives.
; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
ProtectSystem=full
; Sets up a new /dev mount for the process and only adds API pseudo devices
; like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled
; by default because it may not work on devices like the Raspberry Pi.
PrivateDevices=false
; Ensures that the service process and all its children can never gain new
; privileges through execve().
NoNewPrivileges=true
; This makes /home, /root, and /run/user inaccessible and empty for processes invoked
; by this unit. Make sure that you do not depend on data inside these folders.
ProtectHome=true
; Drops the sys admin capability from the daemon.
CapabilityBoundingSet=~CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target:::info Note
You can add the parameter --id instance-1 on the ExecStart line, if you want to have multiple instances.
You can then create multiple separate services. They can use the same user and path.
:::
Finally, to enable the service for the first time:
systemctl daemon-reload
systemctl enable prunner.service
systemctl restart prunner.serviceNext time, if you need to start/stop/restart the service:
systemctl stop prunner.service
systemctl start prunner.service
systemctl restart prunner.serviceYou can also check the status (and last logs):
systemctl status prunner.serviceTo edit the runner configuration: juste edit the /srv/prunner/.config/peertube-runner-nodejs/default/config.toml file,
and restart the service (this file will be created when the runner starts for the first time).
If you are using the --id parameter, you can change specific configuration by editing the file /srv/prunner/.config/peertube-runner-nodejs/[id]/config.toml.
::: info
For every peertube-runner commands described below, you have to run them as the prunner user.
So for example, to call the list-registered command: sudo -u prunner peertube-runner list-registered.
Otherwise the script will read the wrong configuration and cache files, and won't work as expected.
:::
Register
Then, you can register the runner to process transcoding job of a remote PeerTube instance:
::: code-group
peertube-runner register --url http://peertube.example.com --registration-token ptrrt-... --runner-name my-runner-namesudo -u prunner peertube-runner register --url http://peertube.example.com --registration-token ptrrt-... --runner-name my-runner-name:::
The runner will then use a websocket connection with the PeerTube instance to be notified about new available transcoding jobs.
Unregister
To unregister a PeerTube instance:
::: code-group
peertube-runner unregister --url http://peertube.example.com --runner-name my-runner-namesudo -u prunner peertube-runner unregister --url http://peertube.example.com --runner-name my-runner-name:::
List registered instances
::: code-group
peertube-runner list-registeredsudo -u prunner peertube-runner list-registered:::
List jobs
Runner >= 0.1.0
To list jobs that are processed by the runner:
::: code-group
peertube-runner list-jobs
peertube-runner list-jobs --include-payloadsudo -u prunner peertube-runner list-jobs
sudo -u prunner peertube-runner list-jobs --include-payload:::
Graceful shutdown
Ask the runner to shutdown when it has finished all of its current tasks:
::: code-group
peertube-runner graceful-shutdownsudo -u prunner peertube-runner graceful-shutdown:::
Update the runner package
You can check if there is a new runner version using:
sudo npm outdated -g @peertube/peertube-runnerPackage Current Wanted Latest Location Depended by
@peertube/peertube-runner 0.0.6 0.0.7 0.0.7 node_modules/@peertube/peertube-runner libTo update the runner:
Update the package
sudo npm update -g @peertube/peertube-runnerCheck that the version changed (optional)
sudo npm list -g @peertube/peertube-runnerRestart the service (if you are using systemd)
sudo systemctl restart prunner.serviceServer tools
Server tools are scripts that interact directly with the code of your PeerTube instance.
They must be run on the server, in peertube-latest directory.
Parse logs
To parse PeerTube last log file:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run parse-log -- --level infocd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run parse-log -- --level info:::
--level is optional and could be info/warn/error
You can also remove SQL or HTTP logs using --not-tags:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run parse-log -- --level debug --not-tags http sqlcd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run parse-log -- --level debug --not-tags http sql:::
Regenerate video and playlist thumbnails
Regenerating local video and playlist thumbnails could be useful because new PeerTube releases may increase thumbnail sizes:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run regenerate-thumbnailscd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run regenerate-thumbnails:::
Add or replace specific video file
You can use this script to import a video file to replace an already uploaded file or to add a new web compatible resolution to a video. PeerTube needs to be running.
You can then create a transcoding job using the web interface if you need to optimize your file or create an HLS version of it.
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-import-video-file-job -- -v [videoUUID] -i [videoFile]cd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-import-video-file-job -- -v [videoUUID] -i [videoFile]:::
Move video files from filesystem to object storage
Use this script to move video related files (video files, original video file, captions, etc.) to object storage.
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-move-video-storage-job -- --to-object-storage -v [videoUUID]cd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-move-video-storage-job -- --to-object-storage -v [videoUUID]:::
The script can also move all video related files that are not already in object storage:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-move-video-storage-job -- --to-object-storage --all-videoscd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-move-video-storage-job -- --to-object-storage --all-videos:::
Move video files from object storage to filesystem
PeerTube >= 6.0
Use this script to move video related files (video files, original video file, captions, etc.) from object storage to the PeerTube instance filesystem.
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-move-video-storage-job -- --to-file-system -v [videoUUID]cd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-move-video-storage-job -- --to-file-system -v [videoUUID]:::
The script can also move all video related files that are not already on the filesystem:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-move-video-storage-job -- --to-file-system --all-videoscd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-move-video-storage-job -- --to-file-system --all-videos:::
Cleanup remote files
PeerTube >= 6.2
Use this script to recover disk space by removing remote files (thumbnails, avatars...) that can be re-fetched later by your PeerTube instance on-demand.
Restart PeerTube after running this script.
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run house-keeping -- --delete-remote-filescd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run house-keeping -- --delete-remote-files:::
Generate storyboard
PeerTube >= 6.0
Use this script to generate storyboard of a specific video:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-generate-storyboard-job -- -v [videoUUID]cd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-generate-storyboard-job -- -v [videoUUID]:::
The script can also generate all missing storyboards of local videos:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-generate-storyboard-job -- --all-videoscd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run create-generate-storyboard-job -- --all-videos:::
Prune filesystem/object storage
Some transcoded videos or shutdown at a bad time can leave some unused files on your storage.
To delete these files (a confirmation will be demanded first):
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run prune-storagecd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run prune-storage:::
It's also possible to remove more local files if your stop PeerTube using the --offline option:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run prune-storage -- --offlinecd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run prune-storage -- --offline:::
Update PeerTube instance domain name
Changing the hostname is unsupported and may be a risky operation, especially if you have already federated.
If you started PeerTube with a domain, and then changed it you will have
invalid torrent files and invalid URLs in your database. To fix this, you have
to run the command below (keep in mind your follower instances will NOT update their URLs).
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run update-hostcd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run update-host:::
Reset user password
To reset a user password from CLI, run:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u target_usernamecd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run reset-password -- -u target_username:::
Install or uninstall plugins
The difference with peertube plugins CLI is that these scripts can be used even if PeerTube is not running.
If PeerTube is running, you need to restart it for the changes to take effect (whereas with peertube plugins CLI, plugins/themes are dynamically loaded on the server).
To install/update a plugin or a theme from the disk:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run plugin:install -- --plugin-path /local/plugin/pathcd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run plugin:install -- --plugin-path /local/plugin/path:::
From NPM:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run plugin:install -- --npm-name peertube-plugin-myplugincd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run plugin:install -- --npm-name peertube-plugin-myplugin:::
To uninstall a plugin or a theme:
::: code-group
cd /var/www/peertube/peertube-latest; \
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run plugin:uninstall -- --npm-name peertube-plugin-myplugincd /var/www/peertube-docker; \
docker compose exec -u peertube peertube npm run plugin:uninstall -- --npm-name peertube-plugin-myplugin:::
Support Doc Translation (`support/doc/translation.md`)
Translation
We use Weblate as translation platform.
Please do not edit translation files directly from Git, you have to use Weblate!
If you don't see your locale in the platform you can add it directly in the Weblate interface.
Then, if you think there are enough translated strings, please create an issue so we add the new locale in PeerTube!
Translations are manually pulled and merged in PeerTube software and are publicly available in the next official release.
You can get a chance to see translations before the official release by going to https://peertube2.cpy.re which is updated every night with the latest PeerTube changes.
How to
- Create an account: https://weblate.framasoft.org/accounts/register/
- Validate your email and follow the link sent
- Create your password (keep the
Current passwordfield empty) and set up your account - To translate the PeerTube web, visit the PeerTube project page: https://weblate.framasoft.org/projects/peertube/
- To translate the PeerTube mobile application, visit the PeerTube App project page: https://weblate.framasoft.org/projects/peertube-app/
- Choose the file and the locale you want to translate
Files
There are 4 files:
- angular: contains client strings
- player: contains player strings.
Most of the strings come from VideoJS, so you can help yourself by using video.js JSON files - server: contains server strings clients can fetch in JSON format so they don't have to translate common PeerTube strings themselves (iso639 languages, privacies, licences...)
- server-internal: contains internal server strings used in the REST API responses or emails
Tips
Special tags
You must not translate special tags like <x id="INTERPOLATION" ... />.
For example:
<x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> viewsshould be in French
<x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vuesSingular/plural
For singular/plural translations, you must translate values inside { and }. Please don't translate the word other
For example:
{VAR_PLURAL, plural, =0 {No videos} =1 {1 video} other {<x id="INTERPOLATION" equiv-text="{{ playlist.videosLength }}"/> videos} }should be in French
{VAR_PLURAL, plural, =0 {Aucune vidรฉo} =1 {1 vidรฉo} other {<x id="INTERPOLATION" equiv-text="{{ playlist.videosLength }}"/> vidรฉos} }Support Doc Api Embeds (`support/doc/api/embeds.md`)
PeerTube Embed API
PeerTube lets you embed videos and programmatically control their playback. This documentation covers how to interact with the PeerTube Embed API.
Playground
Any PeerTube embed URL (ie https://my-instance.example.com/videos/embed/52a10666-3a18-4e73-93da-e8d3c12c305a) can be viewed as an embedding playground which
allows you to test various aspects of PeerTube embeds. Simply replace /embed with /test-embed and visit the URL in a browser.
For instance, the playground URL for the above embed URL is https://my-instance.example.com/videos/test-embed/52a10666-3a18-4e73-93da-e8d3c12c305a.
Quick Start
Given an existing PeerTube embed `` with API enabled (https://my-instance.example.com/videos/embed/52a10666-3a18-4e73-93da-e8d3c12c305a?api=1),
one can use the PeerTube Embed API to control it by first including the library. You can include it via NPM with:
npm install @peertube/embed-apiNow just use the PeerTubePlayer class exported by the module:
import { PeerTubePlayer } from '@peertube/embed-api.js'
...Or use the minified build from NPM CDN in your HTML file:
<script src="https://unpkg.com/@peertube/embed-api/build/player.min.js"></script>
<script>
const PeerTubePlayer = window['PeerTubePlayer']
...
</script>Then you can instantiate the player:
let player = new PeerTubePlayer(document.querySelector('iframe'))
await player.ready // wait for the player to be ready
// now you can use it!
player.play()
player.seek(32)
player.pause()Embed URL parameters
You can customize PeerTube player by specifying URL query parameters.
For example https://my-instance.example.com/videos/embed/52a10666-3a18-4e73-93da-e8d3c12c305a?start=1s&stop=18s&loop=1&autoplay=1&muted=1&warningTitle=0&controlBar=0&peertubeLink=0&p2p=0
start
Start the video at a specific time.
Value must be raw seconds or a duration (3m4s)
Default: starts at 0
stop
Stop the video at a specific time.
Value must be raw seconds or a duration (54s)
Default: ends at content end
controls
Mimics video HTML element controls attribute, meaning that all controls (including big play button, control bar, etc.) will be removed.
It can be useful if you want to have a full control of the PeerTube player.
Value must be 0 or 1.
Default: 1
controlBar
Hide control bar when the video is played.
Value must be 0 or 1.
Default: 1
peertubeLink
Hide PeerTube instance link in control bar.
Value must be 0 or 1.
Default: 1
muted
Mute the video by default.
Value must be 0 or 1.
Default: tries to restore the last muted setting set by the user
loop
Automatically start again the video when it ends.
Value must be 0 or 1.
Default: 0
subtitle
Auto select a subtitle by default.
Value must be a valid subtitle ISO code (fr, en, etc.).
Default: no subtitle selected and then tries to restore the last subtitle set by the user
autoplay
Try to automatically play the video.
Most web browsers disable video autoplay if the user did not interact with the video. You can try to bypass this limitation by muting the video.
Value must be 0 or 1.
Default: 0
playbackRate
Force the default playback rate (0.75, 1.5 etc).
Default: 1
title
Show/Hide embed title.
Value must be 0 or 1.
Default: 1
warningTitle
Show/Hide P2P warning title.
Value must be 0 or 1.
Default: 1
p2p
Enable/Disable P2P.
Value must be 0 or 1.
Default: tries to use the user setting and fallbacks to instance setting if user setting is not found
bigPlayBackgroundColor
Customize big play button background color.
Value must be a valid color (red or rgba(100, 100, 100, 0.5)).
Default: rgba(0, 0, 0, 0.8)
foregroundColor
Customize embed font color.
Value must be a valid color (red or rgba(100, 100, 100, 0.5)).
Default: white
mode
Force a specific player engine.
Value must be a valid mode (web-video or p2p-media-loader).
See behaviour description here
Default: p2p-media-loader and fallback to web-video mode.
playlistPosition
If you are embedding a playlist, select the video to play by specifying its position.
Value must be a number.
Default: 1
api
Enable/Disable embed JavaScript API (see methods below).
Value must be 0 or 1.
Default: 0
waitPasswordFromEmbedAPI
PeerTube >= 6.0
If the video requires a password, PeerTube will wait a password provided by setVideoPassword method before loading the video.
Until you provide a password, player.ready is not resolved.
Value must be 0 or 1.
Default: 0
Embed attributes
`ready: Promise`
This promise is resolved when the video is loaded and the player is ready.
Embed methods
`isPlaying(): Promise`
PeerTube >= 7.0
Check if the player is playing the media.
`play(): Promise`
Starts playback, or resumes playback if it is paused.
`pause(): Promise`
Pauses playback.
`getCurrentTime(): Promise`
PeerTube >= 7.0
Get player current time in seconds.
`seek(positionInSeconds : number): Promise`
Seek to the given position, as specified in seconds into the video.
`addEventListener(eventName : string, handler : Function)`
Add a listener for a specific event. See below for the available events.
`removeEventListener(eventName : string, handler : Function)`
Remove a listener.
`getResolutions() : Promise`
Get the available resolutions. A PeerTubeResolution looks like:
{
"id": 3,
"label": "720p",
"height": "720",
"active": true
}active is true if the resolution is the currently selected resolution.
`setResolution(resolutionId : number): Promise`
Change the current resolution. Pass -1 for automatic resolution (when available).
Otherwise, resolutionId should be the ID of an object returned by getResolutions()
`getPlaybackRates() : Promise`
Get the available playback rates, where 1 represents normal speed, 0.5 is half speed, 2 is double speed, etc.
`getPlaybackRate() : Promise`
Get the current playback rate. See getPlaybackRates() for more information.
`setPlaybackRate(rate: number) : Promise`
Set the current playback rate. The passed rate should be a value as returned by getPlaybackRates().
`setVolume(factor: number) : Promise`
Set the playback volume. Value should be between 0 and 1.
`getVolume(): Promise`
Get the playback volume. Returns a value between 0 and 1.
`setCaption(id: string) : Promise`
Update current caption using the caption id.
`getCaptions(): Promise<{ id: string, label: string, src: string, mode: 'disabled' | 'showing' }>`
Get video captions.
`playNextVideo(): Promise`
Play next video in playlist.
`playPreviousVideo(): Promise`
Play previous video in playlist.
`getCurrentPosition(): Promise`
Get current position in playlist (starts from 1).
`setVideoPassword(): Promise`
PeerTube >= 6.0
Set the video password so the user doesn't have to manually fill it.waitPasswordFromEmbedAPI=1 is required in embed URL.
`getImageDataUrl(): Promise`
PeerTube >= 6.2
Get the current frame as JPEG image data URL.
Embed events
You can subscribe to events by using addEventListener(). See above for details.
Event `playbackStatusUpdate`
Fired every half second to provide the current status of playback.
The parameter of the callback will resemble:
{
"position": 22.3,
"volume": 0.9,
"duration": "171.37499",
"playbackState": "playing"
}duration field and ended playbackState are available in PeerTube >= 2.2.
The volume field contains the volume from 0 (silent) to 1 (full volume).
The playbackState can be unstarted, playing, paused or ended. More states may be added later.
Event `playbackStatusChange`
Fired when playback transitions between states, such as paused and playing. More states may be added later.
Event `resolutionUpdate`
Fired when the available resolutions have changed, or when the currently selected resolution has changed. Listener should call getResolutions() to get the updated information.
Event `volumeChange`
Fired when the player volume changed.
Support Doc Api Openapi.Yaml (`support/doc/api/openapi.yaml`)
openapi: 3.0.3
info:
title: PeerTube
version: 8.3.0
contact:
name: PeerTube Community
url: https://joinpeertube.org
license:
name: AGPLv3.0
url: https://github.com/Chocobozzz/PeerTube/blob/master/LICENSE
x-logo:
url: https://joinpeertube.org/img/brand.png
altText: PeerTube Project Homepage
The PeerTube API is built on HTTP(S) and is RESTful. You can use your favorite
HTTP/REST library for your programming language to use PeerTube.
See the [REST API quick start](https://docs.joinpeertube.org/api/rest-getting-started) for a few
examples of using the PeerTube API.
# Authentication
When you sign up for an account on a PeerTube instance, you are given the possibility
to generate sessions on it, and authenticate there using an access token. Only __one
access token can currently be used at a time__.
## Roles
Accounts are given permissions based on their role. There are three roles on
PeerTube: Administrator, Moderator, and User. See the [roles guide](https://docs.joinpeertube.org/admin/managing-users#roles) for a detail of their permissions.
# Errors
The API uses standard HTTP status codes to indicate the success or failure
of the API call, completed by a [RFC7807-compliant](https://tools.ietf.org/html/rfc7807) response body.
```
HTTP 1.1 404 Not Found
Content-Type: application/problem+json; charset=utf-8
{
"detail": "Video not found",
"docs": "https://docs.joinpeertube.org/api-rest-reference.html#operation/getVideo",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}
```
We provide error `type` (following RFC7807) and `code` (internal PeerTube code) values for [a growing number of cases](https://github.com/Chocobozzz/PeerTube/blob/develop/packages/models/src/server/server-error-code.enum.ts),
but it is still optional. Types are used to disambiguate errors that bear the same status code
and are non-obvious:
```
HTTP 1.1 403 Forbidden
Content-Type: application/problem+json; charset=utf-8
{
"detail": "Cannot get this video regarding follow constraints",
"docs": "https://docs.joinpeertube.org/api-rest-reference.html#operation/getVideo",
"status": 403,
"title": "Forbidden",
"type": "https://docs.joinpeertube.org/api-rest-reference.html#section/Errors/does_not_respect_follow_constraints"
}
```
Here a 403 error could otherwise mean that the video is private or blocklisted.
## Validation errors
Example:
```
HTTP 1.1 400 Bad Request
Content-Type: application/problem+json; charset=utf-8
{
"detail": "Incorrect request parameters: id",
"docs": "https://docs.joinpeertube.org/api-rest-reference.html#operation/getVideo",
"instance": "/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180",
"invalid-params": {
"id": {
"location": "params",
"msg": "Invalid value",
"param": "id",
"value": "9c9de5e8-0a1e-484a-b099-e80766180"
}
},
"status": 400,
"title": "Bad Request",
"type": "about:blank"
}
```
Where `id` is the name of the field concerned by the error, within the route definition.
`invalid-params.<field>.location` can be either 'params', 'body', 'header', 'query' or 'cookies'.
`invalid-params.<field>.value` reports the value that didn't pass validation whose `invalid-params.<field>.msg` is about.
## max_file_size_reached
The uploaded file exceeds the instance-wide file size limit.
## quota_reached
The uploaded file exceeds the user's storage quota.
## does_not_respect_follow_constraints
The requested remote resource cannot be accessed because the instance does not follow its origin.
## live_not_enabled
Live streaming is not enabled on the instance.
## live_not_allowing_replay
Saving live replays is disabled on this instance, so a live cannot be created or updated with `saveReplay` enabled.
## live_conflicting_permanent_and_save_replay
Not returned by PeerTube anymore: permanent lives can save replays.
## max_instance_lives_limit_reached
The instance has reached its maximum number of simultaneous live streams.
## max_user_lives_limit_reached
The user has reached the maximum number of simultaneous live streams.
## incorrect_files_in_torrent
The torrent does not contain exactly one usable video file.
## comment_not_associated_to_video
The comment is not associated with the requested video.
## invalid_grant
The OAuth grant or refresh token is invalid.
## invalid_client
Client authentication failed.
## invalid_token
The access token is expired, revoked, malformed, or otherwise invalid.
## unauthorized_request
The endpoint requires authentication but no access token was provided.
## invalid_request
The authentication or token request is malformed: missing `grant_type`, malformed `Authorization` header,
access token sent using more than one method, or sent in the query string.
## unsupported_grant_type
The `grant_type` is not supported. PeerTube supports `password` and `refresh_token`.
## unauthorized_client
The OAuth client is not allowed to use the requested `grant_type`.
## server_error
An unexpected error occurred while checking the access token.
## missing_two_factor
The required two-factor authentication header is missing.
## too_long_password
The password exceeds the maximum allowed length.
## invalid_two_factor
The two-factor authentication code is invalid.
## account_blocked
The account is blocked.
## email_not_verified
The account email address has not been verified.
## account_waiting_for_approval
The account is waiting for administrator approval.
## account_approval_rejected
The account approval request was rejected.
## runner_job_not_in_processing_state
The runner job is not in the processing state.
## runner_job_not_in_pending_state
The runner job is not in the pending state.
## unknown_runner_token
The runner token is unknown.
## video_requires_password
A password is required to access the video.
## incorrect_video_password
The password provided for the video is incorrect.
## video_already_being_transcoded
The video is already being transcoded.
## video_already_being_transcribed
The video is already being transcribed.
## video_already_has_captions
The video already has captions.
## max_user_video_quota_exceeded_for_user_export
The user requested an export including video files, but the total size of their videos is above the maximum allowed by the instance for such exports.
Request an export without video files instead.
## current_password_is_invalid
The current password is invalid.
# Rate limits
We are rate-limiting all endpoints of PeerTube's API. Custom values can be set by administrators:
| Endpoint (prefix: `/api/v1`) | Calls | Time frame |
|------------------------------|---------------|--------------|
| `/*` | 50 | 10 seconds |
| `POST /users/token` | 15 | 5 minutes |
| `POST /users/register` | 2<sup>*</sup> | 5 minutes |
| `POST /users/ask-send-verify-email` | 3 | 5 minutes |
Depending on the endpoint, <sup>*</sup>failed requests are not taken into account. A service
limit is announced by a `429 Too Many Requests` status code.
You can get details about the current state of your rate limit by reading the
following headers:
| Header | Description |
|-------------------------|------------------------------------------------------------|
| `X-RateLimit-Limit` | Number of max requests allowed in the current time period |
| `X-RateLimit-Remaining` | Number of remaining requests in the current time period |
| `X-RateLimit-Reset` | Timestamp of end of current time period as UNIX timestamp |
| `Retry-After` | Seconds to delay after the first `429` is received |
# CORS
This API features [Cross-Origin Resource Sharing (CORS)](https://fetch.spec.whatwg.org/),
allowing cross-domain communication from the browser for some routes:
| Endpoint |
|------------------------- ---|
| `/api/*` |
| `/download/*` |
| `/lazy-static/*` |
| `/.well-known/webfinger` |
In addition, all routes serving ActivityPub are CORS-enabled for all origins.externalDocs:
url: https://docs.joinpeertube.org/api-rest-reference.html
tags:
name: Register
As a visitor, you can use this API to open an account (if registrations are open on
that PeerTube instance). As an admin, you should use the dedicated User creation
API instead.name: Session
x-displayName: Login/Logout
Sessions deal with access tokens over time. Only one session token can currently be used at a time.name: Accounts
Accounts encompass remote accounts discovered across the federation,
and correspond to the main Actor, along with video channels a user can create, which
are also Actors.When a comment is posted, it is done with your Account's Actor.
name: Users
Using some features of PeerTube require authentication, for which User
provide different levels of permission as well as associated user
information. Each user has a corresponding local Account for federation.name: User Exports
To create an archive of user data.name: User Imports
To import an archive of user data.name: My User
Operations related to your own User, when logged-in.name: My Subscriptions
Operations related to your subscriptions to video channels, their
new videos, and how to keep up to date with their latest publications!name: My History
Operations related to your watch history.name: My Notifications
Notifications following new videos, follows or reports. They allow you
to keep track of the interactions and overall important information that
concerns you. You MAY set per-notification type delivery preference, to
receive the info either by mail, by in-browser notification or both.name: Config
Each server exposes public information regarding supported videos and
options.name: Job
Jobs are long-running tasks enqueued and processed by the instance
itself. No additional worker registration is currently available.name: Instance Follows
Managing servers which the instance interacts with is crucial to the
concept of federation in PeerTube and external video indexation. The PeerTube
server then deals with inter-server ActivityPub operations and propagates
information across its social graph by posting activities to actors' inbox
endpoints.
externalDocs:
url: https://docs.joinpeertube.org/admin/following-instances#instances-followsname: Instance Redundancy
Redundancy is part of the inter-server solidarity that PeerTube fosters.
Manage the list of instances you wish to help by seeding their videos according
to the policy of video selection of your choice. Note that you have a similar functionality
to mirror individual videos, see video mirroring.
externalDocs:
url: https://docs.joinpeertube.org/admin/following-instances#instances-redundancyname: Plugins
Managing plugins installed from a local path or from NPM, or search for new ones.
externalDocs:
url: https://docs.joinpeertube.org/api/pluginsname: Abuses
Abuses deal with reports of local or remote videos/comments/accounts alike.name: Video
Operations dealing with listing, uploading, fetching or modifying videos.name: Video Upload
Operations dealing with adding video or audio. PeerTube supports two upload modes, and three import modes.Upload
- legacy, where the video file is sent in a single request
- resumable, where the video file is sent in chunks
You can upload videos more reliably by using the resumable variant. Its protocol lets
you resume an upload operation after a network interruption or other transmission failure,
saving time and bandwidth in the event of network failures.Favor using resumable uploads in any of the following cases:
- You are transferring large files
- The likelihood of a network interruption is high
- Uploads are originating from a device with a low-bandwidth or unstable Internet connection, such as a mobile device
Import
- URL-based: where the URL points to any service supported by youtube-dl
- magnet-based: where the URI resolves to a BitTorrent resource containing a single supported video file
- torrent-based: where the metainfo file resolves to a BitTorrent resource containing a single supported video file
The import function is practical when the desired video/audio is available online. It makes PeerTube
download it for you, saving you as much bandwidth and avoiding any instability or limitation your network might have.name: Video Imports
name: Channels Sync
name: Video Captions
name: Video Chapters
name: Video Channels
name: Player Settings
name: Video Comments
Operations dealing with comments to a video. Comments are organized in threads: adding a
comment in response to the video starts a thread, adding a reply to a comment adds it to
its root comment thread.name: Video Blocks
name: Automatic Tags
name: Watched Words
name: Video Rates
name: Video Playlists
name: Video Files
name: Video Transcoding
name: Video Stats
name: Video Feeds
name: Video Download
name: Logs
name: Search
The search helps to find videos or channels from within the instance and beyond.
Videos from other instances federated by the instance (that is, instances
followed by the instance) can be found via keywords and other criteria of
the advanced search.Administrators can also enable the use of a remote search system, indexing
videos and channels that may not be federated by the instance.name: Homepage
name: Video Mirroring
PeerTube instances can mirror videos from one another, and help distribute some videos.For importing videos as your own, refer to video imports.
name: Stats
Statisticsname: Contact
name: Debug
name: Runner Registration Token
Manage runner registration tokens.name: Runner Jobs
name: Runners
name: Video Passwords
name: Client Config
x-tagGroups:name: Static endpoints
tags:- Static Video Files
name: Download
tags:- Video Download
name: Feeds
tags:- Video Feeds
name: Auth
tags:- Register
- Session
name: Accounts
tags:- Accounts
- Users
- User Exports
- User Imports
- My User
- My Subscriptions
- My Notifications
- My History
name: Videos
tags:- Video
- Video Upload
- Video Imports
- Video Captions
- Video Chapters
- Video Channels
- Video Comments
- Video Rates
- Video Playlists
- Video Stats
- Ownership Change
- Video Mirroring
- Video Files
- Video Transcoding
- Live Videos
- Channels Sync
- Video Passwords
- Video Embed Privacy
name: Search
tags:- Search
name: Moderation
tags:- Abuses
- Video Blocks
- Account Blocklist
- Server Blocklist
- Automatic Tags
- Watched Words
name: Instance
tags:- Config
- Client Config
- Homepage
- Instance Follows
- Instance Redundancy
- Plugins
- Stats
- Logs
- Job
name: Remote Jobs
tags:- Runner Registration Token
- Runner Jobs
- Runners
paths:
'/static/web-videos/{filename}':
get:
tags:
- Static Video Files
summary: Get public Web Video file
parameters:
- $ref: '#/components/parameters/staticFilename'
responses:
'200':
'404':
'/static/web-videos/private/{filename}':
get:
tags:
- Static Video Files
summary: Get private Web Video file
parameters:
- $ref: '#/components/parameters/staticFilename'
- $ref: '#/components/parameters/videoFileToken'
security:
- OAuth2: []
responses:
'200':
'403':
'404':
'/static/streaming-playlists/hls/{filename}':
get:
tags:
- Static Video Files
summary: Get public HLS video file
parameters:
- $ref: '#/components/parameters/staticFilename'
security:
- OAuth2: []
responses:
'200':
'403':
'404':
'/static/streaming-playlists/hls/private/{filename}':
get:
tags:
- Static Video Files
summary: Get private HLS video file
parameters:
- $ref: '#/components/parameters/staticFilename'
- $ref: '#/components/parameters/videoFileToken'
- $ref: '#/components/parameters/reinjectVideoFileToken'
security:
- OAuth2: []
responses:
'200':
'403':
'404':
'/download/videos/generate/{videoIdOrUUID}':
get:
tags:
- Video Download
summary: Download video file
Mainly used to merge the HLS audio only video file and the HLS video only resolution file.
parameters:
- $ref: '#/components/parameters/videoIdOrUUID'
- name: videoFileIds
in: query
required: true
schema:
type: array
items:
type: integer
- $ref: '#/components/parameters/videoFileToken'
responses:
'200':
'/feeds/video-comments.{format}':
get:
tags:
- Video Feeds
summary: Comments on videos feeds
operationId: getSyndicatedComments
parameters:
- name: format
in: path
required: true
schema:
type: string
enum:
- xml
- rss
- rss2
- atom
- atom1
- json
- json1
- name: videoId
in: query
schema:
type: string
- name: accountId
in: query
schema:
type: string
- name: accountName
in: query
schema:
type: string
- name: videoChannelId
in: query
schema:
type: string
- name: videoChannelName
in: query
schema:
type: string
- name: isLocal
in: query
required: false
schema:
type: boolean
- name: onLocalVideo
in: query
required: false
schema:
type: boolean
responses:
'200':
headers:
Cache-Control:
schema:
type: string
default: 'max-age=900' # 15 min cache
content:
application/xml:
schema:
$ref: '#/components/schemas/VideoCommentsForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/video-comments.xml?scope=local
application/rss+xml:
schema:
$ref: '#/components/schemas/VideoCommentsForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/video-comments.rss?scope=local
text/xml:
schema:
$ref: '#/components/schemas/VideoCommentsForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/video-comments.xml?scope=local
application/atom+xml:
schema:
$ref: '#/components/schemas/VideoCommentsForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/video-comments.atom?scope=local
application/json:
schema:
type: object
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/video-comments.json?scope=local
'400':
x-summary: field inconsistencies
Arises when:
- videoId filter is mixed with a channel filter
'404':
'406': '/feeds/videos.{format}':
get:
tags:
- Video Feeds
summary: Common videos feeds
operationId: getSyndicatedVideos
parameters:
- name: format
in: path
required: true
schema:
type: string
enum:
- xml
- rss
- rss2
- atom
- atom1
- json
- json1
- name: accountId
in: query
schema:
type: string
- name: accountName
in: query
schema:
type: string
- name: videoChannelId
in: query
schema:
type: string
- name: videoChannelName
in: query
schema:
type: string
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
responses:
'200':
headers:
Cache-Control:
schema:
type: string
default: 'max-age=900' # 15 min cache
content:
application/xml:
schema:
$ref: '#/components/schemas/VideosForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/videos.xml?scope=local
application/rss+xml:
schema:
$ref: '#/components/schemas/VideosForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/videos.rss?scope=local
text/xml:
schema:
$ref: '#/components/schemas/VideosForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/videos.xml?scope=local
application/atom+xml:
schema:
$ref: '#/components/schemas/VideosForXML'
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/videos.atom?scope=local
application/json:
schema:
type: object
examples:
nightly:
externalValue: https://peertube2.cpy.re/feeds/videos.json?scope=local
'404':
'406':
'/feeds/subscriptions.{format}':
get:
tags:
- Video Feeds
summary: Videos of subscriptions feeds
operationId: getSyndicatedSubscriptionVideos
parameters:
- name: format
in: path
required: true
schema:
type: string
enum:
- xml
- rss
- rss2
- atom
- atom1
- json
- json1
- name: accountId
in: query
schema:
type: string
required: true
- name: token
in: query
schema:
type: string
required: true
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
responses:
'200':
headers:
Cache-Control:
schema:
type: string
default: 'max-age=900' # 15 min cache
content:
application/xml:
schema:
$ref: '#/components/schemas/VideosForXML'
application/rss+xml:
schema:
$ref: '#/components/schemas/VideosForXML'
text/xml:
schema:
$ref: '#/components/schemas/VideosForXML'
application/atom+xml:
schema:
$ref: '#/components/schemas/VideosForXML'
application/json:
schema:
type: object
'406':
'/feeds/podcast/videos.xml':
get:
tags:
- Video Feeds
summary: Videos podcast feed
operationId: getVideosPodcastFeed
parameters:
- name: videoChannelId
in: query
required: false
schema:
type: string
- name: playlistId
in: query
required: false
schema:
type: string
- name: enclosurePreference
in: query
required: false
schema:
type: string
enum:
- video-only
- audio-only
responses:
'200':
headers:
Cache-Control:
schema:
type: string
default: 'max-age=900' # 15 min cache
'404':
'/api/v1/accounts/{name}':
get:
tags:
- Accounts
summary: Get an account
operationId: getAccount
parameters:
- $ref: '#/components/parameters/name'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'404':
'/api/v1/accounts/{name}/videos':
get:
tags:
- Accounts
- Video
summary: 'List videos of an account'
operationId: getAccountVideos
parameters:
- $ref: '#/components/parameters/name'
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
x-codeSamples:
- lang: JavaScript
source: |
fetch('https://peertube2.cpy.re/api/v1/accounts/{name}/videos')
.then(function(response) {
return response.json()
}).then(function(data) {
console.log(data)
})
- lang: Shell
source: |
## DEPENDENCIES: jq
curl -s https://peertube2.cpy.re/api/v1/accounts/{name}/videos | jq
- lang: Ruby
source: |
require 'net/http'
require 'json'
uri = URI.parse("https://peertube2.cpy.re/api/v1/accounts/{name}/videos")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.get(uri.request_uri)
puts JSON.parse(response.read_body)
- lang: Python
source: |
import requests
r = requests.get("https://peertube2.cpy.re/api/v1//accounts/{name}/videos")
json = r.json()
print(json) '/api/v1/accounts/{name}/followers':
get:
tags:
- Accounts
summary: 'List followers of an account'
security:
- OAuth2: []
operationId: getAccountFollowers
parameters:
- $ref: '#/components/parameters/name'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/followersSort'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Follow'
/api/v1/accounts:
get:
tags:
- Accounts
summary: List accounts
operationId: getAccounts
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
'application/json':
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Account'
/api/v1/config:
get:
tags:
- Config
summary: Get instance public configuration
operationId: getConfig
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerConfig'
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/config
/api/v1/config/about:
get:
summary: Get instance "About" information
Translatable information is returned in the language of the request, using the x-peertube-language header
or the Accept-Language header. If the instance has no translation for this language, the default information is returned.
operationId: getAbout
tags:
- Config
parameters:
- name: x-peertube-language
in: header
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerConfigAbout'
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/config/about
/api/v1/config/custom:
get:
summary: Get instance runtime configuration
operationId: getCustomConfig
tags:
- Config
security:
- OAuth2:
- admin
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerConfigCustom'
put:
summary: Set instance runtime configuration
operationId: putCustomConfig
tags:
- Config
security:
- OAuth2:
- admin
responses:
'200':
'400':
x-summary: field inconsistencies
Arises when:
- the emailer is disabled and the instance is open to registrations
- web videos and hls are disabled with transcoding enabled - you need at least one enabled
delete:
summary: Delete instance runtime configuration
operationId: delCustomConfig
tags:
- Config
security:
- OAuth2:
- admin
responses:
'200':
/api/v1/config/instance-banner/pick:
post:
summary: Update instance banner
security:
- OAuth2:
- admin
tags:
- Config
responses:
'204':
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
bannerfile:
type: string
format: binary
encoding:
bannerfile:
contentType: image/png, image/jpeg
'/api/v1/config/instance-banner':
delete:
summary: Delete instance banner
security:
- OAuth2:
- admin
tags:
- Config
responses:
'204':
/api/v1/config/instance-avatar/pick:
post:
summary: Update instance avatar
security:
- OAuth2:
- admin
tags:
- Config
responses:
'204':
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
avatarfile:
type: string
format: binary
encoding:
avatarfile:
contentType: image/png, image/jpeg
'/api/v1/config/instance-avatar':
delete:
summary: Delete instance avatar
security:
- OAuth2:
- admin
tags:
- Config
responses:
'204':
'/api/v1/config/instance-logo/{logoType}/pick':
post:
summary: Update instance logo
security:
- OAuth2:
- admin
tags:
- Config
parameters:
- $ref: '#/components/parameters/logoTypeParam'
responses:
'204':
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
logofile:
type: string
format: binary
encoding:
logofile:
contentType: image/png, image/jpeg
'/api/v1/config/instance-logo/{logoType}':
delete:
summary: Delete instance logo
security:
- OAuth2:
- admin
tags:
- Config
parameters:
- $ref: '#/components/parameters/logoTypeParam'
responses:
'204':
/api/v1/custom-pages/homepage/instance:
get:
summary: Get instance custom homepage
tags:
- Homepage
responses:
'404':
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomHomepage'
put:
summary: Set instance custom homepage
tags:
- Homepage
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
content:
type: string
responses:
'204':
/api/v1/jobs/pause:
post:
summary: Pause job queue
security:
- OAuth2:
- admin
tags:
- Job
requestBody:
content:
application/json:
schema:
type: object
properties:
processRoles:
type: array
minItems: 1
items:
type: string
enum:
- primary
- secondary
Roles of the PeerTube processes that must pause their job queue.
Defaults to all the roles.
Other processes are notified asynchronously.
responses:
'204':
/api/v1/jobs/resume:
post:
summary: Resume job queue
security:
- OAuth2:
- admin
tags:
- Job
requestBody:
content:
application/json:
schema:
type: object
properties:
processRoles:
type: array
minItems: 1
items:
type: string
enum:
- primary
- secondary
Roles of the PeerTube processes that must resume their job queue.
Defaults to all the roles.
Other processes are notified asynchronously.
responses:
'204':
/api/v1/jobs/{state}:
get:
summary: List instance jobs
operationId: getJobs
security:
- OAuth2:
- admin
tags:
- Job
parameters:
- name: state
in: path
required: true
schema:
type: string
enum:
- ''
- active
- completed
- failed
- waiting
- delayed
- $ref: '#/components/parameters/jobType'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
maxItems: 100
items:
$ref: '#/components/schemas/Job'
/api/v1/jobs/{jobType}/{jobId}/cancel:
post:
summary: Cancel a job
operationId: cancelJob
security:
- OAuth2:
- admin
tags:
- Job
parameters:
- name: jobType
in: path
required: true
schema:
$ref: '#/components/schemas/JobType'
- name: jobId
in: path
required: true
schema:
type: string
responses:
'204':
'404':
'409':
/api/v1/server/followers:
get:
tags:
- Instance Follows
summary: List instances following the server
parameters:
- $ref: '#/components/parameters/followState'
- $ref: '#/components/parameters/actorType'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Follow'
'/api/v1/server/followers/{handle}':
delete:
summary: Remove or reject a follower to your server
security:
- OAuth2:
- admin
tags:
- Instance Follows
parameters:
- name: handle
in: path
required: true
schema:
type: string
format: email
responses:
'204':
'404':
'/api/v1/server/followers/{handle}/reject':
post:
summary: Reject a pending follower to your server
security:
- OAuth2:
- admin
tags:
- Instance Follows
parameters:
- name: handle
in: path
required: true
schema:
type: string
format: email
responses:
'204':
'404':
'/api/v1/server/followers/{handle}/accept':
post:
summary: Accept a pending follower to your server
security:
- OAuth2:
- admin
tags:
- Instance Follows
parameters:
- name: handle
in: path
required: true
schema:
type: string
format: email
responses:
'204':
'404':
/api/v1/server/following:
get:
tags:
- Instance Follows
summary: List instances followed by the server
parameters:
- $ref: '#/components/parameters/followState'
- $ref: '#/components/parameters/actorType'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Follow'
post:
security:
- OAuth2:
- admin
tags:
- Instance Follows
summary: Follow a list of actors (PeerTube instance, channel or account)
responses:
'204':
'500':
requestBody:
content:
application/json:
schema:
type: object
properties:
hosts:
type: array
items:
type: string
format: hostname
uniqueItems: true
handles:
type: array
items:
type: string
uniqueItems: true
'/api/v1/server/following/{hostOrHandle}':
delete:
summary: Unfollow an actor (PeerTube instance, channel or account)
security:
- OAuth2:
- admin
tags:
- Instance Follows
parameters:
- name: hostOrHandle
in: path
required: true
schema:
type: string
responses:
'204':
'404':
/api/v1/users:
post:
summary: Create a user
operationId: addUser
security:
- OAuth2:
- admin
tags:
- Users
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AddUserResponse'
links:
# GET /users/{id}
GetUser:
operationId: getUser
parameters:
id: '$response.body#/user/id'
# PUT /users/{id}
PutUser:
operationId: putUser
parameters:
id: '$response.body#/user/id'
# DELETE /users/{id}
DelUser:
operationId: delUser
parameters:
id: '$response.body#/user/id'
'403':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AddUser'
If the smtp server is configured, you can leave the password empty and an email will be sent
asking the user to set it first.
required: true
get:
summary: List users
operationId: getUsers
security:
- OAuth2:
- admin
tags:
- Users
parameters:
- $ref: '#/components/parameters/usersSearch'
- $ref: '#/components/parameters/usersBlocked'
- $ref: '#/components/parameters/usersRole'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/usersSort'
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'/api/v1/users/{id}':
parameters:
- $ref: '#/components/parameters/id'
delete:
summary: Delete a user
security:
- OAuth2:
- admin
tags:
- Users
operationId: delUser
responses:
'204':
get:
summary: Get a user
security:
- OAuth2: []
tags:
- Users
operationId: getUser
parameters:
- name: withStats
in: query
schema:
type: boolean
responses:
'200':
x-summary: successful operation
As an admin/moderator, you can request a response augmented with statistics about the user's
moderation relations and videos usage, by using the withStats parameter.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/User'
- $ref: '#/components/schemas/UserWithStats'
put:
summary: Update a user
security:
- OAuth2: []
tags:
- Users
operationId: putUser
responses:
'204':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUser'
required: true
/api/v1/users/{id}/block:
post:
summary: Block a user
security:
- OAuth2:
- admin
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
reason:
type: string
minLength: 0
maxLength: 500
responses:
'204':
'400':
'403':
'404':
/api/v1/users/{id}/unblock:
post:
summary: Unblock a user
security:
- OAuth2:
- admin
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
responses:
'204':
'400':
'403':
'404':
/api/v1/oauth-clients/local:
get:
summary: Login prerequisite
operationId: getOAuthClient
tags:
- Session
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthClient'
links:
UseOAuthClientToLogin:
operationId: getOAuthToken
parameters:
client_id: '$response.body#/client_id'
client_secret: '$response.body#/client_secret'
x-codeSamples:
- lang: Shell
source: |
API="https://peertube2.cpy.re/api/v1"
## AUTH
curl -s "$API/oauth-clients/local" /api/v1/users/token:
post:
summary: Login
operationId: getOAuthToken
tags:
- Session
parameters:
- name: x-peertube-otp
in: header
schema:
type: string
required: false
requestBody:
content:
application/x-www-form-urlencoded:
schema:
oneOf:
- $ref: '#/components/schemas/OAuthToken-password'
- $ref: '#/components/schemas/OAuthToken-refresh_token'
discriminator:
propertyName: grant_type
mapping:
password: '#/components/schemas/OAuthToken-password'
refresh_token: '#/components/schemas/OAuthToken-refresh_token'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
token_type:
type: string
example: Bearer
access_token:
type: string
example: 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0
refresh_token:
type: string
example: 2e0d675df9fc96d2e4ec8a3ebbbf45eca9137bb7
expires_in:
type: integer
minimum: 0
example: 14399
refresh_token_expires_in:
type: integer
minimum: 0
example: 1209600
'400':
x-summary: client or credentials are invalid
Disambiguate via code:
- invalid_client for an unmatched client_id
- invalid_grant for unmatched credentials
'401':
x-summary: token expired or two factor header is missing
Disambiguate via code:
- default value for a regular authentication failure
- invalid_token for an expired token
- missing_two_factor if two factor header is missing
x-codeSamples:
- lang: Shell
source: |
## DEPENDENCIES: jq
API="https://peertube2.cpy.re/api/v1"
USERNAME="
PASSWORD="
## AUTH
client_id=$(curl -s "$API/oauth-clients/local" | jq -r ".client_id")
client_secret=$(curl -s "$API/oauth-clients/local" | jq -r ".client_secret")
curl -s "$API/users/token" \
--data client_id="$client_id" \
--data client_secret="$client_secret" \
--data grant_type=password \
--data username="$USERNAME" \
--data-urlencode password="$PASSWORD" \
| jq -r ".access_token" /api/v1/users/revoke-token:
post:
summary: Logout
operationId: revokeOAuthToken
tags:
- Session
security:
- OAuth2: []
responses:
'200':
/api/v1/users/{id}/token-sessions:
get:
summary: List token sessions
parameters:
- $ref: '#/components/parameters/id'
tags:
- Session
security:
- OAuth2: []
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/TokenSession'
/api/v1/users/{id}/token-sessions/{tokenSessionId}/revoke:
get:
summary: List token sessions
parameters:
- $ref: '#/components/parameters/id'
- $ref: '#/components/parameters/tokenSessionId'
tags:
- Session
security:
- OAuth2: []
responses:
'200':
/api/v1/users/ask-send-verify-email:
post:
summary: Resend user verification link
operationId: resendEmailToVerifyUser
tags:
- Users
- Register
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
required:
- email
responses:
'204':
/api/v1/users/registrations/ask-send-verify-email:
post:
summary: Resend verification link to registration request email
operationId: resendEmailToVerifyRegistration
tags:
- Register
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
required:
- email
responses:
'204':
/api/v1/users/{id}/verify-email:
post:
summary: Verify a user
operationId: verifyUser
Following a user registration, the new user will receive an email asking to click a link
containing a secret.
This endpoint can also be used to verify a new email set in the user account.
tags:
- Users
- Register
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
verificationString:
type: string
format: url
isPendingEmail:
type: boolean
required:
- verificationString
responses:
'204':
'403':
'404':
/api/v1/users/registrations/{registrationId}/verify-email:
post:
summary: Verify a registration email
operationId: verifyRegistrationEmail
Following a user registration request, the user will receive an email asking to click a link
containing a secret.
tags:
- Register
parameters:
- $ref: '#/components/parameters/registrationId'
requestBody:
content:
application/json:
schema:
type: object
properties:
verificationString:
type: string
format: url
required:
- verificationString
responses:
'204':
'403':
'404':
/api/v1/users/ask-reset-password:
post:
summary: Ask to reset password
tags:
- Users
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
required:
- email
responses:
'204':
/api/v1/users/{id}/reset-password:
post:
summary: Reset password
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
verificationString:
type: string
format: url
password:
type: string
required:
- verificationString
- password
responses:
'204':
'403':
'404':
/api/v1/users/{id}/two-factor/request:
post:
summary: Request two factor auth
operationId: requestTwoFactor
security:
- OAuth2: []
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
currentPassword:
type: string
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/RequestTwoFactorResponse'
'403':
'404':
'429':
/api/v1/users/{id}/two-factor/confirm-request:
post:
summary: Confirm two factor auth
operationId: confirmTwoFactorRequest
security:
- OAuth2: []
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
requestToken:
type: string
otpToken:
type: string
required:
- requestToken
- otpToken
responses:
'204':
'403':
'404':
/api/v1/users/{id}/two-factor/disable:
post:
summary: Disable two factor auth
operationId: disableTwoFactor
security:
- OAuth2: []
tags:
- Users
parameters:
- $ref: '#/components/parameters/id'
requestBody:
content:
application/json:
schema:
type: object
properties:
currentPassword:
type: string
responses:
'204':
'403':
'404':
'429':
/api/v1/users/{userId}/imports/import-resumable:
post:
summary: Initialize the resumable user import
operationId: userImportResumableInit
security:
- OAuth2: []
tags:
- User Imports
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/resumableUploadInitContentLengthHeader'
- $ref: '#/components/parameters/resumableUploadInitContentTypeHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserImportResumable'
responses:
'201':
headers:
Location:
schema:
type: string
format: url
Content-Length:
schema:
type: number
example: 0
put:
summary: Send chunk for the resumable user import
operationId: userImportResumable
security:
- OAuth2: []
tags:
- User Imports
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/resumableUploadId'
- $ref: '#/components/parameters/resumableUploadChunkContentRangeHeader'
- $ref: '#/components/parameters/resumableUploadChunkContentLengthHeader'
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'204':
'308':
headers:
Range:
schema:
type: string
example: bytes=0-262143
Content-Length:
schema:
type: number
example: 0
'400':
'503':
headers:
'Retry-After':
schema:
type: number
example: 300
delete:
summary: Cancel the resumable user import
operationId: userImportResumableCancel
security:
- OAuth2: []
tags:
- User Imports
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/resumableUploadId'
- name: Content-Length
in: header
required: true
schema:
type: number
example: 0
responses:
'204':
headers:
Content-Length:
schema:
type: number
example: 0
/api/v1/users/{userId}/imports/latest:
get:
summary: Get latest user import
operationId: getLatestUserImport
security:
- OAuth2: []
tags:
- User Imports
parameters:
- $ref: '#/components/parameters/userId'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
id:
type: integer
state:
type: object
properties:
id:
$ref: '#/components/schemas/UserImportState'
label:
type: string
createdAt:
type: string
format: date-time
/api/v1/users/{userId}/exports/request:
post:
summary: Request user export
operationId: requestUserExport
security:
- OAuth2: []
tags:
- User Exports
parameters:
- $ref: '#/components/parameters/userId'
requestBody:
content:
application/json:
schema:
type: object
properties:
withVideoFiles:
type: boolean
responses:
'200':
content:
application/json:
schema:
type: object
properties:
export:
type: object
properties:
id:
type: integer
/api/v1/users/{userId}/exports:
get:
summary: List user exports
operationId: listUserExports
security:
- OAuth2: []
tags:
- User Exports
parameters:
- $ref: '#/components/parameters/userId'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
id:
type: integer
state:
type: object
properties:
id:
$ref: '#/components/schemas/UserExportState'
label:
type: string
size:
type: integer
privateDownloadUrl:
type: string
createdAt:
type: string
format: date-time
expiresOn:
type: string
format: date-time
/api/v1/users/{userId}/exports/{id}:
delete:
summary: Delete a user export
operationId: deleteUserExport
security:
- OAuth2: []
tags:
- User Exports
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/id'
responses:
'204':
/api/v1/users/me:
get:
summary: Get my user information
operationId: getUserInfo
security:
- OAuth2:
- user
tags:
- My User
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
put:
summary: Update my user information
operationId: putUserInfo
security:
- OAuth2:
- user
tags:
- My User
responses:
'204':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateMe'
required: true
delete:
summary: Delete my account
operationId: deleteMe
security:
- OAuth2:
- user
tags:
- My User
responses:
'204':
'400':
'401':
'/api/v1/users/me/videos/comments':
get:
summary: List comments on user's videos
security:
- OAuth2: []
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/search'
- $ref: '#/components/parameters/searchAccountForComments'
- $ref: '#/components/parameters/searchVideoForComments'
- $ref: '#/components/parameters/videoId'
- $ref: '#/components/parameters/videoChannelId'
- $ref: '#/components/parameters/autoTagOneOfComment'
- $ref: '#/components/parameters/isHeldForReview'
- $ref: '#/components/parameters/includeCollaborations'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoCommentForOwnerOrAdmin'
/api/v1/users/me/videos/imports:
get:
summary: Get video imports of my user
security:
- OAuth2:
- user
tags:
- Videos
- My User
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/includeCollaborations'
-
name: videoId
in: query
required: false
schema:
type: integer
-
name: targetUrl
in: query
required: false
schema:
type: string
-
name: videoChannelSyncId
in: query
required: false
schema:
type: number
-
name: search
in: query
required: false
schema:
type: string
-
name: stateOneOf
in: query
required: false
schema:
type: array
items:
$ref: '#/components/schemas/VideoImportStateConstant/properties/id'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoImportsList'
/api/v1/users/me/video-quota-used:
get:
summary: Get my user used quota
security:
- OAuth2:
- user
tags:
- My User
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoQuotaUsed:
type: number
example: 16810141515
videoQuotaUsedDaily:
type: number
example: 1681014151
'/api/v1/users/me/videos/{videoIdOrUUID}/rating':
get:
summary: Get rate of my user for a video
security:
- OAuth2: []
tags:
- My User
- Video Rates
parameters:
- $ref: '#/components/parameters/videoIdOrUUID'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/GetMeVideoRating'
/api/v1/users/me/videos:
get:
summary: List videos of my user
security:
- OAuth2:
- user
tags:
- My User
- Videos
parameters:
- $ref: '#/components/parameters/channelNameOneOf'
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- $ref: '#/components/parameters/search'
- $ref: '#/components/parameters/includeCollaborations'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
/api/v1/users/me/subscriptions:
get:
summary: List my user subscriptions
security:
- OAuth2:
- user
tags:
- My Subscriptions
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/mySubscriptionSort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelList'
post:
tags:
- My Subscriptions
summary: Add subscription to my user
security:
- OAuth2:
- user
requestBody:
content:
application/json:
schema:
type: object
properties:
uri:
type: string
format: uri
required:
- uri
examples:
default:
value:
uri: [email protected]
responses:
'204':
/api/v1/users/me/subscriptions/exist:
get:
summary: Get if subscriptions exist for my user
security:
- OAuth2:
- user
tags:
- My Subscriptions
parameters:
- $ref: '#/components/parameters/subscriptionsUris'
responses:
'200':
content:
application/json:
schema:
type: object
/api/v1/users/me/subscriptions/videos:
get:
summary: List videos of subscriptions of my user
security:
- OAuth2:
- user
tags:
- My Subscriptions
- Videos
parameters:
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
'/api/v1/users/me/subscriptions/{subscriptionHandle}':
get:
summary: Get subscription of my user
security:
- OAuth2:
- user
tags:
- My Subscriptions
parameters:
- $ref: '#/components/parameters/subscriptionHandle'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannel'
delete:
summary: Delete subscription of my user
security:
- OAuth2:
- user
tags:
- My Subscriptions
parameters:
- $ref: '#/components/parameters/subscriptionHandle'
responses:
'204':
/api/v1/users/me/notifications:
get:
summary: List my notifications
security:
- OAuth2: []
tags:
- My Notifications
parameters:
- name: typeOneOf
in: query
schema:
type: array
items:
$ref: '#/components/schemas/NotificationType'
- name: unread
in: query
schema:
type: boolean
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/NotificationListResponse'
/api/v1/users/me/notifications/read:
post:
summary: Mark notifications as read by their id
security:
- OAuth2: []
tags:
- My Notifications
requestBody:
content:
application/json:
schema:
type: object
properties:
ids:
type: array
items:
type: integer
required:
- ids
responses:
'204':
/api/v1/users/me/notifications/read-all:
post:
summary: Mark all my notification as read
security:
- OAuth2: []
tags:
- My Notifications
responses:
'204':
/api/v1/users/me/notification-settings:
put:
summary: Update my notification settings
security:
- OAuth2: []
tags:
- My Notifications
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserNotificationSettings'
responses:
'204': /api/v1/users/me/new-feature-info/read:
post:
tags:
- My User
summary: Mark feature info as read
security:
- OAuth2:
- user
requestBody:
content:
application/json:
schema:
type: object
properties:
feature:
$ref: '#/components/schemas/NewFeatureInfoType'
required:
- feature
responses:
'204':
/api/v1/users/me/history/videos:
get:
summary: List watched videos history
security:
- OAuth2: []
tags:
- My History
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
/api/v1/users/me/history/videos/{videoIdOrUUID}:
delete:
summary: Delete history element
security:
- OAuth2: []
tags:
- My History
parameters:
- $ref: '#/components/parameters/videoIdOrUUID'
responses:
'204':
/api/v1/users/me/history/videos/remove:
post:
summary: Clear video history
security:
- OAuth2: []
tags:
- My History
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
beforeDate:
type: string
format: date-time
responses:
'204':
/api/v1/users/me/avatar/pick:
post:
summary: Update my user avatar
security:
- OAuth2: []
tags:
- My User
responses:
'200':
content:
application/json:
schema:
type: object
properties:
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
avatarfile:
type: string
format: binary
encoding:
avatarfile:
contentType: image/png, image/jpeg
/api/v1/users/me/avatar:
delete:
summary: Delete my avatar
security:
- OAuth2: []
tags:
- My User
responses:
'204':
/api/v1/users/register:
post:
summary: Register a user
operationId: registerUser
tags:
- Register
responses:
'200':
content:
application/json:
schema:
type: object
properties:
state:
type: object
properties:
id:
$ref: '#/components/schemas/UserRegistrationState'
label:
type: string
'400':
'403':
'409':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterUser'
required: true
/api/v1/users/registrations/request:
post:
summary: Request registration
operationId: requestRegistration
tags:
- Register
responses:
'200':
content:
application/json:
schema:
type: object
properties:
state:
type: object
properties:
id:
$ref: '#/components/schemas/UserRegistrationState'
label:
type: string
'400':
'403':
'409':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRegistrationRequest'
/api/v1/users/registrations/{registrationId}/accept:
post:
security:
- OAuth2:
- admin
- moderator
summary: Accept registration
operationId: acceptRegistration
tags:
- Register
parameters:
- $ref: '#/components/parameters/registrationId'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRegistrationAcceptOrReject'
responses:
'204':
/api/v1/users/registrations/{registrationId}/reject:
post:
security:
- OAuth2:
- admin
- moderator
summary: Reject registration
operationId: rejectRegistration
tags:
- Register
parameters:
- $ref: '#/components/parameters/registrationId'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRegistrationAcceptOrReject'
responses:
'204':
/api/v1/users/registrations/{registrationId}:
delete:
security:
- OAuth2:
- admin
- moderator
summary: Delete registration
operationId: deleteRegistration
tags:
- Register
parameters:
- $ref: '#/components/parameters/registrationId'
responses:
'204':
/api/v1/users/registrations:
get:
security:
- OAuth2:
- admin
- moderator
summary: List registrations
operationId: listRegistrations
tags:
- Register
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: search
in: query
required: false
schema:
type: string
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
- state
- -state
- name: stateOneOf
in: query
required: false
schema:
type: array
items:
$ref: '#/components/schemas/UserRegistrationState'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/UserRegistration'
/api/v1/videos/ownership:
get:
summary: List video ownership changes
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
responses:
'200':
content:
'application/json':
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ChangeOwnership'
'401':
'/api/v1/videos/ownership/{id}/accept':
post:
summary: Accept ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
channelId:
type: integer
required:
- channelId
responses:
'204':
'400':
'403':
'413':
'404':
'/api/v1/videos/ownership/{id}/refuse':
post:
summary: Refuse ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'400':
'403':
'404':
'/api/v1/videos/ownership/{id}':
delete:
summary: Delete ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'400':
'403':
'404':
'/api/v1/videos/{videoIdOrUUID}/ownership':
get:
summary: List ownership change requests for a video
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/videoIdOrUUID'
- name: state
in: query
required: false
schema:
$ref: '#/components/schemas/ChangeOwnershipState'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
responses:
'200':
content:
'application/json':
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ChangeOwnership'
'403':
'404':
'/api/v1/videos/{videoIdOrUUID}/give-ownership':
post:
summary: Request ownership change
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/videoIdOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
required:
- username
responses:
'204':
'400':
'403':
'404':
/api/v1/video-channels/ownership:
get:
summary: List channel ownership changes
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ChangeOwnership'
'401':
'/api/v1/video-channels/ownership/{id}/accept':
post:
summary: Accept channel ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'400':
'403':
'404':
'409':
'413':
'/api/v1/video-channels/ownership/{id}/refuse':
post:
summary: Refuse channel ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'400':
'403':
'404':
'/api/v1/video-channels/ownership/{id}':
delete:
summary: Delete channel ownership change request
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'400':
'403':
'404':
'/api/v1/video-channels/{channelHandle}/ownership':
get:
summary: List ownership change requests for a channel
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
- name: state
in: query
required: false
schema:
$ref: '#/components/schemas/ChangeOwnershipState'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ChangeOwnership'
'400':
'403':
'404':
'/api/v1/video-channels/{channelHandle}/give-ownership':
post:
summary: Request channel ownership change
tags:
- Ownership Change
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
required:
- username
responses:
'204':
'400':
'403':
'404':
'/api/v1/videos/{id}/token':
post:
summary: Request video token
operationId: requestVideoToken
tags:
- Video
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoTokenResponse'
'400':
'404':
/api/v1/videos/{id}/studio/edit:
post:
summary: Create a studio task
tags:
- Video Transcoding
- Video
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/VideoStudioCreateTask'
responses:
'204':
'400':
'404':
/api/v1/videos:
get:
summary: List videos
operationId: getVideos
tags:
- Video
parameters:
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
/api/v1/recommendations/videos:
get:
summary: List recommended videos
Return videos recommended next to a reference video (or general recommendations if no reference video is given).
PeerTube decides the recommendation algorithm: it currently lists videos sharing tags with the reference video
(excluding videos already watched by the authenticated user), then the latest videos.
All returned videos are restricted to the `scope`, which defaults to the `recommendationScope` of the reference video.
operationId: getRecommendationVideos
tags:
- Video
parameters:
- name: scope
in: query
required: false
Restrict recommended videos. Defaults to the `recommendationScope` of the reference video, or to `1` (all videos) if no reference video is given
schema:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
- name: videoId
in: query
required: false
schema:
oneOf:
- $ref: '#/components/schemas/id'
- $ref: '#/components/schemas/UUIDv4'
- $ref: '#/components/schemas/shortUUID'
- name: count
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 30
default: 10
- name: excludeVideoIds
in: query
required: false
style: form
explode: true
schema:
type: array
maxItems: 50
items:
$ref: '#/components/schemas/id'
- $ref: '#/components/parameters/videoPasswordHeader'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
'400':
'401':
'403':
'404': /api/v1/videos/categories:
get:
summary: List available video categories
operationId: getCategories
tags:
- Video
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/videos/categories
/api/v1/videos/licences:
get:
summary: List available video licences
operationId: getLicences
tags:
- Video
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/videos/licences
/api/v1/videos/languages:
get:
summary: List available video languages
operationId: getLanguages
tags:
- Video
parameters:
- name: scope
in: query
required: false
schema:
type: string
enum:
- subtitle
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/videos/languages
/api/v1/videos/privacies:
get:
summary: List available video privacy policies
operationId: getVideoPrivacyPolicies
tags:
- Video
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/videos/privacies
'/api/v1/videos/{id}':
put:
summary: Update a video
operationId: putVideo
security:
- OAuth2: []
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
channelId:
type: integer
New channel of the video. The channel must be owned by the same account as the previous one.
Use the "change ownership" endpoints to give a video to a channel owned by another account on the local PeerTube instance.
thumbnailfile:
type: string
format: binary
previewfile:
deprecated: true
type: string
format: binary
category:
$ref: '#/components/schemas/VideoCategorySet'
licence:
$ref: '#/components/schemas/VideoLicenceSet'
language:
$ref: '#/components/schemas/VideoLanguageSet'
privacy:
$ref: '#/components/schemas/VideoPrivacySet'
type: string
waitTranscoding:
type: string
support:
example: Please support our work on https://soutenir.framasoft.org/en/ <3
type: string
nsfw:
type: boolean
nsfwSummary:
nsfwFlags:
$ref: '#/components/schemas/NSFWFlag'
name:
type: string
minLength: 3
maxLength: 120
tags:
type: array
minItems: 1
maxItems: 5
items:
type: string
minLength: 2
maxLength: 30
commentsPolicy:
$ref: '#/components/schemas/VideoCommentsPolicySet'
recommendationScope:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
aiUsage:
$ref: '#/components/schemas/VideoAIUsageSet'
commercialContent:
$ref: '#/components/schemas/VideoCommercialContentSet'
downloadEnabled:
type: boolean
originallyPublishedAt:
type: string
format: date-time
nullable: true
scheduleUpdate:
$ref: '#/components/schemas/VideoScheduledUpdate'
videoPasswords:
$ref: '#/components/schemas/AddVideoPasswords'
encoding:
thumbnailfile:
contentType: image/jpeg
previewfile:
contentType: image/jpeg
tags:
style: form
explode: true
get:
summary: Get a video
operationId: getVideo
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoDetails'
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerError'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerError'
delete:
summary: Delete a video
operationId: delVideo
security:
- OAuth2: []
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'/api/v1/videos/{id}/views':
post:
summary: Notify user is watching a video
operationId: addView
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserViewingVideo'
required: true
responses:
'204':
'/api/v1/videos/{id}/stats/overall':
get:
summary: Get overall stats of a video
tags:
- Video Stats
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
- name: startDate
in: query
schema:
type: string
format: date-time
- name: endDate
in: query
schema:
type: string
format: date-time
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoStatsOverall'
'/api/v1/videos/{id}/stats/user-agent':
get:
summary: Get user agent stats of a video
tags:
- Video Stats
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
- name: startDate
in: query
schema:
type: string
format: date-time
- name: endDate
in: query
schema:
type: string
format: date-time
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoStatsUserAgent'
'/api/v1/videos/{id}/stats/retention':
get:
summary: Get retention stats of a video
tags:
- Video Stats
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoStatsRetention'
'/api/v1/videos/{id}/stats/timeseries/{metric}':
get:
summary: Get timeserie stats of a video
tags:
- Video Stats
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/idOrUUID'
-
name: metric
in: path
required: true
schema:
type: string
enum:
- 'viewers'
- 'aggregateWatchTime'
- name: startDate
in: query
schema:
type: string
format: date-time
- name: endDate
in: query
schema:
type: string
format: date-time
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoStatsTimeserie'
/api/v1/videos/upload:
post:
summary: Upload a video
operationId: uploadLegacy
security:
- OAuth2: []
tags:
- Video
- Video Upload
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
'403':
'408':
'413':
x-summary: video file too large, due to quota or max body size limit set by the reverse-proxy
If the response has no body, it means the reverse-proxy didn't let it through. Otherwise disambiguate via code:
- quota_reached for quota limits whether daily or global
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
'415':
'422':
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/VideoUploadRequestLegacy'
encoding:
videofile:
contentType: video/mp4, video/webm, video/ogg, video/avi, video/quicktime, video/x-msvideo, video/x-flv, video/x-matroska, application/octet-stream
thumbnailfile:
contentType: image/jpeg
previewfile:
contentType: image/jpeg
x-codeSamples:
- lang: Shell
source: |
## DEPENDENCIES: jq
USERNAME="
PASSWORD="
FILE_PATH="
CHANNEL_ID="
NAME="
API="https://peertube2.cpy.re/api/v1"
## AUTH
client_id=$(curl -s "$API/oauth-clients/local" | jq -r ".client_id")
client_secret=$(curl -s "$API/oauth-clients/local" | jq -r ".client_secret")
token=$(curl -s "$API/users/token" \
--data client_id="$client_id" \
--data client_secret="$client_secret" \
--data grant_type=password \
--data username="$USERNAME" \
--data password="$PASSWORD" \
| jq -r ".access_token")
## VIDEO UPLOAD
curl -s "$API/videos/upload" \
-H "Authorization: Bearer $token" \
--max-time 600 \
--form videofile=@"$FILE_PATH" \
--form channelId=$CHANNEL_ID \
--form name="$NAME" /api/v1/videos/upload-resumable:
post:
summary: Initialize the resumable upload of a video
operationId: uploadResumableInit
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/resumableUploadInitContentLengthHeader'
- $ref: '#/components/parameters/resumableUploadInitContentTypeHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadRequestResumable'
responses:
'200':
'201':
headers:
Location:
schema:
type: string
format: url
example: /api/v1/videos/upload-resumable?upload_id=471e97554f21dec3b8bb5d4602939c51
Content-Length:
schema:
type: number
example: 0
'413':
x-summary: video file too large, due to quota, absolute max file size or concurrent partial upload limit
Disambiguate via code:
- max_file_size_reached for the absolute file size limit
- quota_reached for quota limits whether daily or global
'415':
put:
summary: Send chunk for the resumable upload of a video
operationId: uploadResumable
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/resumableUploadId'
- $ref: '#/components/parameters/resumableUploadChunkContentRangeHeader'
- $ref: '#/components/parameters/resumableUploadChunkContentLengthHeader'
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'200':
headers:
Content-Length:
schema:
type: number
content:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
'308':
headers:
Range:
schema:
type: string
example: bytes=0-262143
Content-Length:
schema:
type: number
example: 0
'400':
'403':
'404':
'409':
'422':
'429':
'503':
headers:
'Retry-After':
schema:
type: number
example: 300
delete:
summary: Cancel the resumable upload of a video, deleting any data uploaded so far
operationId: uploadResumableCancel
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/resumableUploadId'
- name: Content-Length
in: header
required: true
schema:
type: number
example: 0
responses:
'204':
headers:
Content-Length:
schema:
type: number
example: 0
'404':
/api/v1/videos/imports:
post:
summary: Import a video
operationId: importVideo
security:
- OAuth2: []
tags:
- Video Imports
- Video Upload
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/VideoCreateImport'
encoding:
torrentfile:
contentType: application/x-bittorrent
thumbnailfile:
contentType: image/jpeg
previewfile:
contentType: image/jpeg
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
'400':
'403':
'409':
/api/v1/videos/imports/{id}/cancel:
post:
summary: Cancel video import
security:
- OAuth2: []
tags:
- Video Imports
parameters:
- $ref: '#/components/parameters/id'
responses:
'204':
/api/v1/videos/imports/{id}/retry:
post:
summary: Retry video import
security:
- OAuth2: []
tags:
- Video Imports
parameters:
- $ref: '#/components/parameters/id'
responses:
'204':
/api/v1/videos/imports/{id}:
delete:
summary: Delete video import
security:
- OAuth2: []
tags:
- Video Imports
parameters:
- $ref: '#/components/parameters/id'
responses:
'204':
/api/v1/videos/live:
post:
summary: Create a live
operationId: addLive
security:
- OAuth2: []
tags:
- Live Videos
- Video
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoUploadResponse'
'400':
x-summary: validation error, or conflicting saveReplay and permanentLive parameter set
Disambiguate via code:
- default type for a validation error
- live_conflicting_permanent_and_save_replay for conflicting parameters set
'403':
x-summary: live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded
Disambiguate via code:
- live_not_enabled for a disabled live feature
- live_not_allowing_replay for a disabled replay feature
- max_instance_lives_limit_reached for the absolute concurrent live limit
- max_user_lives_limit_reached for the user concurrent live limit
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
channelId:
type: integer
saveReplay:
type: boolean
replaySettings:
$ref: '#/components/schemas/LiveVideoReplaySettings'
permanentLive:
type: boolean
latencyMode:
allOf:
- $ref: '#/components/schemas/LiveVideoLatencyMode'
thumbnailfile:
type: string
format: binary
previewfile:
deprecated: true
type: string
format: binary
privacy:
$ref: '#/components/schemas/VideoPrivacySet'
category:
$ref: '#/components/schemas/VideoCategorySet'
licence:
$ref: '#/components/schemas/VideoLicenceSet'
language:
$ref: '#/components/schemas/VideoLanguageSet'
type: string
support:
example: Please support our work on https://soutenir.framasoft.org/en/ <3
type: string
nsfw:
type: boolean
nsfwSummary:
nsfwFlags:
$ref: '#/components/schemas/NSFWFlag'
name:
type: string
minLength: 3
maxLength: 120
tags:
type: array
minItems: 1
maxItems: 5
items:
type: string
minLength: 2
maxLength: 30
commentsPolicy:
$ref: '#/components/schemas/VideoCommentsPolicySet'
recommendationScope:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
aiUsage:
$ref: '#/components/schemas/VideoAIUsageSet'
commercialContent:
$ref: '#/components/schemas/VideoCommercialContentSet'
downloadEnabled:
type: boolean
schedules:
type: array
items:
$ref: '#/components/schemas/LiveSchedule'
required:
- channelId
- name
encoding:
thumbnailfile:
contentType: image/jpeg
previewfile:
contentType: image/jpeg
/api/v1/videos/live/{id}:
get:
summary: Get information about a live
operationId: getLiveId
security:
- OAuth2: []
tags:
- Live Videos
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/LiveVideoResponse'
put:
summary: Update information about a live
operationId: updateLiveId
security:
- OAuth2: []
tags:
- Live Videos
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LiveVideoUpdate'
responses:
'204':
'400':
'403':
/api/v1/videos/live/{id}/sessions:
get:
summary: List live sessions
security:
- OAuth2: []
tags:
- Live Videos
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/LiveVideoSessionResponse'
/api/v1/videos/{id}/live-session:
get:
summary: Get live session of a replay
security:
- OAuth2: []
tags:
- Live Videos
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/LiveVideoSessionResponse'
'/api/v1/videos/{id}/source':
get:
summary: Get video source file metadata
operationId: getVideoSource
security:
- OAuth2: []
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoSource'
'/api/v1/videos/{id}/source/file':
delete:
summary: Delete video source file
operationId: deleteVideoSourceFile
tags:
- Video
security:
- OAuth2:
- admin
- moderator
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'404':
'/api/v1/videos/{id}/source/replace-resumable':
post:
summary: Initialize the resumable replacement of a video
operationId: replaceVideoSourceResumableInit
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/resumableUploadInitContentLengthHeader'
- $ref: '#/components/parameters/resumableUploadInitContentTypeHeader'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoReplaceSourceRequestResumable'
responses:
'200':
'201':
headers:
Location:
schema:
type: string
format: url
Content-Length:
schema:
type: number
example: 0
'413':
x-summary: video file too large, due to quota, absolute max file size or concurrent partial upload limit
Disambiguate via code:
- max_file_size_reached for the absolute file size limit
- quota_reached for quota limits whether daily or global
'415':
put:
summary: Send chunk for the resumable replacement of a video
operationId: replaceVideoSourceResumable
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/resumableUploadId'
- $ref: '#/components/parameters/resumableUploadChunkContentRangeHeader'
- $ref: '#/components/parameters/resumableUploadChunkContentLengthHeader'
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
'204':
'308':
headers:
Range:
schema:
type: string
example: bytes=0-262143
Content-Length:
schema:
type: number
example: 0
'400':
'403':
'404':
'409':
'422':
'429':
'503':
headers:
'Retry-After':
schema:
type: number
example: 300
delete:
summary: Cancel the resumable replacement of a video
operationId: replaceVideoSourceResumableCancel
security:
- OAuth2: []
tags:
- Video
- Video Upload
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/resumableUploadId'
- name: Content-Length
in: header
required: true
schema:
type: number
example: 0
responses:
'204':
headers:
Content-Length:
schema:
type: number
example: 0
'404':
/api/v1/users/me/abuses:
get:
summary: List my abuses
operationId: getMyAbuses
security:
- OAuth2: []
tags:
- Abuses
- My User
parameters:
- name: id
in: query
schema:
type: integer
- name: state
in: query
schema:
$ref: '#/components/schemas/AbuseStateSet'
- $ref: '#/components/parameters/abusesSort'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Abuse'
/api/v1/abuses:
get:
summary: List abuses
operationId: getAbuses
security:
- OAuth2:
- admin
- moderator
tags:
- Abuses
parameters:
- name: id
in: query
schema:
type: integer
- name: predefinedReason
in: query
schema:
$ref: '#/components/schemas/PredefinedAbuseReasons'
- name: search
in: query
schema:
type: string
- name: state
in: query
schema:
$ref: '#/components/schemas/AbuseStateSet'
- name: searchReporter
in: query
schema:
type: string
- name: searchReportee
in: query
schema:
type: string
- name: searchVideo
in: query
schema:
type: string
- name: searchVideoChannel
in: query
schema:
type: string
- name: videoIs
in: query
schema:
type: string
enum:
- 'deleted'
- 'blacklisted'
- name: filter
in: query
schema:
type: string
enum:
- 'video'
- 'comment'
- 'account'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/abusesSort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Abuse'
post:
summary: Report an abuse
You cannot report a video that you own or on which you are a collaborator (video channel editor).
security:
- OAuth2: []
tags:
- Abuses
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
reason:
type: string
minLength: 2
maxLength: 3000
predefinedReasons:
$ref: '#/components/schemas/PredefinedAbuseReasons'
video:
type: object
properties:
id:
allOf:
- $ref: '#/components/schemas/Video/properties/id'
startAt:
type: integer
format: seconds
minimum: 0
endAt:
type: integer
format: seconds
minimum: 0
comment:
type: object
properties:
id:
allOf:
- $ref: '#/components/schemas/VideoComment/properties/id'
account:
type: object
properties:
id:
type: integer
required:
- reason
responses:
'200':
content:
application/json:
schema:
type: object
properties:
abuse:
type: object
properties:
id:
$ref: '#/components/schemas/id'
'400':
'403':
'/api/v1/abuses/{abuseId}':
put:
summary: Update an abuse
security:
- OAuth2:
- admin
- moderator
tags:
- Abuses
parameters:
- $ref: '#/components/parameters/abuseId'
requestBody:
content:
application/json:
schema:
type: object
properties:
state:
$ref: '#/components/schemas/AbuseStateSet'
moderationComment:
type: string
minLength: 2
maxLength: 3000
responses:
'204':
'404':
delete:
tags:
- Abuses
summary: Delete an abuse
security:
- OAuth2:
- admin
- moderator
parameters:
- $ref: '#/components/parameters/abuseId'
responses:
'204':
'404':
'/api/v1/abuses/{abuseId}/messages':
get:
summary: List messages of an abuse
security:
- OAuth2: []
tags:
- Abuses
parameters:
- $ref: '#/components/parameters/abuseId'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/AbuseMessage'
post:
summary: Add message to an abuse
security:
- OAuth2: []
tags:
- Abuses
parameters:
- $ref: '#/components/parameters/abuseId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
message:
type: string
minLength: 2
maxLength: 3000
required:
- message
responses:
'200':
'400':
'/api/v1/abuses/{abuseId}/messages/{abuseMessageId}':
delete:
summary: Delete an abuse message
security:
- OAuth2: []
tags:
- Abuses
parameters:
- $ref: '#/components/parameters/abuseId'
- $ref: '#/components/parameters/abuseMessageId'
responses:
'204':
'/api/v1/videos/{id}/blacklist':
post:
summary: Block a video
operationId: addVideoBlock
security:
- OAuth2:
- admin
- moderator
tags:
- Video Blocks
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoBlacklistCreate'
responses:
'204':
put:
summary: Update a video block
operationId: updateVideoBlock
security:
- OAuth2:
- admin
- moderator
tags:
- Video Blocks
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoBlacklistUpdate'
responses:
'204':
'404':
delete:
summary: Unblock a video by its id
operationId: delVideoBlock
security:
- OAuth2:
- admin
- moderator
tags:
- Video Blocks
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'404':
/api/v1/videos/blacklist:
get:
tags:
- Video Blocks
summary: List video blocks
operationId: getVideoBlocks
security:
- OAuth2:
- admin
- moderator
parameters:
- name: type
in: query
list only blocks that match this type:
- `1`: manual block
- `2`: automatic block that needs review
schema:
type: integer
enum:
- 1
- 2
- name: search
in: query
schema:
type: string
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/blacklistsSort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoBlacklist' /api/v1/videos/{id}/storyboards:
get:
summary: List storyboards of a video
operationId: listVideoStoryboards
tags:
- Video
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
storyboards:
type: array
items:
$ref: '#/components/schemas/Storyboard'
/api/v1/videos/{id}/captions:
get:
summary: List captions of a video
operationId: getVideoCaptions
tags:
- Video Captions
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoCaption'
/api/v1/videos/{id}/captions/generate:
post:
summary: Generate a video caption
operationId: generateVideoCaption
security:
- OAuth2:
- user
tags:
- Video Captions
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
forceTranscription:
type: boolean
default: false
responses:
'204':
'404':
/api/v1/videos/{id}/captions/{captionLanguage}:
put:
summary: Add or replace a video caption
operationId: addVideoCaption
security:
- OAuth2:
- user
tags:
- Video Captions
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/captionLanguage'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
captionfile:
type: string
format: binary
encoding:
captionfile:
contentType: text/vtt, application/x-subrip, text/plain
responses:
'204':
'404':
delete:
summary: Delete a video caption
operationId: delVideoCaption
security:
- OAuth2:
- user
tags:
- Video Captions
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/captionLanguage'
responses:
'204':
'404':
/api/v1/videos/{id}/chapters:
get:
summary: Get chapters of a video
operationId: getVideoChapters
tags:
- Video Chapters
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChapters'
put:
summary: Replace video chapters
operationId: replaceVideoChapters
security:
- OAuth2:
- user
tags:
- Video Chapters
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
chapters:
type: array
items:
type: object
properties:
title:
type: string
timecode:
type: integer
responses:
'204':
'404':
/api/v1/videos/{id}/embed-privacy:
get:
summary: Get video embed privacy
operationId: getVideoEmbedPrivacy
security:
- OAuth2:
- user
tags:
- Video Embed Privacy
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
policy:
type: object
properties:
id:
$ref: '#/components/schemas/VideoEmbedPrivacy'
label:
type: string
example: Allowlist
domains:
type: array
items:
type: string
example: 'example.com'
'400':
put:
summary: Update video embed privacy
operationId: updateVideoEmbedPrivacy
security:
- OAuth2:
- user
tags:
- Video Embed Privacy
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
policy:
$ref: '#/components/schemas/VideoEmbedPrivacy'
domains:
type: array
items:
type: string
example: 'example.com'
responses:
'204':
'400':
/api/v1/videos/{id}/embed-privacy/allowed:
get:
summary: Check if embed is allowed
operationId: isVideoEmbedOnDomainAllowed
security:
- OAuth2:
- user
tags:
- Video Embed Privacy
parameters:
- $ref: '#/components/parameters/idOrUUID'
- name: domain
in: query
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
domainAllowed:
type: boolean
userBypassAllowed:
nullable: true
type: boolean
'400':
/api/v1/videos/{id}/passwords:
get:
summary: List video passwords
operationId: listVideoPasswords
security:
- OAuth2:
- user
tags:
- Video Passwords
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoPasswordList'
'400':
put:
summary: Update video passwords
operationId: updateVideoPasswordList
security:
- OAuth2:
- user
tags:
- Video Passwords
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
passwords:
$ref: '#/components/schemas/AddVideoPasswords'
responses:
'204':
'400':
post:
summary: Add a video password
operationId: addVideoPassword
security:
- OAuth2:
- user
tags:
- Video Passwords
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
password:
type: string
responses:
'204':
'400':
/api/v1/videos/{id}/passwords/{passwordId}:
delete:
summary: Delete a video password
operationId: removeVideoPassword
security:
- OAuth2:
- user
tags:
- Video Passwords
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/passwordId'
responses:
'204':
'403':
'400':
/api/v1/video-channels:
get:
summary: List video channels
operationId: getVideoChannels
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelList'
post:
summary: Create a video channel
operationId: addVideoChannel
security:
- OAuth2: []
tags:
- Video Channels
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoChannel:
type: object
properties:
id:
$ref: '#/components/schemas/id'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelCreate'
'/api/v1/video-channels/{channelHandle}':
get:
summary: Get a video channel
operationId: getVideoChannel
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannel'
put:
summary: Update a video channel
operationId: putVideoChannel
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'204':
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelUpdate'
delete:
summary: Delete a video channel
operationId: delVideoChannel
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'204':
'/api/v1/video-channels/{channelHandle}/videos':
get:
summary: List videos of a video channel
operationId: getVideoChannelVideos
tags:
- Video
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
'/api/v1/video-channels/{channelHandle}/activities':
get:
summary: List activities of a video channel
operationId: listVideoChannelActivities
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ChannelActivityListResponse'
'/api/v1/video-channels/{channelHandle}/video-playlists':
get:
summary: List playlists of a channel
tags:
- Video Playlists
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/videoPlaylistType'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoPlaylist'
'/api/v1/video-channels/{channelHandle}/video-playlists/reorder':
post:
summary: Reorder channel playlists
operationId: reorderVideoPlaylistsOfChannel
security:
- OAuth2: []
tags:
- Video Playlists
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'204':
requestBody:
content:
application/json:
schema:
type: object
properties:
startPosition:
type: integer
minimum: 1
insertAfterPosition:
type: integer
minimum: 0
reorderLength:
type: integer
minimum: 1
required:
- startPosition
- insertAfterPosition
'/api/v1/video-channels/{channelHandle}/followers':
get:
tags:
- Video Channels
summary: 'List followers of a video channel'
security:
- OAuth2: []
operationId: getVideoChannelFollowers
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/followersSort'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Follow'
'/api/v1/video-channels/{channelHandle}/avatar/pick':
post:
summary: Update channel avatar
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
avatarfile:
type: string
format: binary
encoding:
avatarfile:
contentType: image/png, image/jpeg
'/api/v1/video-channels/{channelHandle}/avatar':
delete:
summary: Delete channel avatar
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'204':
'/api/v1/video-channels/{channelHandle}/banner/pick':
post:
summary: Update channel banner
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
banners:
type: array
items:
$ref: '#/components/schemas/ActorImage'
'413':
headers:
X-File-Maximum-Size:
schema:
type: string
format: Nginx size
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
bannerfile:
type: string
format: binary
encoding:
bannerfile:
contentType: image/png, image/jpeg
'/api/v1/video-channels/{channelHandle}/banner':
delete:
summary: Delete channel banner
security:
- OAuth2: []
tags:
- Video Channels
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'204':
'/api/v1/video-channels/{channelHandle}/import-videos':
post:
summary: Import videos in channel
security:
- OAuth2: []
tags:
- Video Channels
- Channels Sync
parameters:
- $ref: '#/components/parameters/channelHandle'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ImportVideosInChannelCreate'
responses:
'204':
'/api/v1/video-channel-syncs':
post:
summary: Create a synchronization for a video channel
operationId: addVideoChannelSync
security:
- OAuth2: []
tags:
- Channels Sync
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelSyncCreate'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoChannelSync:
$ref: "#/components/schemas/VideoChannelSync"
'/api/v1/video-channel-syncs/{channelSyncId}':
delete:
summary: Delete a video channel synchronization
operationId: delVideoChannelSync
security:
- OAuth2: []
tags:
- Channels Sync
parameters:
- $ref: '#/components/parameters/channelSyncId'
responses:
'204':
'/api/v1/video-channel-syncs/{channelSyncId}/sync':
post:
summary: Triggers the channel synchronization job, fetching all the videos from the remote channel
operationId: triggerVideoChannelSync
security:
- OAuth2: []
tags:
- Channels Sync
parameters:
- $ref: '#/components/parameters/channelSyncId'
responses:
'204':
'/api/v1/player-settings/videos/{id}':
get:
summary: Get video player settings
operationId: getVideoPlayerSettings
tags:
- Player Settings
parameters:
- $ref: '#/components/parameters/idOrUUID'
- name: raw
in: query
required: false
schema:
type: boolean
default: false
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerVideoSettings'
'404':
put:
summary: Update video player settings
operationId: updateVideoPlayerSettings
security:
- OAuth2: []
tags:
- Player Settings
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerVideoSettingsUpdate'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerVideoSettings'
'404':
'/api/v1/player-settings/video-channels/{channelHandle}':
get:
summary: Get channel player settings
operationId: getChannelPlayerSettings
tags:
- Player Settings
parameters:
- $ref: '#/components/parameters/channelHandle'
- name: raw
in: query
required: false
schema:
type: boolean
default: false
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerChannelSettings'
'404':
put:
summary: Update channel player settings
operationId: updateChannelPlayerSettings
security:
- OAuth2: []
tags:
- Player Settings
parameters:
- $ref: '#/components/parameters/channelHandle'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerChannelSettingsUpdate'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PlayerChannelSettings'
'404':
/api/v1/video-playlists/privacies:
get:
summary: List available playlist privacy policies
operationId: getPlaylistPrivacyPolicies
tags:
- Video Playlists
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
examples:
nightly:
externalValue: https://peertube2.cpy.re/api/v1/video-playlists/privacies
/api/v1/video-playlists:
get:
summary: List video playlists
operationId: getPlaylists
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/videoPlaylistType'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoPlaylist'
post:
summary: Create a video playlist
operationId: addPlaylist
security:
- OAuth2: []
tags:
- Video Playlists
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoPlaylist:
type: object
properties:
id:
$ref: '#/components/schemas/VideoPlaylist/properties/id'
uuid:
$ref: '#/components/schemas/VideoPlaylist/properties/uuid'
shortUUID:
$ref: '#/components/schemas/VideoPlaylist/properties/shortUUID'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
displayName:
type: string
minLength: 1
maxLength: 120
thumbnailfile:
type: string
format: binary
privacy:
$ref: '#/components/schemas/VideoPlaylistPrivacySet'
type: string
minLength: 3
maxLength: 1000
videoChannelId:
allOf:
- $ref: '#/components/schemas/id'
required:
- displayName
encoding:
thumbnailfile:
contentType: image/jpeg
/api/v1/video-playlists/{playlistId}:
get:
summary: Get a video playlist
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoPlaylist'
put:
summary: Update a video playlist
security:
- OAuth2: []
tags:
- Video Playlists
responses:
'204':
parameters:
- $ref: '#/components/parameters/playlistId'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
displayName:
type: string
minLength: 1
maxLength: 120
thumbnailfile:
type: string
format: binary
privacy:
$ref: '#/components/schemas/VideoPlaylistPrivacySet'
type: string
videoChannelId:
allOf:
- $ref: '#/components/schemas/id'
encoding:
thumbnailfile:
contentType: image/jpeg
delete:
summary: Delete a video playlist
security:
- OAuth2: []
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
responses:
'204':
/api/v1/video-playlists/{playlistId}/videos:
get:
summary: 'List videos of a playlist'
operationId: getVideoPlaylistVideos
tags:
- Videos
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
responses:
'200':
content:
application/json:
schema:
properties:
total:
type: integer
example: 1
data:
type: array
maxItems: 100
items:
type: object
properties:
id:
allOf:
- $ref: '#/components/schemas/id'
position:
type: integer
example: 2
startTimestamp:
type: integer
nullable: true
example: 10
format: seconds
stopTimestamp:
type: integer
nullable: true
example: 41
format: seconds
video:
$ref: '#/components/schemas/Video'
post:
summary: Add a video in a playlist
operationId: addVideoPlaylistVideo
security:
- OAuth2: []
tags:
- Videos
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoPlaylistElement:
type: object
properties:
id:
type: integer
example: 2
requestBody:
content:
application/json:
schema:
type: object
properties:
videoId:
oneOf:
- $ref: '#/components/schemas/Video/properties/uuid'
- $ref: '#/components/schemas/Video/properties/id'
startTimestamp:
type: integer
format: seconds
stopTimestamp:
type: integer
format: seconds
required:
- videoId /api/v1/video-playlists/{playlistId}/videos/reorder:
post:
summary: Reorder playlist elements
operationId: reorderVideoPlaylist
security:
- OAuth2: []
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
responses:
'204':
requestBody:
content:
application/json:
schema:
type: object
properties:
startPosition:
type: integer
minimum: 1
insertAfterPosition:
type: integer
minimum: 0
reorderLength:
type: integer
minimum: 1
required:
- startPosition
- insertAfterPosition
/api/v1/video-playlists/{playlistId}/videos/{playlistElementId}:
put:
summary: Update a playlist element
operationId: putVideoPlaylistVideo
security:
- OAuth2: []
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
- $ref: '#/components/parameters/playlistElementId'
responses:
'204':
requestBody:
content:
application/json:
schema:
type: object
properties:
startTimestamp:
type: integer
format: seconds
stopTimestamp:
type: integer
format: seconds
delete:
summary: Delete an element from a playlist
operationId: delVideoPlaylistVideo
security:
- OAuth2: []
tags:
- Video Playlists
parameters:
- $ref: '#/components/parameters/playlistId'
- $ref: '#/components/parameters/playlistElementId'
responses:
'204':
'/api/v1/users/me/video-playlists/videos-exist':
get:
summary: Check video exists in my playlists
security:
- OAuth2: []
tags:
- Video Playlists
parameters:
- name: videoIds
in: query
required: true
schema:
type: array
items:
$ref: '#/components/schemas/Video/properties/id'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
videoId:
type: array
items:
type: object
properties:
playlistElementId:
type: integer
playlistId:
type: integer
startTimestamp:
type: integer
format: seconds
nullable: true
stopTimestamp:
type: integer
format: seconds
nullable: true
'/api/v1/accounts/{name}/video-playlists':
get:
summary: List playlists of an account
tags:
- Video Playlists
- Accounts
parameters:
- $ref: '#/components/parameters/name'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/search'
- $ref: '#/components/parameters/videoPlaylistType'
- $ref: '#/components/parameters/includeCollaborations'
- name: channelNameOneOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
items:
type: string
style: form
explode: true
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoPlaylist'
'/api/v1/accounts/{name}/video-channels':
get:
summary: List video channels of an account
tags:
- Video Channels
- Accounts
parameters:
- $ref: '#/components/parameters/name'
- name: withStats
in: query
schema:
type: boolean
- name: statsDays
in: query
number of days of view statistics to include in viewsPerDay when withStats is true
(only if authenticated as the account user).
0 means all time (since the channel's earliest recorded stat).
viewsPerDay always spans the whole requested range so channels can be compared to each other.
Its bucket size is reported in viewsGroupInterval: it is derived from the requested range,
narrowed to the channel history so that a young channel on a long range is not aggregated
into a single coarse bucket.
totalViews is unaffected by this parameter and always reports lifetime views.
schema:
type: integer
enum: [30, 90, 365, 0]
default: 30
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/search'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/includeCollaborations'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelList'
'/api/v1/accounts/{name}/video-channel-syncs':
get:
summary: List the synchronizations of video channels of an account
tags:
- Video Channels
- Channels Sync
- Accounts
parameters:
- $ref: '#/components/parameters/name'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/includeCollaborations'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelSyncList'
'/api/v1/accounts/{name}/ratings':
get:
summary: List ratings of an account
security:
- OAuth2: []
tags:
- Accounts
parameters:
- $ref: '#/components/parameters/name'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- name: rating
in: query
required: false
schema:
type: string
enum:
- like
- dislike
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/VideoRating'
'/api/v1/videos/{id}/comment-threads':
get:
summary: List threads of a video
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/commentsSort'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommentThreadResponse'
post:
summary: Create a thread
security:
- OAuth2: []
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommentThreadPostResponse'
'404':
requestBody:
content:
application/json:
schema:
type: object
properties:
text:
allOf:
- $ref: '#/components/schemas/VideoComment/properties/text'
format: markdown
maxLength: 10000
required:
- text
'/api/v1/videos/{id}/comment-threads/{threadId}':
get:
summary: Get a thread
Since PeerTube 8.3 the returned tree is truncated: only the first replies of each comment are included, and only
down to maxDepth nesting levels. Use GET /api/v1/videos/{id}/comments/{commentId}/replies to fetch the
replies that are missing, comparing children and totalChildren of each node of the tree.
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/threadId'
- $ref: '#/components/parameters/commentMaxDepth'
- $ref: '#/components/parameters/commentRepliesPerLevel'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoCommentThreadTree'
'/api/v1/videos/{id}/comments/{commentId}/replies':
get:
summary: List replies of a comment
PeerTube >= 8.3 List the direct replies of a comment, each of them nested up to maxDepth levels. Used to unfold the parts of a
thread that GET /api/v1/videos/{id}/comment-threads/{threadId} truncated.
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/commentId'
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/commentRepliesSort'
- $ref: '#/components/parameters/commentMaxDepth'
- $ref: '#/components/parameters/commentRepliesPerLevel'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 13
data:
type: array
items:
$ref: '#/components/schemas/VideoCommentThreadTree'
'/api/v1/videos/comments':
get:
summary: List instance comments
security:
- OAuth2:
- admin
- moderator
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/search'
- $ref: '#/components/parameters/searchAccountForComments'
- $ref: '#/components/parameters/searchVideoForComments'
- $ref: '#/components/parameters/videoId'
- $ref: '#/components/parameters/videoChannelId'
- $ref: '#/components/parameters/autoTagOneOfComment'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/onLocalVideo'
- $ref: '#/components/parameters/includeMuted'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoCommentForOwnerOrAdmin' '/api/v1/videos/{id}/comments/{commentId}':
post:
summary: Reply to a thread of a video
security:
- OAuth2: []
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/commentId'
- $ref: '#/components/parameters/videoPasswordHeader'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommentThreadPostResponse'
'404':
requestBody:
content:
application/json:
schema:
type: object
properties:
text:
allOf:
- $ref: '#/components/schemas/VideoComment/properties/text'
format: markdown
maxLength: 10000
required:
- text
delete:
summary: Delete a comment or a reply
security:
- OAuth2: []
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/commentId'
responses:
'204':
'403':
'404':
'409':
'/api/v1/videos/{id}/comments/{commentId}/approve':
post:
summary: Approve a comment
security:
- OAuth2: []
tags:
- Video Comments
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/commentId'
responses:
'204':
'/api/v1/videos/{id}/rate':
put:
summary: Like/dislike a video
security:
- OAuth2: []
tags:
- Video Rates
parameters:
- $ref: '#/components/parameters/idOrUUID'
- $ref: '#/components/parameters/videoPasswordHeader'
requestBody:
content:
application/json:
schema:
type: object
properties:
rating:
type: string
enum:
- like
- dislike
required:
- rating
responses:
'204':
'404':
'/api/v1/videos/{id}/hls':
delete:
summary: Delete video HLS files
security:
- OAuth2:
- admin
tags:
- Video Files
operationId: delVideoHLS
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'404':
'/api/v1/videos/{id}/web-videos':
delete:
summary: Delete video Web Video files
security:
- OAuth2:
- admin
tags:
- Video Files
operationId: delVideoWebVideos
parameters:
- $ref: '#/components/parameters/idOrUUID'
responses:
'204':
'404':
'/api/v1/videos/{id}/transcoding':
post:
summary: Create a transcoding job
security:
- OAuth2:
- admin
tags:
- Video Transcoding
operationId: createVideoTranscoding
parameters:
- $ref: '#/components/parameters/idOrUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
transcodingType:
type: string
enum:
- hls
- web-video
forceTranscoding:
type: boolean
default: false
required:
- transcodingType
responses:
'204':
'404':
/api/v1/search/videos:
get:
tags:
- Search
- Video
summary: Search videos
operationId: searchVideos
parameters:
- name: search
in: query
required: true
allowEmptyValue: false
String to search. If the user can make a remote URI search, and the string is an URI then the
PeerTube instance will fetch the remote object and add it to its database. Then,
you can use the REST API to fetch the complete video information and interact with it.
schema:
type: string
- $ref: '#/components/parameters/uuids'
- $ref: '#/components/parameters/searchTarget'
# Common video filter parameters
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/skipCount'
- $ref: '#/components/parameters/videosSort'
- $ref: '#/components/parameters/nsfw'
- $ref: '#/components/parameters/nsfwFlagsIncluded'
- $ref: '#/components/parameters/nsfwFlagsExcluded'
- $ref: '#/components/parameters/aiUsageOneOf'
- $ref: '#/components/parameters/isLive'
- $ref: '#/components/parameters/includeScheduledLive'
- $ref: '#/components/parameters/categoryOneOf'
- $ref: '#/components/parameters/licenceOneOf'
- $ref: '#/components/parameters/languageOneOf'
- $ref: '#/components/parameters/tagsOneOf'
- $ref: '#/components/parameters/tagsAllOf'
- $ref: '#/components/parameters/isLocal'
- $ref: '#/components/parameters/include'
- $ref: '#/components/parameters/hasHLSFiles'
- $ref: '#/components/parameters/hasWebVideoFiles'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/autoTagOneOfVideo'
- $ref: '#/components/parameters/stateOneOfVideo'
- $ref: '#/components/parameters/privacyOneOf'
- $ref: '#/components/parameters/excludeAlreadyWatched'
- name: startDate
in: query
schema:
type: string
format: date-time
- name: endDate
in: query
schema:
type: string
format: date-time
- name: originallyPublishedStartDate
in: query
schema:
type: string
format: date-time
- name: originallyPublishedEndDate
in: query
schema:
type: string
format: date-time
- name: durationMin
in: query
schema:
type: integer
- name: durationMax
in: query
schema:
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoListResponse'
'500':
/api/v1/search/video-channels:
get:
tags:
- Search
- Video Channels
summary: Search channels
operationId: searchChannels
parameters:
- name: search
in: query
required: true
String to search. If the user can make a remote URI search, and the string is an URI then the
PeerTube instance will fetch the remote object and add it to its database. Then,
you can use the REST API to fetch the complete channel information and interact with it.
schema:
type: string
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/searchTarget'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/handles'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoChannelList'
'500':
/api/v1/search/video-playlists:
get:
tags:
- Search
- Video Playlists
summary: Search playlists
operationId: searchPlaylists
parameters:
- name: search
in: query
required: true
String to search. If the user can make a remote URI search, and the string is an URI then the
PeerTube instance will fetch the remote object and add it to its database. Then,
you can use the REST API to fetch the complete playlist information and interact with it.
schema:
type: string
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/searchTarget'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/host'
- $ref: '#/components/parameters/uuids'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoPlaylist'
'500':
/api/v1/blocklist/status:
get:
tags:
- Account Blocklist
- Server Blocklist
summary: Get block status of accounts/hosts
parameters:
-
name: 'accounts'
in: query
example: [ '[email protected]', '[email protected]' ]
schema:
type: array
items:
type: string
-
name: 'hosts'
in: query
example: [ 'example.com' ]
schema:
type: array
items:
type: string
responses:
'200':
content:
'application/json':
schema:
$ref: '#/components/schemas/BlockStatus'
/api/v1/users/me/blocklist/accounts:
get:
summary: List accounts blocked by my account
operationId: getMyBlockedAccounts
security:
- OAuth2:
- user
tags:
- Account Blocklist
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- name: search
in: query
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/AccountBlock'
'401':
post:
summary: Block an account by my account
operationId: blockAccount
security:
- OAuth2:
- user
tags:
- Account Blocklist
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
accountName:
type: string
example: '[email protected]'
required:
- accountName
responses:
'204':
'400':
'401':
'404':
/api/v1/users/me/blocklist/accounts/{accountName}:
delete:
summary: Unblock an account by my account
operationId: unblockAccount
security:
- OAuth2:
- user
tags:
- Account Blocklist
parameters:
- name: accountName
in: path
required: true
schema:
type: string
example: '[email protected]'
responses:
'204':
'400':
'401':
'404':
/api/v1/users/me/blocklist/servers:
get:
summary: List servers blocked by my account
operationId: getMyBlockedServers
security:
- OAuth2:
- user
tags:
- Account Blocklist
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- name: search
in: query
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ServerBlock'
'401':
post:
summary: Block a server by my account
operationId: blockServer
security:
- OAuth2:
- user
tags:
- Account Blocklist
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
host:
type: string
example: 'example.com'
required:
- host
responses:
'204':
'400':
'401':
'404':
/api/v1/users/me/blocklist/servers/{host}:
delete:
summary: Unblock a server by my account
operationId: unblockServer
security:
- OAuth2:
- user
tags:
- Account Blocklist
parameters:
- name: host
in: path
required: true
schema:
type: string
example: 'example.com'
responses:
'204':
'400':
'401':
'404':
/api/v1/server/blocklist/accounts:
get:
tags:
- Server Blocklist
summary: List blocked accounts by server
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
-
name: subscriptionName
in: query
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/AccountBlock'
post:
tags:
- Server Blocklist
summary: Block an account by server
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
accountName:
type: string
example: [email protected]
required:
- accountName
responses:
'200':
'409':
'/api/v1/server/blocklist/accounts/{accountName}':
delete:
tags:
- Server Blocklist
summary: Unblock an account by server
security:
- OAuth2:
- admin
parameters:
- name: accountName
in: path
required: true
schema:
type: string
responses:
'201':
'404':
/api/v1/server/blocklist/servers:
get:
tags:
- Server Blocklist
summary: List blocked servers by server
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
-
name: subscriptionName
in: query
required: false
schema:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/ServerBlock'
post:
tags:
- Server Blocklist
summary: Block a server by server
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
host:
type: string
format: hostname
required:
- host
responses:
'204':
'409':
'/api/v1/server/blocklist/servers/{host}':
delete:
tags:
- Server Blocklist
summary: Unblock a server by server
security:
- OAuth2:
- admin
parameters:
- name: host
in: path
required: true
schema:
type: string
format: hostname
responses:
'204':
'404':
/api/v1/server/blocklist/subscriptions:
get:
tags:
- Server Blocklist
summary: List server blocklist subscriptions
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/BlocklistSubscription'
post:
tags:
- Server Blocklist
summary: Add a server blocklist subscription
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: url
required:
- url
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/BlocklistSubscription'
'409':
'/api/v1/server/blocklist/subscriptions/{id}':
delete:
tags:
- Server Blocklist
summary: Delete a server blocklist subscription
security:
- OAuth2:
- admin
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'204':
'404':
/api/v1/server/blocklist/public-log:
get:
tags:
- Server Blocklist
summary: List publicly shared server blocklist log entries
parameters:
- name: startDate
in: query
required: true
schema:
type: string
format: date-time
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AutoMuteList'
'403':
/api/v1/server/redundancy/{host}:
put:
tags:
- Instance Redundancy
summary: Update a server redundancy policy
security:
- OAuth2:
- admin
parameters:
- name: host
in: path
required: true
schema:
type: string
format: hostname
requestBody:
content:
application/json:
schema:
type: object
properties:
redundancyAllowed:
type: boolean
required:
- redundancyAllowed
responses:
'204':
'404':
/api/v1/server/redundancy/videos:
get:
tags:
- Video Mirroring
summary: List videos being mirrored
operationId: getMirroredVideos
security:
- OAuth2:
- admin
parameters:
- name: target
in: query
required: true
schema:
type: string
enum:
- my-videos
- remote-videos
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/videoRedundanciesSort'
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/VideoRedundancy'
post:
tags:
- Video Mirroring
summary: Mirror a video
operationId: putMirroredVideo
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
videoId:
$ref: '#/components/schemas/Video/properties/id'
required:
- videoId
responses:
'204':
'400':
'404':
'409':
/api/v1/server/redundancy/videos/{redundancyId}:
delete:
tags:
- Video Mirroring
summary: Delete a mirror done on a video
operationId: delMirroredVideo
security:
- OAuth2:
- admin
parameters:
- name: redundancyId
in: path
required: true
schema:
type: string
responses:
'204':
'404':
/api/v1/server/stats:
get:
tags:
- Stats
summary: Get instance stats
operationId: getInstanceStats
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/ServerStats'
/api/v1/server/contact:
post:
tags:
- Contact
summary: Contact the instance administrators
operationId: contactAdministrator
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
fromName:
type: string
fromEmail:
type: string
format: email
subject:
type: string
body:
type: string
required:
- fromName
- fromEmail
- body
responses:
'204':
'403':
'409':
/api/v1/server/debug:
get:
tags:
- Debug
summary: Get debug information
operationId: getDebug
security:
- OAuth2:
- admin
responses:
'200':
content:
application/json:
schema:
type: object
properties:
ip:
type: string
activityPubMessagesWaiting:
type: integer
secondariesUp:
type: integer
processes:
type: array
items:
type: object
properties:
id:
type: string
role:
type: string
enum:
- primary
- secondary
hostname:
type: string
pid:
type: integer
version:
type: string
startedAt:
type: string
format: date-time
lastSeenAt:
type: string
format: date-time
/api/v1/server/debug/run-command:
post:
tags:
- Debug
summary: Run a debug command
operationId: runDebugCommand
security:
- OAuth2:
- admin
requestBody:
required: true
content:
application/json:
schema:
oneOf:
- type: object
properties:
command:
type: string
enum:
- remove-dandling-resumable-uploads
- remove-expired-user-exports
- process-video-stats-buffer
- process-video-viewers
- process-update-videos-scheduler
- process-video-channel-sync-latest
- process-remove-old-stats
- process-video-files-lifecycle
required:
- command
- type: object
properties:
command:
type: string
enum:
- test-emails
email:
type: string
format: email
required:
- command
- email
responses:
'204':
'400':
/api/v1/server/logs/client:
post:
tags:
- Logs
summary: Send client log
operationId: sendClientLog
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendClientLog'
responses:
'204':
/api/v1/server/logs:
get:
tags:
- Logs
summary: Get instance logs
operationId: getInstanceLogs
security:
- OAuth2:
- admin
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: string
/api/v1/server/audit-logs:
get:
tags:
- Logs
summary: Get instance audit logs
User, administration and moderation actions recorded by all the PeerTube processes of the instance.
By default (`format=array`), returns an array of at most the 10,000 most recent entries of the requested date range, oldest first.
`startDate` is then required and pagination parameters are ignored.
With `format=list`, returns a paginated list.
operationId: getInstanceAuditLogs
security:
- OAuth2:
- admin
parameters:
- name: format
in: query
required: false
schema:
type: string
default: array
enum:
- array
- list
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- createdAt
- name: search
in: query
required: false
schema:
type: string
- name: entityType
in: query
required: false
schema:
$ref: '#/components/schemas/AuditLogEntityType'
- name: entityId
in: query
required: false
schema:
type: integer
- name: action
in: query
required: false
schema:
$ref: '#/components/schemas/AuditLogAction'
- name: startDate
in: query
required: false
schema:
type: string
format: date-time
- name: endDate
in: query
required: false
schema:
type: string
format: date-time
responses:
'200':
content:
application/json:
schema:
oneOf:
- type: array
items:
$ref: '#/components/schemas/AuditLog'
- type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/AuditLog'
'403': /api/v1/plugins:
get:
tags:
- Plugins
summary: List plugins
operationId: getPlugins
security:
- OAuth2:
- admin
parameters:
- name: pluginType
in: query
schema:
type: integer
- name: uninstalled
in: query
schema:
type: boolean
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PluginResponse'
/api/v1/plugins/available:
get:
tags:
- Plugins
summary: List available plugins
operationId: getAvailablePlugins
security:
- OAuth2:
- admin
parameters:
- name: search
in: query
schema:
type: string
- name: pluginType
in: query
schema:
type: integer
- name: currentPeerTubeEngine
in: query
schema:
type: string
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PluginResponse'
'503':
/api/v1/plugins/install:
post:
tags:
- Plugins
summary: Install a plugin
operationId: addPlugin
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
oneOf:
- type: object
properties:
npmName:
type: string
example: peertube-plugin-auth-ldap
required:
- npmName
additionalProperties: false
- type: object
properties:
path:
type: string
required:
- path
additionalProperties: false
responses:
'204':
'400':
/api/v1/plugins/update:
post:
tags:
- Plugins
summary: Update a plugin
operationId: updatePlugin
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
oneOf:
- type: object
properties:
npmName:
type: string
example: peertube-plugin-auth-ldap
required:
- npmName
additionalProperties: false
- type: object
properties:
path:
type: string
required:
- path
additionalProperties: false
responses:
'204':
'400':
'404':
/api/v1/plugins/uninstall:
post:
tags:
- Plugins
summary: Uninstall a plugin
operationId: uninstallPlugin
security:
- OAuth2:
- admin
requestBody:
content:
application/json:
schema:
type: object
properties:
npmName:
type: string
example: peertube-plugin-auth-ldap
required:
- npmName
responses:
'204':
'404':
/api/v1/plugins/{npmName}:
get:
tags:
- Plugins
summary: Get a plugin
operationId: getPlugin
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/npmName'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Plugin'
'404':
/api/v1/plugins/{npmName}/settings:
put:
tags:
- Plugins
summary: Set a plugin's settings
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/npmName'
requestBody:
content:
application/json:
schema:
type: object
properties:
settings:
type: object
additionalProperties: true
responses:
'204':
'404':
/api/v1/plugins/{npmName}/public-settings:
get:
tags:
- Plugins
summary: Get a plugin's public settings
parameters:
- $ref: '#/components/parameters/npmName'
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: true
'404':
/api/v1/plugins/{npmName}/registered-settings:
get:
tags:
- Plugins
summary: Get a plugin's registered settings
security:
- OAuth2:
- admin
parameters:
- $ref: '#/components/parameters/npmName'
responses:
'200':
content:
application/json:
schema:
type: object
additionalProperties: true
'404':
/api/v1/metrics/playback:
post:
summary: Create playback metrics
tags:
- Stats
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PlaybackMetricCreate'
responses:
'204':
/api/v1/runners/registration-tokens/generate:
post:
summary: Generate registration token
security:
- OAuth2:
- admin
tags:
- Runner Registration Token
responses:
'204':
/api/v1/runners/registration-tokens/{registrationTokenId}:
delete:
summary: Remove registration token
security:
- OAuth2:
- admin
tags:
- Runner Registration Token
parameters:
- $ref: '#/components/parameters/registrationTokenId'
responses:
'204':
/api/v1/runners/registration-tokens:
get:
summary: List registration tokens
security:
- OAuth2:
- admin
tags:
- Runner Registration Token
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/registrationTokenSort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/RunnerRegistrationToken'
/api/v1/runners/register:
post:
summary: Register a new runner
tags:
- Runners
requestBody:
content:
application/json:
schema:
type: object
properties:
registrationToken:
type: string
name:
type: string
type: string
required:
- registrationToken
- name
responses:
'200':
content:
application/json:
schema:
type: object
properties:
id:
type: integer
runnerToken:
type: string
/api/v1/runners/unregister:
post:
summary: Unregister a runner
tags:
- Runners
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
required:
- runnerToken
responses:
'204':
/api/v1/runners/{runnerId}:
delete:
summary: Delete a runner
security:
- OAuth2:
- admin
tags:
- Runners
parameters:
- $ref: '#/components/parameters/runnerId'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
required:
- runnerToken
responses:
'204':
/api/v1/runners:
get:
summary: List runners
security:
- OAuth2:
- admin
tags:
- Runners
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/runnerSort'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/Runner'
/api/v1/runners/jobs/request:
post:
summary: Request a new job
tags:
- Runner Jobs
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobTypes:
type: array
items:
type: string
required:
- runnerToken
responses:
'200':
content:
application/json:
schema:
type: object
properties:
availableJobs:
type: array
items:
type: object
properties:
uuid:
$ref: '#/components/schemas/UUIDv4'
type:
$ref: '#/components/schemas/RunnerJobType'
payload:
$ref: '#/components/schemas/RunnerJobPayload'
/api/v1/runners/jobs/{jobUUID}/accept:
post:
summary: Accept job
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
required:
- runnerToken
responses:
'200':
content:
application/json:
schema:
type: object
properties:
job:
allOf:
- $ref: '#/components/schemas/RunnerJob'
- type: object
properties:
jobToken:
type: string
/api/v1/runners/jobs/{jobUUID}/abort:
post:
summary: Abort job
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
reason:
type: string
required:
- runnerToken
- jobToken
- reason
responses:
'204':
/api/v1/runners/jobs/{jobUUID}/update:
post:
summary: Update job
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
progress:
type: integer
payload:
anyOf:
- type: object
properties:
type:
type: string
enum:
- 'add-chunk'
- 'remove-chunk'
masterPlaylistFile:
type: string
format: binary
resolutionPlaylistFile:
type: string
format: binary
resolutionPlaylistFilename:
type: string
videoChunkFile:
type: string
format: binary
videoChunkFilename:
type: string
required:
- runnerToken
- jobToken
responses:
'204':
/api/v1/runners/jobs/{jobUUID}/error:
post:
summary: Post job error
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
message:
type: string
required:
- runnerToken
- jobToken
- message
responses:
'204':
/api/v1/runners/jobs/{jobUUID}/success:
post:
summary: Post job success
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
requestBody:
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
payload:
anyOf:
- type: object
title: VOD web video transcoding
properties:
videoFile:
type: string
format: binary
- type: object
title: VOD HLS transcoding
properties:
videoFile:
type: string
format: binary
resolutionPlaylistFile:
type: string
format: binary
- type: object
title: VOD audio merge transcoding
properties:
videoFile:
type: string
format: binary
- type: object
title: Live RTMP to HLS transcoding
required:
- runnerToken
- jobToken
- payload
responses:
'204':
/api/v1/runners/jobs/{jobUUID}/files/videos/{videoIdOrUUID}/max-quality/audio:
post:
summary: Download the max-quality audio file for a job video
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
- $ref: '#/components/parameters/videoIdOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
required:
- runnerToken
- jobToken
responses:
'200':
content:
application/octet-stream:
schema:
type: string
format: binary
'403':
/api/v1/runners/jobs/{jobUUID}/files/videos/{videoIdOrUUID}/max-quality:
post:
summary: Download the max-quality video file for a job video
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
- $ref: '#/components/parameters/videoIdOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
required:
- runnerToken
- jobToken
responses:
'200':
content:
application/octet-stream:
schema:
type: string
format: binary
'403':
/api/v1/runners/jobs/{jobUUID}/files/videos/{videoIdOrUUID}/thumbnails/max-quality:
post:
summary: Download the max-quality thumbnail for a job video
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
- $ref: '#/components/parameters/videoIdOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
required:
- runnerToken
- jobToken
responses:
'200':
content:
application/octet-stream:
schema:
type: string
format: binary
'403':
/api/v1/runners/jobs/{jobUUID}/files/videos/{videoIdOrUUID}/previews/max-quality:
post:
summary: Download the max-quality preview for a job video
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
- $ref: '#/components/parameters/videoIdOrUUID'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
required:
- runnerToken
- jobToken
responses:
'200':
content:
application/octet-stream:
schema:
type: string
format: binary
'403':
/api/v1/runners/jobs/{jobUUID}/files/videos/{videoIdOrUUID}/studio/task-files/{filename}:
post:
summary: Download a video studio task file for a job video
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
- $ref: '#/components/parameters/videoIdOrUUID'
- name: filename
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
runnerToken:
type: string
jobToken:
type: string
required:
- runnerToken
- jobToken
responses:
'200':
content:
application/octet-stream:
schema:
type: string
format: binary
'400':
'403':
/api/v1/runners/jobs/{jobUUID}/cancel:
post:
summary: Cancel a job
security:
- OAuth2:
- admin
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
responses:
'204':
/api/v1/runners/jobs/{jobUUID}:
delete:
summary: Delete a job
security:
- OAuth2:
- admin
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/jobUUID'
responses:
'204':
/api/v1/runners/jobs:
get:
summary: List jobs
security:
- OAuth2:
- admin
tags:
- Runner Jobs
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/runnerJobSort'
- $ref: '#/components/parameters/search'
- name: stateOneOf
in: query
required: false
schema:
type: array
items:
$ref: '#/components/schemas/RunnerJobState'
- name: typeOneOf
in: query
required: false
schema:
type: array
items:
$ref: '#/components/schemas/RunnerJobType'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/RunnerJobAdmin'
/api/v1/automatic-tags/policies/accounts/{accountName}/comments:
get:
tags:
- Automatic Tags
summary: Get account auto tag policies on comments
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CommentAutoTagPolicies'
put:
tags:
- Automatic Tags
summary: Update account auto tag policies on comments
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
review:
type: array
items:
type: string
responses:
'204':
/api/v1/automatic-tags/accounts/{accountName}/available:
get:
tags:
- Automatic Tags
summary: Get account available auto tags
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AutomaticTagAvailable'
/api/v1/automatic-tags/server/available:
get:
tags:
- Automatic Tags
summary: Get server available auto tags
security:
- OAuth2:
- admin
- moderator
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/AutomaticTagAvailable'
/api/v1/automatic-tags/policies/server/videos:
get:
tags:
- Automatic Tags
summary: Get server auto tag policies for videos
security:
- OAuth2:
- admin
- moderator
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/VideoAutoTagPolicies'
put:
tags:
- Automatic Tags
summary: Update server auto tag policies for videos
security:
- OAuth2:
- admin
- moderator
requestBody:
content:
application/json:
schema:
type: object
properties:
autoBlock:
type: array
items:
type: string
responses:
'204':
/api/v1/watched-words/accounts/{accountName}/lists:
get:
tags:
- Watched Words
summary: List account watched words
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/WatchedWordsLists'
post:
tags:
- Watched Words
summary: Add account watched words
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
listName:
type: string
words:
type: array
items:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
watchedWordsList:
type: object
properties:
id:
type: integer
/api/v1/watched-words/accounts/{accountName}/lists/{listId}:
put:
tags:
- Watched Words
summary: Update account watched words
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
- name: listId
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
listName:
type: string
words:
type: array
items:
type: string
responses:
'204':
delete:
tags:
- Watched Words
summary: Delete account watched words
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
- name: listId
in: path
required: true
schema:
type: string
responses:
'204':
/api/v1/watched-words/server/lists:
get:
tags:
- Watched Words
summary: List server watched words
security:
- OAuth2:
- admin
- moderator
responses:
'200':
content:
application/json:
schema:
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/WatchedWordsLists'
post:
tags:
- Watched Words
summary: Add server watched words
security:
- OAuth2:
- admin
- moderator
requestBody:
content:
application/json:
schema:
type: object
properties:
listName:
type: string
words:
type: array
items:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
watchedWordsList:
type: object
properties:
id:
type: integer
/api/v1/watched-words/server/lists/{listId}:
put:
tags:
- Watched Words
summary: Update server watched words
security:
- OAuth2:
- admin
- moderator
parameters:
- name: listId
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
listName:
type: string
words:
type: array
items:
type: string
responses:
'204':
delete:
tags:
- Watched Words
summary: Delete server watched words
security:
- OAuth2:
- admin
- moderator
parameters:
- name: listId
in: path
required: true
schema:
type: string
responses:
'204':
/api/v1/watched-words/accounts/{accountName}/subscriptions:
get:
tags:
- Watched Words
summary: List account watched words subscriptions
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/WatchedWordsSubscription'
post:
tags:
- Watched Words
summary: Add account watched words subscription
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: url
required:
- url
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WatchedWordsSubscription'
'400':
'409':
/api/v1/watched-words/accounts/{accountName}/subscriptions/{id}:
delete:
tags:
- Watched Words
summary: Delete account watched words subscription
security:
- OAuth2: []
parameters:
- name: accountName
in: path
required: true
schema:
type: string
- name: id
in: path
required: true
schema:
type: integer
responses:
'204':
'404':
/api/v1/watched-words/server/subscriptions:
get:
tags:
- Watched Words
summary: List server watched words subscriptions
security:
- OAuth2:
- admin
- moderator
parameters:
- $ref: '#/components/parameters/start'
- $ref: '#/components/parameters/count'
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/search'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/WatchedWordsSubscription'
post:
tags:
- Watched Words
summary: Add server watched words subscription
security:
- OAuth2:
- admin
- moderator
requestBody:
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: url
required:
- url
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/WatchedWordsSubscription'
'400':
'409':
/api/v1/watched-words/server/subscriptions/{id}:
delete:
tags:
- Watched Words
summary: Delete server watched words subscription
security:
- OAuth2:
- admin
- moderator
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'204':
'404':
/api/v1/client-config/update-language:
post:
tags:
- Client Config
summary: Update client language
operationId: updateClientLanguage
deprecated: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
language:
type: string
nullable: true
example: 'en-US'
required:
- language
responses:
'204':
/api/v1/client-config/update-interface-language:
post:
tags:
- Client Config
summary: Update client language
operationId: updateClientInterfaceLanguage
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
language:
type: string
nullable: true
example: 'en-US'
required:
- language
responses:
'204':
/api/v1/video-channels/{channelHandle}/collaborators:
get:
tags:
- Video Channels
summary: List channel collaborators
operationId: listVideoChannelCollaborators
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
responses:
'200':
content:
application/json:
schema:
type: object
properties:
total:
type: integer
example: 1
data:
type: array
items:
$ref: '#/components/schemas/VideoChannelCollaborator'
/api/v1/video-channels/{channelHandle}/collaborators/invite:
post:
tags:
- Video Channels
summary: Invite a collaborator
operationId: inviteVideoChannelCollaborator
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
accountHandle:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
properties:
collaborator:
$ref: '#/components/schemas/VideoChannelCollaborator'
/api/v1/video-channels/{channelHandle}/collaborators/{collaboratorId}/accept:
post:
tags:
- Video Channels
summary: Accept a collaboration invitation
operationId: acceptVideoChannelCollaborator
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/collaboratorId'
responses:
'204':
/api/v1/video-channels/{channelHandle}/collaborators/{collaboratorId}/reject:
post:
tags:
- Video Channels
summary: Reject a collaboration invitation
operationId: rejectVideoChannelCollaborator
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/collaboratorId'
responses:
'204':
/api/v1/video-channels/{channelHandle}/collaborators/{collaboratorId}:
delete:
tags:
- Video Channels
summary: Remove a channel collaborator
operationId: removeVideoChannelCollaborator
security:
- OAuth2: []
parameters:
- $ref: '#/components/parameters/channelHandle'
- $ref: '#/components/parameters/collaboratorId'
responses:
'204':
servers:
url: 'https://peertube2.cpy.re'
url: 'https://peertube3.cpy.re'
url: 'https://peertube.cpy.re'
components:
parameters:
start:
name: start
in: query
required: false
schema:
type: integer
minimum: 0
count:
name: count
in: query
required: false
schema:
type: integer
default: 15
maximum: 100
minimum: 1
sort:
name: sort
in: query
required: false
schema:
type: string
example: -createdAt
search:
name: search
in: query
required: false
schema:
type: string
searchTarget:
name: searchTarget
in: query
required: false
If the administrator enabled search index support, you can override the default search target.
Warning: If you choose to make an index search, PeerTube will get results from a third party service.
It means the instance may not yet know the objects you fetched. If you want to load video/channel information:
* If the current user has the ability to make a remote URI search (this information is available in the config endpoint),
then reuse the search API to make a search using the object URI so PeerTube instance fetches the remote object and fill its database.
After that, you can use the classic REST API endpoints to fetch the complete object or interact with it
* If the current user doesn't have the ability to make a remote URI search, then redirect the user on the origin instance or fetch
the data from the origin instance API
schema:
type: string
enum:
- 'local'
- 'search-index'
mySubscriptionSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- -id
- -createdAt
- -channelUpdatedAt
videosSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- name
- -duration
- -createdAt
- -publishedAt
- -views
- -likes
- -comments
- -trending
- -hot
- -best
Sort videos by criteria (prefixing with-meansDESCorder):
*hot- Adaptation of Reddit "hot" algorithm taking into account video views, likes, dislikes and comments and publication date
*best- Same thanhot, but also takes into account user video history
*trending- Sort videos by recent views ("recent" is defined by the admin)
*views- Sort videos using theirviewscounter
*publishedAt- Sort by video publication date (when it became publicly available)
videosSearchSort:
name: sort
in: query
required: false
Sort videos by criteria (prefixing with-meansDESCorder):
schema:
type: string
enum:
- name
- -duration
- -createdAt
- -publishedAt
- -views
- -likes
- -match
commentsSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- -createdAt
- -totalReplies
blacklistsSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- -id
- name
- -duration
- -views
- -likes
- -dislikes
- -uuid
- -createdAt
usersSearch:
name: search
in: query
required: false
schema:
type: string
usersBlocked:
name: blocked
in: query
required: false
schema:
type: boolean
usersRole:
name: role
in: query
required: false
schema:
$ref: '#/components/schemas/UserRole'
usersSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- -id
- -username
- -createdAt
abusesSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- -id
- -createdAt
- -state
videoRedundanciesSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- name
followersSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- createdAt
registrationTokenSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- createdAt
runnerSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- createdAt
runnerJobSort:
name: sort
in: query
required: false
schema:
type: string
enum:
- updatedAt
- createdAt
- priority
- state
- progressname:
name: name
in: path
required: true
schema:
type: string
example: chocobozzz | [email protected]
id:
name: id
in: path
required: true
schema:
$ref: '#/components/schemas/id'
tokenSessionId:
name: tokenSessionId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
userId:
name: userId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
registrationId:
name: registrationId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
idOrUUID:
name: id
in: path
required: true
schema:
oneOf:
- $ref: '#/components/schemas/id'
- $ref: '#/components/schemas/UUIDv4'
- $ref: '#/components/schemas/shortUUID'
playlistId:
name: playlistId
in: path
required: true
schema:
$ref: '#/components/schemas/VideoPlaylist/properties/id'
videoIdOrUUID:
name: videoIdOrUUID
in: path
required: true
schema:
oneOf:
- $ref: '#/components/schemas/id'
- $ref: '#/components/schemas/UUIDv4'
- $ref: '#/components/schemas/shortUUID'
playlistElementId:
name: playlistElementId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
abuseId:
name: abuseId
in: path
required: true
schema:
$ref: '#/components/schemas/Abuse/properties/id'
abuseMessageId:
name: abuseMessageId
in: path
required: true
schema:
$ref: '#/components/schemas/AbuseMessage/properties/id'
captionLanguage:
name: captionLanguage
in: path
required: true
schema:
$ref: '#/components/schemas/VideoLanguageSet'
channelHandle:
name: channelHandle
in: path
required: true
schema:
type: string
example: my_username | [email protected]
channelSyncId:
name: channelSyncId
in: path
required: true
schema:
$ref: '#/components/schemas/Abuse/properties/id'
subscriptionHandle:
name: subscriptionHandle
in: path
required: true
schema:
type: string
example: my_username | [email protected]
threadId:
name: threadId
in: path
required: true
schema:
type: integer
commentId:
name: commentId
in: path
required: true
schema:
$ref: '#/components/schemas/VideoComment/properties/id'
commentMaxDepth:
name: maxDepth
in: query
required: false
Number of nesting levels to include below the requested comment.
Bounded byrepliesPerLevelandcount, see the note onrepliesPerLevel
schema:
type: integer
minimum: 1
maximum: 10
default: 5
commentRepliesPerLevel:
name: repliesPerLevel
in: query
required: false
Number of direct replies to include for each comment of the tree. Does not apply to the first level ofGET /api/v1/videos/{id}/comments/{commentId}/replies, which is paginated usingstartandcount.
A tree can make the server walk throughcount * (repliesPerLevel ^ maxDepth - 1) / (repliesPerLevel - 1)comments, which grows exponentially.
Combinations above 2000000 are rejected
A deep tree has to be narrow and a wide tree has to be shallow.
schema:
type: integer
minimum: 1
maximum: 30
default: 10
commentRepliesSort:
name: sort
in: query
required: false
Sort the direct replies of the comment. Deeper levels of the tree are always sorted the same way.
Defaults tocreatedAtso the replies are appended to the thread tree in the order it was built
schema:
type: string
default: createdAt
enum:
- createdAt
- -createdAt
isLive:
name: isLive
in: query
required: false
schema:
type: boolean
includeScheduledLive:
name: includeScheduledLive
in: query
required: false
schema:
type: boolean
categoryOneOf:
name: categoryOneOf
in: query
required: false
schema:
oneOf:
- $ref: '#/components/schemas/VideoCategorySet'
- type: array
items:
$ref: '#/components/schemas/VideoCategorySet'
style: form
explode: true
tagsOneOf:
name: tagsOneOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
maxItems: 5
items:
type: string
style: form
explode: true
tagsAllOf:
name: tagsAllOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
items:
type: string
style: form
explode: true
languageOneOf:
name: languageOneOf
in: query
required: false
schema:
oneOf:
- $ref: '#/components/schemas/VideoLanguageSet'
- type: array
items:
$ref: '#/components/schemas/VideoLanguageSet'
style: form
explode: true
autoTagOneOfVideo:
name: autoTagOneOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
items:
type: string
style: form
explode: true
stateOneOfVideo:
name: stateOneOf
in: query
required: false
schema:
oneOf:
- $ref: '#/components/schemas/VideoStateConstant/properties/id'
- type: array
items:
$ref: '#/components/schemas/VideoStateConstant/properties/id'
style: form
explode: true
channelNameOneOf:
name: channelNameOneOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
items:
type: string
style: form
explode: true
autoTagOneOfComment:
name: autoTagOneOf
in: query
required: false
schema:
oneOf:
- type: string
- type: array
items:
type: string
style: form
explode: true
isHeldForReview:
name: isHeldForReview
in: query
required: false
schema:
type: boolean
licenceOneOf:
name: licenceOneOf
in: query
required: false
schema:
oneOf:
- $ref: '#/components/schemas/VideoLicenceSet'
- type: array
items:
$ref: '#/components/schemas/VideoLicenceSet'
style: form
explode: true
skipCount:
name: skipCount
in: query
required: false
schema:
type: string
enum:
- 'true'
- 'false'
default: 'false'
nsfw:
name: nsfw
in: query
required: false
schema:
type: string
enum:
- 'true'
- 'false'
nsfwFlagsIncluded:
name: nsfwFlagsIncluded
in: query
required: false
schema:
$ref: '#/components/schemas/NSFWFlag'
nsfwFlagsExcluded:
name: nsfwFlagsExcluded
in: query
required: false
schema:
$ref: '#/components/schemas/NSFWFlag'
aiUsageOneOf:
name: aiUsageOneOf
in: query
required: false
PeerTube >= 9.0 Only list videos with one of these AI usages, declared by video creators.
If not provided, the preference of the authenticated user (aiUsagesHidden) is used
schema:
oneOf:
- $ref: '#/components/schemas/VideoAIUsageSet'
- type: array
items:
$ref: '#/components/schemas/VideoAIUsageSet'
style: form
explode: true
isLocal:
name: isLocal
in: query
required: false
schema:
type: boolean
hasHLSFiles:
name: hasHLSFiles
in: query
required: false
schema:
type: boolean
hasWebVideoFiles:
name: hasWebVideoFiles
in: query
required: false
schema:
type: boolean
privacyOneOf:
name: privacyOneOf
in: query
required: false
schema:
$ref: '#/components/schemas/VideoPrivacySet'
excludeAlreadyWatched:
name: excludeAlreadyWatched
in: query
schema:
type: boolean
uuids:
name: uuids
in: query
required: false
schema:
items:
type: string
host:
name: host
in: query
required: false
schema:
type: string
handles:
name: handles
in: query
required: false
schema:
items:
type: string
include:
name: include
in: query
required: false
schema:
type: integer
enum:
- 0
- 1
- 2
- 4
- 8
- 16
- 32
Only administrators and moderators can use this parameter
Include additional videos in results (can be combined using bitwise or operator)
-0NONE
-1NOT_PUBLISHED_STATE
-2BLACKLISTED
-4BLOCKED_OWNER
-8FILES
-16CAPTIONS
-32VIDEO SOURCE
subscriptionsUris:
name: uris
in: query
required: true
schema:
type: array
items:
type: string
format: uri
npmName:
name: npmName
in: path
required: true
schema:
type: string
example: peertube-plugin-auth-ldap
jobType:
name: jobType
in: query
required: false
schema:
$ref: '#/components/schemas/JobType'
followState:
name: state
in: query
schema:
type: string
enum:
- pending
- accepted
actorType:
name: actorType
in: query
schema:
type: string
enum:
- Person
- Application
- Group
- Service
- Organization
staticFilename:
name: filename
in: path
required: true
schema:
type: string
videoFileToken:
name: videoFileToken
in: query
required: false
schema:
type: string
reinjectVideoFileToken:
name: reinjectVideoFileToken
in: query
required: false
schema:
type: boolean
videoPlaylistType:
name: playlistType
in: query
required: false
schema:
$ref: '#/components/schemas/VideoPlaylistTypeSet'
registrationTokenId:
name: registrationTokenId
in: path
required: true
schema:
type: integer
runnerId:
name: runnerId
in: path
required: true
schema:
type: integer
jobUUID:
name: jobUUID
in: path
required: true
schema:
$ref: '#/components/schemas/UUIDv4'
passwordId:
name: passwordId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
onLocalVideo:
name: onLocalVideo
in: query
required: false
schema:
type: boolean
includeMuted:
name: includeMuted
in: query
required: false
schema:
type: boolean
videoChannelId:
name: videoChannelId
in: query
required: false
schema:
type: integer
videoId:
name: videoId
in: query
required: false
schema:
type: integer
searchVideoForComments:
name: searchVideo
in: query
required: false
schema:
type: string
searchAccountForComments:
name: searchAccount
in: query
required: false
schema:
type: string
videoPasswordHeader:
name: x-peertube-video-password
in: header
required: false
schema:
type: string
resumableUploadInitContentLengthHeader:
name: X-Upload-Content-Length
in: header
schema:
type: number
example: 2469036
required: true
resumableUploadInitContentTypeHeader:
name: X-Upload-Content-Type
in: header
schema:
type: string
format: mimetype
example: video/mp4
required: true
resumableUploadChunkContentRangeHeader:
name: Content-Range
in: header
schema:
type: string
example: bytes 0-262143/2469036
required: true
Specifies the bytes in the file that the request is uploading.
For example, a value ofbytes 0-262143/1000000shows that the request is sending the first
262144 bytes (256 x 1024) in a 2,469,036 byte file.
When the server configclient.videos.resumableUpload.minChunkSize(video uploads) orimport.users.resumableUpload.minChunkSize(user archive imports) is not0,
every chunk except the last one must be at least that big. It must also be at least 1/10,000 of the file size
(the maximum number of object storage multipart upload parts).
resumableUploadChunkContentLengthHeader:
name: Content-Length
in: header
schema:
type: number
example: 262144
required: true
Size of the chunk that the request is sending.
Remember that larger chunks are more efficient. PeerTube's web client uses chunks varying from
1048576 bytes (~1MB) and increases or reduces size depending on connection health.
resumableUploadId:
name: upload_id
in: query
required: true
Created session id to proceed with. If you didn't send chunks in the last hour, it is
not valid anymore and you need to initialize a new upload.
schema:
type: string
logoTypeParam:
name: logoType
in: path
required: true
schema:
type: string
enum:
- 'favicon'
- 'header-wide'
- 'header-square'
- 'opengraph'
includeCollaborations:
name: includeCollaborations
in: query
required: false
schema:
type: boolean
collaboratorId:
name: collaboratorId
in: path
required: true
schema:
$ref: '#/components/schemas/id'
securitySchemes:
OAuth2:
Authenticating via OAuth requires the following steps:
- Have an activated account
- [Generate] an access token for that account at /api/v1/users/token.
- Make requests with the Authorization: Bearer <token> header
- Profit, depending on the role assigned to the account
Note that the __access token is valid for 1 day__ and is given
along with a __refresh token valid for 2 weeks__.
[Generate]: https://docs.joinpeertube.org/api/rest-getting-started
type: oauth2
flows:
password:
tokenUrl: /api/v1/users/token
scopes:
admin: Admin scope
moderator: Moderator scope
user: User scope schemas:
# Reusable core properties
id:
type: integer
minimum: 1
example: 42
UUIDv4:
type: string
format: uuid
example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
minLength: 36
maxLength: 36
shortUUID:
type: string
example: 2y84q2MQUMWPbiEcxNXMgC
username:
type: string
example: chocobozzz
pattern: '/^[a-z0-9.]+$/'
minLength: 1
maxLength: 50
usernameChannel:
type: string
example: framasoft_videos
pattern: '/^[a-zA-Z0-9\-.:]+$/'
minLength: 1
maxLength: 50
password:
type: string
format: password
minLength: 6
maxLength: 50
VideoCategorySet:
type: integer
example: 15
VideoConstantNumber-Category:
properties:
id:
$ref: '#/components/schemas/VideoCategorySet'
label:
type: string
example: Science & Technology
VideoLicenceSet:
type: integer
example: 2
VideoConstantNumber-Licence:
properties:
id:
$ref: '#/components/schemas/VideoLicenceSet'
label:
type: string
example: Attribution - Share Alike
VideoLanguageSet:
type: string
example: en
VideoConstantString-Language:
properties:
id:
$ref: '#/components/schemas/VideoLanguageSet'
label:
type: string
example: English
VideoPlaylistPrivacySet:
type: integer
enum:
- 1
- 2
- 3
VideoPlaylistPrivacyConstant:
properties:
id:
$ref: '#/components/schemas/VideoPlaylistPrivacySet'
label:
type: string
VideoPlaylistTypeSet:
type: integer
enum:
- 1
- 2
VideoPlaylistTypeConstant:
properties:
id:
$ref: '#/components/schemas/VideoPlaylistTypeSet'
label:
type: string
VideoPrivacySet:
type: integer
enum:
- 1
- 2
- 3
- 4
- 5
VideoPrivacyConstant:
properties:
id:
$ref: '#/components/schemas/VideoPrivacySet'
label:
type: string
VideoCommentsPolicySet:
type: integer
enum:
- 1
- 2
- 3
VideoCommentsPolicyConstant:
properties:
id:
$ref: '#/components/schemas/VideoCommentsPolicySet'
label:
type: string
VideoRecommendationScopeSet:
type: integer
enum:
- 1
- 2
- 3
- 4
Videos that can be recommended next to a video:
- `1` All videos
- `2` Only videos of the platform that owns the reference video (or of the current platform if no video is given)
- `3` Only videos of the account that owns the reference video
- `4` Only videos of the channel of the reference video
This is a preference of the video owner: applications displaying recommendations may not apply it
VideoRecommendationScopeConstant:
properties:
id:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
label:
type: string
VideoAIUsageSet:
type: integer
enum:
- 1
- 2
- 3
- 4
**PeerTube >= 9.0** Use of AI in the video, declared by the video creator:
- `1` Not specified
- `2` No AI-generated content: nothing seen or heard in the video has been generated by AI
- `3` Contains AI-generated content: some parts of the video have been generated by AI
- `4` AI-generated: the whole video, or most of it, has been generated by AI
VideoAIUsageConstant:
properties:
id:
$ref: '#/components/schemas/VideoAIUsageSet'
label:
type: string
VideoCommercialContentSet:
type: integer
enum:
- 1
- 2
- 3
**PeerTube >= 9.0** Commercial content in the video, declared by the video creator:
- `1` None
- `2` Promotional content: the creator promotes their own products, services or business
- `3` Paid partnership: a third party paid, or provided goods or services, in exchange for the promotion
VideoCommercialContentConstant:
properties:
id:
$ref: '#/components/schemas/VideoCommercialContentSet'
label:
type: string
BlockStatus:
properties:
accounts:
type: object
additionalProperties:
x-additionalPropertiesName: account
type: object
properties:
blockedByServer:
type: boolean
blockedByServerSubscription:
type: string
blockedByUser:
type: boolean
hosts:
type: object
additionalProperties:
x-additionalPropertiesName: host
type: object
properties:
blockedByServer:
type: boolean
blockedByServerSubscription:
type: string
blockedByUser:
type: boolean
NSFWPolicy:
type: string
enum:
- display
- warn
- do_not_list
NSFWFlag:
type: integer
enum:
- 0
- 1
- 2
- 4
NSFW flags (can be combined using bitwise or operator)
- `0` NONE
- `1` VIOLENT
- `2` EXPLICIT_SEX
UserRole:
type: integer
enum:
- 0
- 1
- 2
example: 2
UserAdminFlags:
type: integer
enum:
- 0
- 1
example: 1
LiveVideoLatencyMode:
type: integer
enum:
- 1
- 2
- 3
LiveVideoReplaySettings:
type: object
properties:
privacy:
# description: Video playlist privacy policy (see [../video-playlists/privacies])
$ref: '#/components/schemas/VideoPrivacySet'
VideoChannelActivityAction:
type: integer
enum:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
The activity action:
- CREATE: 1
- UPDATE: 2
- DELETE: 3
- UPDATE_CAPTIONS: 4
- UPDATE_CHAPTERS: 5
- UPDATE_PASSWORDS: 6
- CREATE_STUDIO_TASKS: 7
- UPDATE_SOURCE_FILE: 8
- UPDATE_ELEMENTS: 9
- REMOVE_CHANNEL_OWNERSHIP: 10
- CREATE_CHANNEL_OWNERSHIP: 11
VideoChannelActivityTarget:
type: integer
enum:
- 1
- 2
- 3
- 4
- 5
The activity target:
- VIDEO: 1,
- PLAYLIST: 2,
- CHANNEL: 3,
- CHANNEL_SYNC: 4,
- VIDEO_IMPORT: 5
VideoStateConstant:
properties:
id:
type: integer
enum:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
The video state:
- `1`: Published
- `2`: To transcode
- `3`: To import
- `4`: Waiting for live stream
- `5`: Live ended
- `6`: To move to an external storage (object storage...)
- `7`: Transcoding failed
- `8`: Moving to an external storage failed
- `9`: To edit using studio edition feature
label:
type: string
UserExportState:
type: integer
enum:
- 1
- 2
- 3
- 4
The user export state:
- `1`: Pending
- `2`: Processing
- `3`: Completed
- `4`: Errored
UserImportState:
type: integer
enum:
- 1
- 2
- 3
- 4
The user import state:
- `1`: Pending
- `2`: Processing
- `3`: Completed
- `4`: Errored
AbuseStateSet:
type: integer
enum:
- 1
- 2
- 3
AbuseStateConstant:
properties:
id:
$ref: '#/components/schemas/AbuseStateSet'
label:
type: string
AbusePredefinedReasons:
type: array
items:
type: string
enum:
- violentOrAbusive
- hatefulOrAbusive
- spamOrMisleading
- privacy
- rights
- serverRules
- thumbnails
- captions
example: [spamOrMisleading]
VideoResolutionSet:
type: integer
Video resolution (`0`, `240`, `360`, `720`, `1080`, `1440` or `2160`)
`0` is used as a special value for stillimage videos dedicated to audio, a.k.a. audio-only videos.
example: 240
VideoResolutionConstant:
properties:
id:
$ref: '#/components/schemas/VideoResolutionSet'
label:
type: string
example: 240p
VideoScheduledUpdate:
properties:
privacy:
$ref: '#/components/schemas/VideoPrivacySet'
updateAt:
type: string
format: date-time
required:
- updateAt
AccountSummary:
properties:
id:
type: integer
name:
type: string
displayName:
type: string
url:
type: string
format: url
host:
type: string
format: hostname
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
VideoSummary:
properties:
id:
allOf:
- $ref: '#/components/schemas/id'
uuid:
allOf:
- $ref: '#/components/schemas/UUIDv4'
shortUUID:
allOf:
- $ref: '#/components/schemas/shortUUID'
name:
type: string
isLive:
type: boolean
nsfw:
type: boolean
publishedAt:
type: string
format: date-time
thumbnails:
type: array
items:
$ref: '#/components/schemas/Thumbnail'
channel:
$ref: '#/components/schemas/VideoChannelSummary'
VideoChannelSummary:
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
displayName:
type: string
url:
type: string
format: url
host:
type: string
format: hostname
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
PlaylistElement:
properties:
position:
type: integer
startTimestamp:
type: integer
format: seconds
stopTimestamp:
type: integer
format: seconds
video:
nullable: true
allOf:
- $ref: '#/components/schemas/Video'
Thumbnail:
properties:
fileUrl:
type: string
width:
type: integer
height:
type: integer
aspectRatio:
type: string
example: '16:9'
VideoFile:
properties:
id:
$ref: '#/components/schemas/id'
magnetUri:
type: string
format: uri
pattern: /magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i
resolution:
$ref: '#/components/schemas/VideoResolutionConstant'
size:
type: integer
torrentUrl:
type: string
format: url
torrentDownloadUrl:
type: string
format: url
fileUrl:
type: string
format: url
playlistUrl:
type: string
format: url
fileDownloadUrl:
type: string
format: url
fps:
type: number
width:
type: number
height:
type: number
metadataUrl:
type: string
format: url
hasAudio:
type: boolean
hasVideo:
type: boolean
storage:
$ref: '#/components/schemas/FileStorage'
VideoStreamingPlaylists:
allOf:
- type: object
properties:
id:
$ref: '#/components/schemas/id'
type:
type: integer
enum:
- 1
Playlist type:
- `1`: HLS
- $ref: '#/components/schemas/VideoStreamingPlaylists-HLS'
VideoStreamingPlaylists-HLS:
properties:
playlistUrl:
type: string
format: url
segmentsSha256Url:
type: string
format: url
files:
type: array
Video files associated to this playlist.
The difference with the root `files` property is that these files are fragmented, so they can be used in this streaming playlist (HLS, etc.)
items:
$ref: '#/components/schemas/VideoFile'
redundancies:
type: array
items:
type: object
properties:
baseUrl:
type: string
format: url
VideoInfo:
properties:
id:
$ref: '#/components/schemas/Video/properties/id'
uuid:
$ref: '#/components/schemas/Video/properties/uuid'
name:
$ref: '#/components/schemas/Video/properties/name'
state:
$ref: '#/components/schemas/Video/properties/state'
Video:
properties:
id:
allOf:
- $ref: '#/components/schemas/id'
uuid:
allOf:
- $ref: '#/components/schemas/UUIDv4'
shortUUID:
allOf:
- $ref: '#/components/schemas/shortUUID'
isLive:
type: boolean
liveSchedules:
type: array
items:
$ref: '#/components/schemas/LiveSchedule'
createdAt:
type: string
format: date-time
example: 2017-10-01T10:52:46.396Z
publishedAt:
type: string
format: date-time
example: 2018-10-01T10:52:46.396Z
updatedAt:
type: string
format: date-time
example: 2021-05-04T08:01:01.502Z
originallyPublishedAt:
type: string
nullable: true
format: date-time
example: 2010-10-01T10:52:46.396Z
category:
allOf:
- $ref: '#/components/schemas/VideoConstantNumber-Category'
licence:
allOf:
- $ref: '#/components/schemas/VideoConstantNumber-Licence'
language:
allOf:
- $ref: '#/components/schemas/VideoConstantString-Language'
privacy:
allOf:
- $ref: '#/components/schemas/VideoPrivacyConstant'
truncatedDescription:
type: string
nullable: true
example: |
**[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n
**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)**\r\n*A decentralized video hosting network, based on fr...
minLength: 3
maxLength: 250
truncated description of the video, written in Markdown.
duration:
type: integer
example: 1419
format: seconds
aspectRatio:
type: number
nullable: true
format: float
example: 1.778
isLocal:
type: boolean
name:
type: string
example: What is PeerTube?
minLength: 3
maxLength: 120
thumbnailPath:
deprecated: true
nullable: true
type: string
previewPath:
deprecated: true
nullable: true
type: string
thumbnails:
type: array
items:
$ref: '#/components/schemas/Thumbnail'
embedPath:
type: string
example: /videos/embed/a65bc12f-9383-462e-81ae-8207e8b434ee
views:
type: integer
example: 1337
likes:
type: integer
example: 42
dislikes:
type: integer
example: 7
comments:
type: integer
nsfw:
type: boolean
nsfwFlags:
allOf:
- $ref: '#/components/schemas/NSFWFlag'
nsfwSummary:
type: string
aiUsage:
$ref: '#/components/schemas/VideoAIUsageConstant'
commercialContent:
$ref: '#/components/schemas/VideoCommercialContentConstant'
recommendationScope:
$ref: '#/components/schemas/VideoRecommendationScopeConstant'
waitTranscoding:
type: boolean
nullable: true
state:
allOf:
- $ref: '#/components/schemas/VideoStateConstant'
scheduledUpdate:
nullable: true
allOf:
- $ref: '#/components/schemas/VideoScheduledUpdate'
blacklisted:
nullable: true
type: boolean
blacklistedReason:
nullable: true
type: string
account:
$ref: '#/components/schemas/AccountSummary'
channel:
$ref: '#/components/schemas/VideoChannelSummary'
userHistory:
nullable: true
type: object
properties:
currentTime:
type: integer
ServerError:
properties:
type:
type: string
format: uri-reference
URI identifying the error type. `about:blank` when the error has no specific type.
Otherwise it links to the corresponding section of the [Errors](#section/Errors) documentation;
the type name itself is also available in `code`.
example: 'https://docs.joinpeertube.org/api-rest-reference.html#section/Errors/video_requires_password'
detail:
type: string
example: 'Please provide a password to access this password protected video'
status:
type: integer
example: 403
code:
type: string
example: video_requires_password
VideoDetails:
allOf:
- $ref: '#/components/schemas/Video'
- type: object
properties:
viewers:
type: integer
type: string
nullable: true
example: |
"**[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n
**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)**\r\n*A decentralized video hosting network,
based on free/libre software!*\r\n\r\n**Animation Produced by:** [LILA](https://libreart.info) - [ZeMarmot Team](https://film.zemarmot.net)\r\n
*Directed by* Aryeom\r\n*Assistant* Jehan\r\n**Licence**: [CC-By-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)\r\n\r\n
**Sponsored by** [Framasoft](https://framasoft.org)\r\n\r\n**Music**: [Red Step Forward](http://play.dogmazic.net/song.php?song_id=52491) - CC-By Ken Bushima\r\n\r\n
**Movie Clip**: [Caminades 3: Llamigos](http://www.caminandes.com/) CC-By Blender Institute\r\n\r\n**Video sources**: https://gitlab.gnome.org/Jehan/what-is-peertube/"
minLength: 3
maxLength: 1000
full description of the video, written in Markdown.
support:
type: string
nullable: true
example: Please support our work on https://soutenir.framasoft.org/en/ <3
minLength: 3
maxLength: 1000
channel:
$ref: '#/components/schemas/VideoChannel'
account:
$ref: '#/components/schemas/Account'
tags:
example: [flowers, gardening]
type: array
minItems: 1
maxItems: 5
items:
type: string
minLength: 2
maxLength: 30
commentsPolicy:
$ref: '#/components/schemas/VideoCommentsPolicyConstant'
downloadEnabled:
type: boolean
inputFileUpdatedAt:
type: string
format: date-time
nullable: true
trackerUrls:
type: array
WebTorrent (`ws://` or `wss://`) and BitTorrent (`http://` or `https://`) trackers of the video
items:
type: string
format: url
example:
- https://peertube2.cpy.re/tracker/announce
- wss://peertube2.cpy.re/tracker/socket
files:
type: array
items:
$ref: '#/components/schemas/VideoFile'
Web compatible video files. If Web Video is disabled on the server:
- field will be empty
- video files will be found in `streamingPlaylists[].files` field
streamingPlaylists:
type: array
items:
$ref: '#/components/schemas/VideoStreamingPlaylists'
HLS playlists/manifest files. If HLS is disabled on the server:
- field will be empty
- video files will be found in `files` field
FileRedundancyInformation:
properties:
id:
$ref: '#/components/schemas/id'
fileUrl:
type: string
format: url
strategy:
type: string
enum:
- manual
- most-views
- trending
- recently-added
size:
type: integer
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
expiresOn:
type: string
format: date-time
VideoRedundancy:
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
url:
type: string
format: url
uuid:
$ref: '#/components/schemas/UUIDv4'
redundancies:
type: object
properties:
streamingPlaylists:
type: array
items:
$ref: '#/components/schemas/FileRedundancyInformation'
AccountBlock:
properties:
byAccount:
$ref: '#/components/schemas/Account'
blockedAccount:
$ref: '#/components/schemas/Account'
type: boolean
blocklistSubscription:
$ref: '#/components/schemas/BlocklistSubscriptionSummary'
nullable: true
createdAt:
type: string
format: date-time
ServerBlock:
properties:
byAccount:
$ref: '#/components/schemas/Account'
blockedServer:
type: object
properties:
host:
type: string
format: hostname
blocklistSubscription:
$ref: '#/components/schemas/BlocklistSubscriptionSummary'
nullable: true
createdAt:
type: string
format: date-time
BlocklistSubscription:
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
url:
type: string
format: url
mutedAccountsCount:
type: integer
minimum: 0
mutedServersCount:
type: integer
minimum: 0
lastSyncAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
BlocklistSubscriptionSummary:
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
url:
type: string
format: url
BlocklistLog:
properties:
id:
$ref: '#/components/schemas/id'
action:
type: string
enum:
- add
- delete
target:
type: string
createdAt:
type: string
format: date-time
AutoMuteList:
properties:
name:
type: string
actions:
type: array
items:
type: object
properties:
type:
type: string
enum:
- block
- unblock
target:
type: string
createdAt:
type: string
format: date-time
CommentAutoTagPolicies:
properties:
review:
type: array
items:
type: string
VideoAutoTagPolicies:
properties:
autoBlock:
type: array
items:
type: string
AutomaticTagAvailable:
properties:
available:
type: array
items:
type: object
properties:
name:
type: string
type:
type: string
enum:
- 'core'
- 'watched-words-list'
VideoImportStateConstant:
properties:
id:
type: integer
enum:
- 1
- 2
- 3
- 4
- 5
- 6
The video import state (Pending = `1`, Success = `2`, Failed = `3`, Rejected = `4`, Cancelled = `5`,
Processing = `6`)
label:
type: string
example: Pending
VideoCreateImport:
allOf:
- type: object
additionalProperties: false
oneOf:
- properties:
targetUrl:
$ref: '#/components/schemas/VideoImport/properties/targetUrl'
required: [targetUrl]
- properties:
magnetUri:
$ref: '#/components/schemas/VideoImport/properties/magnetUri'
required: [magnetUri]
- properties:
torrentfile:
$ref: '#/components/schemas/VideoImport/properties/torrentfile'
required: [torrentfile]
- $ref: '#/components/schemas/VideoUploadRequestCommon'
required:
- channelId
- name
VideoImport:
properties:
id:
$ref: '#/components/schemas/id'
targetUrl:
type: string
format: url
example: https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d
magnetUri:
type: string
format: uri
pattern: /magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i
torrentfile:
type: string
format: binary
torrentName:
type: string
state:
allOf:
- $ref: '#/components/schemas/VideoImportStateConstant'
error:
type: string
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
video:
nullable: true
allOf:
- $ref: '#/components/schemas/Video'
VideoImportsList:
properties:
total:
type: integer
example: 1
data:
type: array
maxItems: 100
items:
$ref: '#/components/schemas/VideoImport'
Abuse:
properties:
id:
$ref: '#/components/schemas/id'
reason:
type: string
example: The video is a spam
minLength: 2
maxLength: 3000
predefinedReasons:
$ref: '#/components/schemas/AbusePredefinedReasons'
reporterAccount:
$ref: '#/components/schemas/Account'
state:
$ref: '#/components/schemas/AbuseStateConstant'
moderationComment:
type: string
example: Decided to ban the server since it spams us regularly
minLength: 2
maxLength: 3000
video:
type: object
properties:
id:
type: integer
uuid:
$ref: '#/components/schemas/UUIDv4'
shortUUID:
$ref: '#/components/schemas/shortUUID'
name:
type: string
nsfw:
type: boolean
startAt:
type: string
format: date-time
endAt:
type: string
format: date-time
deleted:
type: boolean
blacklisted:
type: boolean
thumbnailPath:
deprecated: true
nullable: true
type: string
thumbnails:
type: array
items:
$ref: '#/components/schemas/Thumbnail'
channel:
$ref: '#/components/schemas/VideoChannel'
createdAt:
type: string
format: date-time
AbuseMessage:
properties:
id:
$ref: '#/components/schemas/id'
message:
type: string
minLength: 2
maxLength: 3000
byModerator:
type: boolean
createdAt:
type: string
format: date-time
account:
$ref: '#/components/schemas/AccountSummary'
VideoBlacklist:
type: object
properties:
id:
$ref: '#/components/schemas/id'
reason:
type: string
internalNote:
type: string
unfederated:
type: boolean
type:
type: integer
- `1`: manual block
- `2`: automatic block by instance policy
- `3`: automatic block by auto-tag policy
video:
$ref: '#/components/schemas/Video'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
VideoBlacklistCreate:
type: object
properties:
reason:
type: string
unfederate:
type: boolean
internalNote:
type: string
VideoBlacklistUpdate:
type: object
properties:
reason:
type: string
internalNote:
type: string
ChangeOwnership:
type: object
properties:
id:
$ref: '#/components/schemas/id'
state:
properties:
id:
$ref: '#/components/schemas/ChangeOwnershipState'
label:
type: string
initiatorAccount:
$ref: '#/components/schemas/Account'
nextOwnerAccount:
$ref: '#/components/schemas/Account'
video:
$ref: '#/components/schemas/VideoSummary'
videoChannel:
$ref: '#/components/schemas/VideoChannelSummary'
createdAt:
type: string
format: date-time
VideoPlaylist:
properties:
id:
$ref: '#/components/schemas/id'
uuid:
$ref: '#/components/schemas/UUIDv4'
shortUUID:
allOf:
- $ref: '#/components/schemas/shortUUID'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
type: string
minLength: 3
maxLength: 1000
displayName:
type: string
minLength: 1
maxLength: 120
isLocal:
type: boolean
videoLength:
type: integer
minimum: 0
thumbnailPath:
deprecated: true
nullable: true
type: string
thumbnails:
type: array
items:
$ref: '#/components/schemas/Thumbnail'
privacy:
$ref: '#/components/schemas/VideoPlaylistPrivacyConstant'
type:
$ref: '#/components/schemas/VideoPlaylistTypeConstant'
ownerAccount:
$ref: '#/components/schemas/AccountSummary'
videoChannel:
$ref: '#/components/schemas/VideoChannelSummary'
videoChannelPosition:
type: integer
minimum: 1
VideoComment:
properties:
id:
$ref: '#/components/schemas/id'
url:
type: string
format: url
text:
type: string
format: html
minLength: 1
example: This video is wonderful!
threadId:
$ref: '#/components/schemas/id'
inReplyToCommentId:
nullable: true
allOf:
- $ref: '#/components/schemas/id'
videoId:
$ref: '#/components/schemas/Video/properties/id'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
deletedAt:
nullable: true
type: string
format: date-time
default: null
isDeleted:
type: boolean
default: false
heldForReview:
type: boolean
totalRepliesFromVideoAuthor:
type: integer
minimum: 0
totalReplies:
type: integer
minimum: 0
account:
$ref: '#/components/schemas/Account'
VideoCommentThreadTree:
properties:
comment:
$ref: '#/components/schemas/VideoComment'
children:
type: array
Direct replies of `comment`. The server truncates the tree in depth (see the `maxDepth` parameter) and in
width, so this array may contain less elements than `totalChildren`. Missing replies can be fetched using
`GET /api/v1/videos/{id}/comments/{commentId}/replies`
items:
$ref: '#/components/schemas/VideoCommentThreadTree'
totalChildren:
type: integer
minimum: 0
VideoCommentForOwnerOrAdmin:
properties:
id:
$ref: '#/components/schemas/id'
url:
$ref: '#/components/schemas/VideoComment/properties/url'
text:
$ref: '#/components/schemas/VideoComment/properties/text'
heldForReview:
$ref: '#/components/schemas/VideoComment/properties/heldForReview'
threadId:
$ref: '#/components/schemas/VideoComment/properties/threadId'
inReplyToCommentId:
$ref: '#/components/schemas/VideoComment/properties/inReplyToCommentId'
createdAt:
$ref: '#/components/schemas/VideoComment/properties/createdAt'
updatedAt:
$ref: '#/components/schemas/VideoComment/properties/updatedAt'
account:
$ref: '#/components/schemas/VideoComment/properties/account'
video:
$ref: '#/components/schemas/VideoInfo'
automaticTags:
type: array
items:
type: string
Storyboard:
properties:
storyboardPath:
deprecated: true
nullable: true
type: string
fileUrl:
type: string
totalHeight:
type: integer
totalWidth:
type: integer
spriteHeight:
type: integer
spriteWidth:
type: integer
spriteDuration:
type: integer
VideoCaption:
properties:
language:
$ref: '#/components/schemas/VideoConstantString-Language'
automaticallyGenerated:
type: boolean
captionPath:
type: string
deprecated: true
nullable: true
fileUrl:
type: string
m3u8Url:
type: string
updatedAt:
type: string
format: date-time
VideoChapters:
properties:
chapters:
type: object
properties:
title:
type: string
timecode:
type: integer
VideoSource:
properties:
inputFilename:
type: string
fileDownloadUrl:
type: string
resolution:
allOf:
- $ref: '#/components/schemas/VideoResolutionConstant'
size:
type: integer
fps:
type: number
width:
type: integer
height:
type: integer
createdAt:
type: string
format: date-time
ActorImage:
properties:
path:
deprecated: true
nullable: true
type: string
fileUrl:
type: string
width:
type: integer
height:
type: integer
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
ActorInfo:
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
displayName:
type: string
host:
type: string
format: hostname
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
Actor:
properties:
id:
$ref: '#/components/schemas/id'
url:
type: string
format: url
name:
allOf:
- $ref: '#/components/schemas/username'
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
host:
type: string
format: hostname
hostRedundancyAllowed:
type: boolean
nullable: true
followingCount:
type: integer
minimum: 0
followersCount:
type: integer
minimum: 0
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
Account:
allOf:
- $ref: '#/components/schemas/Actor'
- properties:
userId:
nullable: true
allOf:
- $ref: '#/components/schemas/User/properties/id'
displayName:
type: string
minLength: 3
maxLength: 120
type: string
nullable: true
UserViewingVideo:
required:
- currentTime
properties:
currentTime:
type: integer
format: seconds
example: 5
viewEvent:
type: string
enum:
- seek
Event since last viewing call:
* `seek` - If the user seeked the video
sessionId:
type: string
Optional param to represent the current viewer session.
Used by the backend to properly count one view per session per video.
PeerTube admin can configure the server to not trust this `sessionId` parameter but use the request IP address instead to identify a viewer.
client:
type: string
Client software used to watch the video. For example "Firefox", "PeerTube Approval Android", etc.
device:
Device used to watch the video. For example "desktop", "mobile", "smarttv", etc.
allOf:
- $ref: '#/components/schemas/VideoStatsUserAgentDevice'
operatingSystem:
type: string
Operating system used to watch the video. For example "Windows", "Ubuntu", etc.
VideoStatsOverall:
properties:
averageWatchTime:
type: number
totalWatchTime:
type: number
viewersPeak:
type: number
totalViewers:
type: number
viewersPeakDate:
type: string
format: date-time
countries:
type: array
items:
type: object
properties:
isoCode:
type: string
viewers:
type: number
subdivisions:
type: array
items:
type: object
properties:
name:
type: string
viewers:
type: number
VideoStatsUserAgentDevice:
enum:
- 'console'
- 'embedded'
- 'mobile'
- 'smarttv'
- 'tablet'
- 'wearable'
- 'xr'
- 'desktop'
VideoStatsUserAgent:
properties:
clients:
type: array
items:
type: object
properties:
name:
type: string
viewers:
type: number
devices:
type: array
items:
type: object
properties:
name:
$ref: '#/components/schemas/VideoStatsUserAgentDevice'
viewers:
type: number
operatingSystem:
type: array
items:
type: object
properties:
name:
type: string
viewers:
type: number
VideoStatsRetention:
properties:
data:
type: array
items:
type: object
properties:
second:
type: number
retentionPercent:
type: number
VideoStatsTimeserie:
properties:
data:
type: array
items:
type: object
properties:
date:
type: string
value:
type: number
ServerConfig:
properties:
instance:
type: object
properties:
name:
type: string
shortDescription:
type: string
defaultClientRoute:
type: string
isNSFW:
type: boolean
defaultNSFWPolicy:
type: string
serverCountry:
type: string
defaultLanguage:
type: string
support:
type: object
properties:
text:
type: string
social:
type: object
properties:
externalLink:
type: string
mastodonLink:
type: string
blueskyLink:
type: string
xLink:
type: string
customizations:
type: object
properties:
javascript:
type: string
css:
type: string
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
banners:
type: array
items:
$ref: '#/components/schemas/ActorImage'
search:
type: object
properties:
remoteUri:
type: object
properties:
users:
type: boolean
anonymous:
type: boolean
plugin:
type: object
properties:
registered:
type: array
items:
type: string
theme:
type: object
properties:
registered:
type: array
items:
type: string
email:
type: object
properties:
enabled:
type: boolean
contactForm:
type: object
properties:
enabled:
type: boolean
serverVersion:
type: string
serverCommit:
type: string
signup:
type: object
properties:
allowed:
type: boolean
allowedForCurrentIP:
type: boolean
requiresEmailVerification:
type: boolean
transcoding:
type: object
properties:
hls:
type: object
properties:
enabled:
type: boolean
web_videos:
type: object
properties:
enabled:
type: boolean
enabledResolutions:
type: array
items:
$ref: '#/components/schemas/VideoResolutionSet'
import:
type: object
properties:
videos:
type: object
properties:
http:
type: object
properties:
enabled:
type: boolean
torrent:
type: object
properties:
enabled:
type: boolean
videoChannelSynchronization:
type: object
properties:
enabled:
type: boolean
users:
type: object
properties:
enabled:
type: boolean
resumableUpload:
type: object
properties:
minChunkSize:
type: number
export:
type: object
properties:
users:
type: object
properties:
enabled:
type: boolean
exportExpiration:
type: number
maxUserVideoQuota:
type: number
autoBlacklist:
type: object
properties:
videos:
type: object
properties:
ofUsers:
type: object
properties:
enabled:
type: boolean
blocklist:
type: object
properties:
publicLog:
type: object
properties:
enabled:
type: boolean
avatar:
type: object
properties:
file:
type: object
properties:
size:
type: object
properties:
max:
type: integer
extensions:
type: array
items:
type: string
video:
type: object
properties:
image:
type: object
properties:
extensions:
type: array
items:
type: string
size:
type: object
properties:
max:
type: integer
file:
type: object
properties:
extensions:
type: array
items:
type: string
videoCaption:
type: object
properties:
file:
type: object
properties:
size:
type: object
properties:
max:
type: integer
extensions:
type: array
items:
type: string
user:
type: object
properties:
videoQuota:
type: integer
example: 16810141515
videoQuotaDaily:
type: integer
example: 1681014151
trending:
type: object
properties:
videos:
type: object
properties:
intervalDays:
type: integer
tracker:
type: object
properties:
enabled:
type: boolean
followings:
type: object
properties:
instance:
type: object
properties:
autoFollowIndex:
type: object
properties:
indexUrl:
type: string
format: url
federation:
type: object
properties:
enabled:
type: boolean
homepage:
type: object
properties:
enabled:
type: boolean
openTelemetry:
type: object
properties:
metrics:
type: object
properties:
enabled:
type: boolean
playbackStatsInterval:
type: number
views:
type: object
properties:
videos:
type: object
properties:
countViewAfter:
type: number
watchingInterval:
type: object
properties:
anonymous:
type: number
users:
type: number
SendClientLog:
properties:
message:
type: string
url:
type: string
level:
enum:
- error
- warn
stackTrace:
type: string
userAgent:
type: string
meta:
type: string
required:
- message
- url
- level
ServerStats:
properties:
totalUsers:
type: number
totalDailyActiveUsers:
type: number
totalWeeklyActiveUsers:
type: number
totalMonthlyActiveUsers:
type: number
totalModerators:
type: number
totalAdmins:
type: number
totalLocalVideos:
type: number
totalLocalVideoViews:
type: number
totalLocalVideoDownloads:
type: number
totalLocalVideoComments:
type: number
totalLocalVideoFilesSize:
type: number
totalVideos:
type: number
totalVideoComments:
type: number
totalLocalVideoChannels:
type: number
totalLocalDailyActiveVideoChannels:
type: number
totalLocalWeeklyActiveVideoChannels:
type: number
totalLocalMonthlyActiveVideoChannels:
type: number
totalLocalPlaylists:
type: number
totalInstanceFollowers:
type: number
totalInstanceFollowing:
type: number
videosRedundancy:
type: array
items:
type: object
properties:
strategy:
type: string
totalSize:
type: number
totalUsed:
type: number
totalVideoFiles:
type: number
totalVideos:
type: number
totalActivityPubMessagesProcessed:
type: number
totalActivityPubMessagesSuccesses:
type: number
totalActivityPubMessagesErrors:
type: number
activityPubMessagesProcessedPerSecond:
type: number
totalActivityPubMessagesWaiting:
type: number
averageRegistrationRequestResponseTimeMs:
type: number
totalRegistrationRequestsProcessed:
type: number
totalRegistrationRequests:
type: number
averageAbuseResponseTimeMs:
type: number
totalAbusesProcessed:
type: number
totalAbuses:
type: number
ServerConfigAbout:
properties:
instance:
type: object
properties:
name:
type: string
shortDescription:
type: string
type: string
terms:
type: string
codeOfConduct:
type: string
hardwareInformation:
type: string
creationReason:
type: string
moderationInformation:
type: string
administrator:
type: string
maintenanceLifetime:
type: string
businessModel:
type: string
support:
type: object
properties:
text:
type: string
languages:
type: array
items:
type: string
categories:
type: array
items:
type: integer
avatars:
type: array
items:
$ref: '#/components/schemas/ActorImage'
banners:
type: array
items:
$ref: '#/components/schemas/ActorImage'
InstanceTranslation:
properties:
language:
type: string
example: fr-FR
shortDescription:
type: string
type: string
terms:
type: string
codeOfConduct:
type: string
moderationInformation:
type: string
administrator:
type: string
creationReason:
type: string
maintenanceLifetime:
type: string
businessModel:
type: string
hardwareInformation:
type: string
supportText:
type: string
ServerConfigCustom:
properties:
instance:
type: object
properties:
name:
type: string
shortDescription:
type: string
type: string
terms:
type: string
codeOfConduct:
type: string
creationReason:
type: string
moderationInformation:
type: string
administrator:
type: string
maintenanceLifetime:
type: string
businessModel:
type: string
hardwareInformation:
type: string
translations:
type: array
items:
$ref: '#/components/schemas/InstanceTranslation'
languages:
type: array
items:
type: string
categories:
type: array
items:
type: number
isNSFW:
type: boolean
defaultNSFWPolicy:
type: string
serverCountry:
type: string
support:
type: object
properties:
text:
type: string
social:
type: object
properties:
externalLink:
type: string
mastodonLink:
type: string
blueskyLink:
type: string
xLink:
type: string
defaultClientRoute:
type: string
customizations:
type: object
properties:
javascript:
type: string
css:
type: string
theme:
type: object
properties:
default:
type: string
services:
type: object
properties:
twitter:
type: object
properties:
username:
type: string
cache:
type: object
properties:
previews:
type: object
properties:
size:
type: integer
captions:
type: object
properties:
size:
type: integer
signup:
type: object
properties:
enabled:
type: boolean
limit:
type: integer
requiresEmailVerification:
type: boolean
admin:
type: object
properties:
email:
type: string
format: email
contactForm:
type: object
properties:
enabled:
type: boolean
user:
type: object
properties:
videoQuota:
type: integer
example: 16810141515
videoQuotaDaily:
type: integer
example: 1681014151
transcoding:
type: object
properties:
enabled:
type: boolean
originalFile:
type: object
properties:
keep:
type: boolean
allowAdditionalExtensions:
type: boolean
allowAudioFiles:
type: boolean
threads:
type: integer
concurrency:
type: number
profile:
type: string
enum:
- default
New profiles can be added by plugins ; available in core PeerTube: 'default'.
resolutions:
type: object
properties:
0p:
type: boolean
144p:
type: boolean
240p:
type: boolean
360p:
type: boolean
480p:
type: boolean
720p:
type: boolean
1080p:
type: boolean
1440p:
type: boolean
2160p:
type: boolean
web_videos:
type: object
properties:
enabled:
type: boolean
hls:
type: object
properties:
enabled:
type: boolean
splitAudioAndVideo:
type: boolean
import:
type: object
properties:
videos:
type: object
properties:
http:
type: object
properties:
enabled:
type: boolean
torrent:
type: object
properties:
enabled:
type: boolean
video_channel_synchronization:
type: object
properties:
enabled:
type: boolean
autoBlacklist:
type: object
properties:
videos:
type: object
properties:
ofUsers:
type: object
properties:
enabled:
type: boolean
blocklist:
type: object
properties:
publicLog:
type: object
properties:
enabled:
type: boolean
followers:
type: object
properties:
instance:
type: object
properties:
enabled:
type: boolean
manualApproval:
type: boolean
storyboard:
type: object
properties:
enabled:
type: boolean
defaults:
type: object
properties:
publish:
type: object
properties:
downloadEnabled:
type: boolean
commentsPolicy:
$ref: '#/components/schemas/VideoCommentsPolicySet'
recommendationScope:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
privacy:
$ref: '#/components/schemas/VideoPrivacySet'
licence:
$ref: '#/components/schemas/VideoLicenceSet'
p2p:
type: object
properties:
webapp:
type: object
properties:
enabled:
type: boolean
embed:
type: object
properties:
enabled:
type: boolean
player:
type: object
properties:
autoPlay:
type: boolean
CustomHomepage:
properties:
content:
type: string
Follow:
properties:
id:
$ref: '#/components/schemas/id'
follower:
$ref: '#/components/schemas/Actor'
following:
$ref: '#/components/schemas/Actor'
score:
type: number
state:
type: string
enum:
- pending
- accepted
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
PredefinedAbuseReasons:
type: array
maxItems: 8
items:
type: string
enum:
- violentOrAbusive
- hatefulOrAbusive
- spamOrMisleading
- privacy
- rights
- serverRules
- thumbnails
- captions
JobType:
type: string
enum:
- activitypub-cleaner
- activitypub-follow
- activitypub-http-broadcast
- activitypub-http-broadcast-parallel
- activitypub-http-fetcher
- activitypub-http-unicast
- activitypub-refresher
- actor-keys
- after-video-channel-import
- build-automatic-tags
- build-object-automatic-tags
- create-user-export
- email
- federate-video
- generate-video-storyboard
- import-user-archive
- manage-video-torrent
- move-to-file-system
- move-to-object-storage
- notify
- transcoding-job-builder
- video-channel-import
- video-file-import
- video-files-lifecycle
- video-import
- video-live-ending
- video-redundancy
- video-studio-edition
- video-transcoding
- video-transcription
- videos-stats
Job:
properties:
id:
$ref: '#/components/schemas/id'
state:
type: string
enum:
- active
- completed
- failed
- waiting
- delayed
type:
$ref: '#/components/schemas/JobType'
data:
type: object
additionalProperties: true
error:
type: object
additionalProperties: true
createdAt:
type: string
format: date-time
finishedOn:
type: string
format: date-time
processedOn:
type: string
format: date-time
canCancel:
type: boolean
AddUserResponse:
properties:
user:
type: object
properties:
id:
$ref: '#/components/schemas/id'
account:
type: object
properties:
id:
$ref: '#/components/schemas/id'
VideoUploadRequestCommon:
properties:
name:
type: string
example: What is PeerTube?
minLength: 3
maxLength: 120
channelId:
type: integer
example: 3
minimum: 1
privacy:
$ref: '#/components/schemas/VideoPrivacySet'
category:
$ref: '#/components/schemas/VideoCategorySet'
licence:
$ref: '#/components/schemas/VideoLicenceSet'
language:
$ref: '#/components/schemas/VideoLanguageSet'
type: string
example: |
**[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)**
waitTranscoding:
type: boolean
generateTranscription:
type: boolean
support:
example: Please support our work on https://soutenir.framasoft.org/en/ <3
type: string
nsfw:
type: boolean
nsfwSummary:
nsfwFlags:
$ref: '#/components/schemas/NSFWFlag'
tags:
type: array
minItems: 1
maxItems: 5
uniqueItems: true
example:
- framasoft
- peertube
items:
type: string
minLength: 2
maxLength: 30
commentsPolicy:
$ref: '#/components/schemas/VideoCommentsPolicySet'
recommendationScope:
$ref: '#/components/schemas/VideoRecommendationScopeSet'
aiUsage:
$ref: '#/components/schemas/VideoAIUsageSet'
commercialContent:
$ref: '#/components/schemas/VideoCommercialContentSet'
downloadEnabled:
type: boolean
originallyPublishedAt:
type: string
format: date-time
scheduleUpdate:
$ref: '#/components/schemas/VideoScheduledUpdate'
thumbnailfile:
type: string
format: binary
previewfile:
deprecated: true
type: string
format: binary
videoPasswords:
$ref: '#/components/schemas/AddVideoPasswords'
required:
- channelId
- name
VideoUploadRequestLegacy:
allOf:
- $ref: '#/components/schemas/VideoUploadRequestCommon'
- type: object
required:
- videofile
properties:
videofile:
type: string
format: binary
VideoUploadRequestResumable:
allOf:
- $ref: '#/components/schemas/VideoUploadRequestCommon'
- type: object
required:
- filename
properties:
filename:
type: string
format: filename
example: what_is_peertube.mp4
thumbnailfile:
type: string
format: binary
previewfile:
deprecated: true
type: string
format: binary
VideoUploadResponse:
properties:
video:
type: object
properties:
id:
$ref: '#/components/schemas/Video/properties/id'
uuid:
$ref: '#/components/schemas/Video/properties/uuid'
shortUUID:
$ref: '#/components/schemas/Video/properties/shortUUID'
VideoReplaceSourceRequestResumable:
properties:
filename:
type: string
format: filename
example: what_is_peertube.mp4
UserImportResumable:
properties:
filename:
type: string
format: filename
example: "user-export-6-2024-02-09T10_12_11.682Z"
CommentThreadResponse:
properties:
total:
type: integer
totalNotDeletedComments:
type: integer
data:
type: array
maxItems: 100
items:
$ref: '#/components/schemas/VideoComment'
CommentThreadPostResponse:
properties:
comment:
$ref: '#/components/schemas/VideoComment'
VideoTokenResponse:
properties:
files:
type: object
properties:
token:
type: string
expires:
type: string
format: date-time
VideoListResponse:
properties:
total:
type: integer
example: 1
data:
type: array
maxItems: 100
items:
$ref: '#/components/schemas/Video'
ChannelActivityListResponse:
properties:
total:
type: integer
example: 1
data:
type: array
items:
type: object
properties:
id:
type: integer
account:
nullable: true
$ref: '#/components/schemas/AccountSummary'
action:
type: object
properties:
id:
$ref: '#/components/schemas/VideoChannelActivityAction'
label:
type: string
targetType:
type: object
properties:
id:
$ref: '#/components/schemas/VideoChannelActivityTarget'
label:
type: string
details:
type: object
additionalProperties: true
createdAt:
type: string
format: date-time
channel:
type: object
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
displayName:
type: string
url:
type: string
format: url
video:
nullable: true
type: object
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
uuid:
$ref: '#/components/schemas/UUIDv4'
shortUUID:
$ref: '#/components/schemas/shortUUID'
url:
type: string
format: url
isLive:
type: boolean
videoImport:
nullable: true
type: object
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
uuid:
$ref: '#/components/schemas/UUIDv4'
shortUUID:
$ref: '#/components/schemas/shortUUID'
url:
type: string
format: url
targetUrl:
type: string
format: uri
playlist:
nullable: true
type: object
properties:
id:
$ref: '#/components/schemas/id'
name:
type: string
uuid:
$ref: '#/components/schemas/UUIDv4'
shortUUID:
$ref: '#/components/schemas/shortUUID'
url:
type: string
format: url
channelSync:
nullable: true
type: object
properties:
id:
$ref: '#/components/schemas/id'
externalChannelUrl:
type: string
format: uri
UserNotificationSettings:
properties:
abuseAsModerator:
$ref: '#/components/schemas/NotificationSettingValue'
videoAutoBlacklistAsModerator:
$ref: '#/components/schemas/NotificationSettingValue'
newUserRegistration:
$ref: '#/components/schemas/NotificationSettingValue'
newVideoFromSubscription:
$ref: '#/components/schemas/NotificationSettingValue'
blacklistOnMyVideo:
$ref: '#/components/schemas/NotificationSettingValue'
myVideoPublished:
$ref: '#/components/schemas/NotificationSettingValue'
myVideoImportFinished:
$ref: '#/components/schemas/NotificationSettingValue'
commentMention:
$ref: '#/components/schemas/NotificationSettingValue'
newCommentOnMyVideo:
$ref: '#/components/schemas/NotificationSettingValue'
newFollow:
$ref: '#/components/schemas/NotificationSettingValue'
newInstanceFollower:
$ref: '#/components/schemas/NotificationSettingValue'
autoInstanceFollowing:
$ref: '#/components/schemas/NotificationSettingValue'
abuseStateChange:
$ref: '#/components/schemas/NotificationSettingValue'
abuseNewMessage:
$ref: '#/components/schemas/NotificationSettingValue'
newPeerTubeVersion:
$ref: '#/components/schemas/NotificationSettingValue'
newPluginVersion:
$ref: '#/components/schemas/NotificationSettingValue'
myVideoStudioEditionFinished:
$ref: '#/components/schemas/NotificationSettingValue'
myVideoTranscriptionGenerated:
$ref: '#/components/schemas/NotificationSettingValue'
User:
properties:
id:
$ref: '#/components/schemas/id'
username:
$ref: '#/components/schemas/username'
email:
type: string
format: email
emailVerified:
type: boolean
nsfwPolicy:
$ref: '#/components/schemas/NSFWPolicy'
nsfwFlagsDisplayed:
$ref: '#/components/schemas/NSFWFlag'
nsfwFlagsHidden:
$ref: '#/components/schemas/NSFWFlag'
nsfwFlagsWarned:
$ref: '#/components/schemas/NSFWFlag'
nsfwFlagsBlurred:
$ref: '#/components/schemas/NSFWFlag'
aiUsagesHidden:
type: array
items:
$ref: '#/components/schemas/VideoAIUsageSet'
adminFlags:
$ref: '#/components/schemas/UserAdminFlags'
autoPlayNextVideo:
type: boolean
autoPlayNextVideoPlaylist:
type: boolean
autoPlayVideo:
type: boolean
p2pEnabled:
type: boolean