X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=support%2Fdoc%2Fapi%2Fopenapi.yaml;h=86c781f313d811785086242927ce7a6f4c1f2be6;hb=c00100b607ab97dfea690880434657b7ee11466d;hp=56941031bc2a8c35da5b2361fb9032857f85060a;hpb=6b738c7a31591a83fdcd9c78b6b1f98e543c378b;p=github%2FChocobozzz%2FPeerTube.git diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index 56941031b..f99d49fef 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml @@ -1,1728 +1,6487 @@ -swagger: '2.0' +openapi: 3.0.0 info: title: PeerTube - version: 1.0.0-beta - description: Federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular. -host: peertube.example.com -securityDefinitions: - OAuth2: - description: 'In the header: *Authorization: Bearer mytoken*' - type: oauth2 - flow: password - # Not implemented yet - # authorizationUrl: https://example.com/oauth/authorize - tokenUrl: https://peertube.example.com/api/v1/users/token -basePath: '/api/v1' -schemes: - - https + version: 3.2.0-rc.1 + 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 + description: | + 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. The spec API is fully compatible with + [openapi-generator](https://github.com/OpenAPITools/openapi-generator/wiki/API-client-generator-HOWTO) + which generates a client SDK in the language of your choice - we generate some client SDKs automatically: + + - [Python](https://framagit.org/framasoft/peertube/clients/python) + - [Go](https://framagit.org/framasoft/peertube/clients/go) + - [Kotlin](https://framagit.org/framasoft/peertube/clients/kotlin) + + See the [REST API quick start](https://docs.joinpeertube.org/api-rest-getting-started) for a few + examples of using with 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 a session token. Only __one + session 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?id=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. The body of the response will be JSON in the following + formats. + + ``` + { + "error": "Account not found" // error debug message + } + ``` + + Validation errors benefit from a more detailed error type and return the HTTP `400 Bad Request` status code. + + ``` + { + "errors": { + "id": { // where 'id' is the name of the parameter concerned by the error. + "value": "a117eb-c6a9-4756-bb09-2a956239f", // value that triggered the error. + "msg": "Should have an valid id", // error debug message + "param": "id", + "location": "params" // 'params', 'body', 'header', 'query' or 'cookies' + } + } + } + ``` + + # Rate limits + + We are rate-limiting all endpoints of PeerTube's API. Custom values can be set by administrators: + + | Endpoint | Calls | Time frame | + |-------------------------|------------------|---------------------------| + | `/*` | 50 | 10 seconds | + | `POST /users/token` | 15 | 5 minutes | + | `POST /users/register` | 2* | 5 minutes | + | `POST /users/ask-send-verify-email` | 3 | 5 minutes | + + Depending on the endpoint, *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 | +externalDocs: + url: https://docs.joinpeertube.org/api-rest-reference.html +tags: + - name: Accounts + description: > + 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 + description: > + 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: My User + description: > + Operations related to your own User, when logged-in. + - name: My Subscriptions + description: > + 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 + description: > + Operations related to your watch history. + - name: My Notifications + description: > + 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 + description: > + Each server exposes public information regarding supported videos and + options. + - name: Job + description: > + Jobs are long-running tasks enqueued and processed by the instance + itself. No additional worker registration is currently available. + - name: Instance Follows + description: > + 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?id=instances-follows + - name: Instance Redundancy + description: > + 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](#tag/Video-Mirroring). + externalDocs: + url: https://docs.joinpeertube.org/admin-following-instances?id=instances-redundancy + - name: Plugins + description: > + Managing plugins installed from a local path or from NPM, or search for new ones. + externalDocs: + url: https://docs.joinpeertube.org/api-plugins + - name: Abuses + description: | + Abuses deal with reports of local or remote videos/comments/accounts alike. + - name: Video + description: | + Operations dealing with listing, uploading, fetching or modifying videos. + - name: Video Upload + description: | + Operations dealing with adding video or audio. PeerTube supports two upload modes, and three import modes. + + ### Upload + + - [_legacy_](#operation/uploadLegacy), where the video file is sent in a single request + - [_resumable_](#operation/uploadResumableInit), 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](https://ytdl-org.github.io/youtube-dl/) + - _magnet_-based: where the URI resolves to a BitTorrent ressource containing a single supported video file + - _torrent_-based: where the metainfo file resolves to a BitTorrent ressource 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 Captions + description: Operations dealing with listing, adding and removing closed captions of a video. + - name: Video Channels + description: Operations dealing with the creation, modification and listing of videos within a channel. + - name: Video Comments + description: > + 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 + description: Operations dealing with blocking videos (removing them from view and preventing interactions). + - name: Video Rates + description: Like/dislike a video. + - name: Video Playlists + description: Operations dealing with playlists of videos. Playlists are bound to users and/or channels. + - name: Feeds + description: Server syndication feeds + - name: Search + description: | + 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 not could be not federated by the instance. + - name: Video Mirroring + description: | + PeerTube instances can mirror videos from one another, and help distribute some videos. + + For importing videos as your own, refer to [video imports](#operation/importVideo). +x-tagGroups: + - name: Accounts + tags: + - Accounts + - Users + - My User + - My Subscriptions + - My Notifications + - My History + - name: Videos + tags: + - Video + - Video Upload + - Video Captions + - Video Channels + - Video Comments + - Video Rates + - Video Playlists + - Video Ownership Change + - Video Mirroring + - Live Videos + - Feeds + - name: Search + tags: + - Search + - name: Moderation + tags: + - Abuses + - Video Blocks + - Account Blocks + - Server Blocks + - name: Instance Configuration + tags: + - Config + - Instance Follows + - Instance Redundancy + - Plugins + - name: Jobs + tags: + - Job paths: - '/accounts/{id}': + '/accounts/{name}': get: tags: - Accounts - consumes: - - application/json - produces: - - application/json + summary: Get an account parameters: - - name: id - in: path - required: true - type: string - description: 'The id of the account' - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/name' responses: '200': description: successful operation - schema: - $ref: '#/definitions/Account' - '/accounts/{id}/videos': + content: + application/json: + schema: + $ref: '#/components/schemas/Account' + '404': + description: account not found + '/accounts/{name}/videos': get: tags: - Accounts - consumes: - - application/json - produces: - - application/json + - Video + summary: 'List videos of an account' parameters: - - name: id - in: path - required: true - type: string - description: 'The id of the account' + - $ref: '#/components/parameters/name' + - $ref: '#/components/parameters/categoryOneOf' + - $ref: '#/components/parameters/isLive' + - $ref: '#/components/parameters/tagsOneOf' + - $ref: '#/components/parameters/tagsAllOf' + - $ref: '#/components/parameters/licenceOneOf' + - $ref: '#/components/parameters/languageOneOf' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/skipCount' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/videosSort' responses: '200': description: successful operation - schema: - $ref: '#/definitions/Video' + 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) /accounts: get: tags: - Accounts - consumes: - - application/json - produces: - - application/json + summary: List accounts + parameters: + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Account' + content: + 'application/json': + schema: + type: array + items: + $ref: '#/components/schemas/Account' /config: get: tags: - Config - consumes: - - application/json - produces: - - application/json + summary: Get instance public configuration responses: '200': description: successful operation - schema: - $ref: '#/definitions/ServerConfig' - /feeds/videos.{format}: + content: + application/json: + schema: + $ref: '#/components/schemas/ServerConfig' + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/config + /config/about: get: + summary: Get instance "About" information tags: - - Feeds - produces: - - application/atom+xml - - application/rss+xml - - application/json - parameters: - - name: format - in: path - required: true - type: string - enum: [ 'xml', 'atom', 'json'] - default: 'xml' - description: 'The format expected (xml defaults to RSS 2.0, atom to ATOM 1.0 and json to JSON FEED 1.0' - - name: accountId - in: query - required: false - type: number - description: 'The id of the local account to filter to (beware, users IDs and not actors IDs which will return empty feeds' - - name: accountName - in: query - required: false - type: string - description: 'The name of the local account to filter to' + - Config + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ServerConfigAbout' + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/config/about + /config/custom: + get: + summary: Get instance runtime configuration + tags: + - Config + security: + - OAuth2: + - admin + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ServerConfigCustom' + put: + summary: Set instance runtime configuration + tags: + - Config + security: + - OAuth2: + - admin + responses: + '200': + description: successful operation + '400': + x-summary: field inconsistencies + description: > + Arises when: + - the emailer is disabled and the instance is open to registrations + - webtorrent and hls are disabled with transcoding enabled - you need at least one enabled + delete: + summary: Delete instance runtime configuration + tags: + - Config + security: + - OAuth2: + - admin responses: '200': description: successful operation - /jobs: + /jobs/{state}: get: + summary: List instance jobs security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - Job - consumes: - - application/json - produces: - - application/json parameters: - name: state in: path required: true - type: string - description: 'The id of the account' - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: count - in: query - required: false - type: number - description: '' - - name: sort - in: query - required: false - type: number - description: 'sorting' + description: The state of the job ('' for for no filter) + 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': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Job' + content: + application/json: + schema: + type: object + properties: + total: + type: integer + example: 1 + data: + type: array + maxItems: 100 + items: + $ref: '#/components/schemas/Job' '/server/following/{host}': delete: security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - - ServerFollowing - consumes: - - application/json - produces: - - application/json + - Instance Follows + summary: Unfollow a server parameters: - name: host in: path required: true - type: string description: 'The host to unfollow ' + schema: + type: string + format: hostname responses: '201': description: successful operation /server/followers: get: tags: - - ServerFollowing - consumes: - - application/json - produces: - - application/json + - Instance Follows + summary: List instance followers parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Follow' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Follow' /server/following: get: tags: - - ServerFollowing - consumes: - - application/json - produces: - - application/json + - Instance Follows + summary: List instances followed by the server parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop + - name: state in: query - required: false - type: number - description: 'stopping page' - - name: sort + schema: + type: string + enum: + - pending + - accepted + - name: actorType in: query - required: false - type: number - description: 'sorting' + schema: + type: string + enum: + - Person + - Application + - Group + - Service + - Organization + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Follow' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Follow' post: security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - - ServerFollowing - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - schema: - $ref: '#/definitions/Follow' + - Instance Follows + summary: Follow a server responses: '204': description: successful operation + '500': + description: cannot follow a non-HTTPS server + requestBody: + content: + application/json: + schema: + type: object + properties: + hosts: + type: array + items: + type: string + format: hostname + uniqueItems: true /users: post: + summary: Create a user security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - - User - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - required: true - description: 'User to create' - schema: - $ref: '#/definitions/AddUser' + - Users responses: '200': - description: successful operation - schema: - $ref: '#/definitions/AddUserResponse' + description: user created + content: + application/json: + schema: + $ref: '#/components/schemas/AddUserResponse' + links: + # GET /users/{id} + GetUserId: + operationId: getUserId + parameters: + id: '$response.body#/user/id' + # PUT /users/{id} + PutUserId: + operationId: putUserId + parameters: + id: '$response.body#/user/id' + # DELETE /users/{id} + DelUserId: + operationId: delUserId + parameters: + id: '$response.body#/user/id' + '403': + description: insufficient authority to create an admin or moderator + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AddUser' + description: | + 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 security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - - User - consumes: - - application/json - produces: - - application/json + - Users parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/usersSearch' + - $ref: '#/components/parameters/usersBlocked' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/usersSort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/User' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' '/users/{id}': + parameters: + - $ref: '#/components/parameters/id' delete: + summary: Delete a user security: - - OAuth2: [ ] + - OAuth2: + - admin tags: - - User - consumes: - - application/json - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The user id ' + - Users + operationId: delUserId responses: '204': description: successful operation get: + summary: Get a user security: - - OAuth2: [ ] + - OAuth2: [] tags: - - User - consumes: - - application/json - produces: - - application/json + - Users + operationId: getUserId parameters: - - name: id - in: path - required: true - type: string - description: 'The user id ' + - name: withStats + in: query + description: include statistics about the user (only available as a moderator/admin) + schema: + type: boolean responses: '200': - description: successful operation - schema: - $ref: '#/definitions/User' + x-summary: successful operation + description: | + 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: [ ] + - OAuth2: [] tags: - - User - consumes: - - application/json - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The user id ' - - in: body - name: body - required: true - schema: - $ref: '#/definitions/UpdateUser' + - Users + operationId: putUserId + responses: + '204': + description: successful operation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateUser' + required: true + /users/register: + post: + summary: Register a user + tags: + - Users responses: '204': description: successful operation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterUser' + required: true /users/me: get: + summary: Get my user information security: - - OAuth2: [ ] + - OAuth2: + - user tags: - - User - consumes: - - application/json - produces: - - application/json + - My User responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/User' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' put: + summary: Update my user information security: - - OAuth2: [ ] + - OAuth2: + - user tags: - - User - consumes: - - application/json - produces: - - application/json - parameters: - - in: body - name: body - required: true - schema: - $ref: '#/definitions/UpdateMe' + - My User responses: '204': description: successful operation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateMe' + required: true + /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' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoImportsList' /users/me/video-quota-used: get: + summary: Get my user used quota security: - - OAuth2: [ ] + - OAuth2: + - user tags: - - User - consumes: - - application/json - produces: - - application/json - parameters: [] + - My User responses: '200': description: successful operation - schema: - type: number + content: + application/json: + schema: + type: object + properties: + videoQuotaUsed: + type: number + description: The user video quota used so far in bytes + example: 16810141515 + videoQuotaUsedDaily: + type: number + description: The user video quota used today in bytes + example: 1681014151 '/users/me/videos/{videoId}/rating': get: + summary: Get rate of my user for a video security: - - OAuth2: [ ] + - OAuth2: [] tags: - - User - consumes: - - application/json - produces: - - application/json + - My User + - Video Rates parameters: - name: videoId in: path required: true - type: string - description: 'The video id ' + description: The video id + schema: + $ref: '#/components/schemas/Video/properties/id' responses: '200': description: successful operation - schema: - $ref: '#/definitions/GetMeVideoRating' + content: + application/json: + schema: + $ref: '#/components/schemas/GetMeVideoRating' /users/me/videos: get: + summary: Get videos of my user security: - - OAuth2: [ ] + - OAuth2: + - user tags: - - User - consumes: - - application/json - produces: - - application/json + - My User + - Videos parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Video' - /users/register: - post: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + /users/me/subscriptions: + get: + summary: Get my user subscriptions + security: + - OAuth2: + - user tags: - - User - consumes: - - application/json - produces: - - application/json + - My Subscriptions parameters: - - in: body - name: body - required: true - schema: - $ref: '#/definitions/RegisterUser' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: - '204': + '200': description: successful operation - /users/me/avatar/pick: + 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 + description: uri of the video channels to subscribe to + required: + - uri + examples: + default: + value: + uri: 008a0e54-375d-49d0-8379-143202e24152@video.lqdn.fr + responses: + '200': + description: successful operation + /users/me/subscriptions/exist: + get: + summary: Get if subscriptions exist for my user security: - - OAuth2: [ ] + - OAuth2: + - user tags: - - User - consumes: - - multipart/form-data - produces: - - application/json + - My Subscriptions parameters: - - in: formData - name: avatarfile - type: file - description: The file to upload. + - $ref: '#/components/parameters/subscriptionsUris' responses: '200': description: successful operation - schema: - $ref: '#/definitions/Avatar' - /videos: + content: + application/json: + schema: + type: object + /users/me/subscriptions/videos: get: + summary: List videos of subscriptions of my user + security: + - OAuth2: + - user tags: - - Video - consumes: - - application/json - produces: - - application/json + - My Subscriptions + - Videos parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' - responses: - '200': - description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Video' - /videos/categories: - get: - tags: - - Video - consumes: - - application/json - produces: - - application/json - responses: - '200': - description: successful operation - schema: - type: array - items: - type: string - /videos/licences: - get: - tags: - - Video - consumes: - - application/json - produces: - - application/json + - $ref: '#/components/parameters/categoryOneOf' + - $ref: '#/components/parameters/isLive' + - $ref: '#/components/parameters/tagsOneOf' + - $ref: '#/components/parameters/tagsAllOf' + - $ref: '#/components/parameters/licenceOneOf' + - $ref: '#/components/parameters/languageOneOf' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/skipCount' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/videosSort' responses: '200': description: successful operation - schema: - type: array - items: - type: string - /videos/languages: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + '/users/me/subscriptions/{subscriptionHandle}': get: + summary: Get subscription of my user + security: + - OAuth2: + - user tags: - - Video - consumes: - - application/json - produces: - - application/json + - My Subscriptions + parameters: + - $ref: '#/components/parameters/subscriptionHandle' responses: '200': description: successful operation - schema: - type: array - items: - type: string - /videos/privacies: - get: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannel' + delete: + summary: Delete subscription of my user + security: + - OAuth2: + - user tags: - - Video - consumes: - - application/json - produces: - - application/json + - My Subscriptions + parameters: + - $ref: '#/components/parameters/subscriptionHandle' responses: '200': description: successful operation - schema: - type: array - items: - type: string - /videos/search: + /users/me/notifications: get: + summary: List my notifications + security: + - OAuth2: [] tags: - - Video - consumes: - - application/json - produces: - - application/json + - My Notifications parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort + - name: unread in: query - required: false - type: number - description: 'sorting' + description: only list unread notifications + schema: + type: boolean + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Video' - "/videos/{id}": - put: + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationListResponse' + /users/me/notifications/read: + post: + summary: Mark notifications as read by their id security: - - OAuth2: [ ] + - OAuth2: [] tags: - - Video - consumes: - - multipart/form-data - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The video id' - - name: thumbnailfile - in: formData - type: file - description: 'Video thumbnail file' - - name: previewfile - in: formData - type: file - description: 'Video preview file' - - name: category - in: formData - type: number - description: 'Video category' - - name: licence - in: formData - type: number - description: 'Video licence' - - name: language - in: formData - type: string - description: 'Video language' - - name: description - in: formData - type: string - description: 'Video description' - - name: support - in: formData - type: string - description: 'Text describing how to support the video uploader' - - name: nsfw - in: formData - type: boolean - description: 'Whether or not this video contains sensitive content' - - name: name - in: formData - type: string - description: 'Video name' - - name: tags - in: formData - type: string[] - description: 'Video tags' - - name: commentsEnabled - in: formData - type: boolean - description: 'Enable or disable comments for this video' - - name: privacy - in: formData - type: string - enum: [Public, Unlisted] - description: 'Video privacy' + - My Notifications + requestBody: + content: + application/json: + schema: + type: object + properties: + ids: + type: array + description: ids of the notifications to mark as read + items: + type: integer + required: + - ids responses: - '200': + '204': description: successful operation - schema: - $ref: '#/definitions/Video' - get: + /users/me/notifications/read-all: + post: + summary: Mark all my notification as read + security: + - OAuth2: [] tags: - - Video - consumes: - - application/json - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - My Notifications responses: - '200': + '204': description: successful operation - schema: - $ref: '#/definitions/Video' - delete: + /users/me/notification-settings: + put: + summary: Update my notification settings security: - - OAuth2: [ ] + - OAuth2: [] tags: - - Video - consumes: - - application/json - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - My Notifications + requestBody: + content: + application/json: + schema: + type: object + properties: + newVideoFromSubscription: + $ref: '#/components/schemas/NotificationSettingValue' + newCommentOnMyVideo: + $ref: '#/components/schemas/NotificationSettingValue' + abuseAsModerator: + $ref: '#/components/schemas/NotificationSettingValue' + videoAutoBlacklistAsModerator: + $ref: '#/components/schemas/NotificationSettingValue' + blacklistOnMyVideo: + $ref: '#/components/schemas/NotificationSettingValue' + myVideoPublished: + $ref: '#/components/schemas/NotificationSettingValue' + myVideoImportFinished: + $ref: '#/components/schemas/NotificationSettingValue' + newFollow: + $ref: '#/components/schemas/NotificationSettingValue' + newUserRegistration: + $ref: '#/components/schemas/NotificationSettingValue' + commentMention: + $ref: '#/components/schemas/NotificationSettingValue' + newInstanceFollower: + $ref: '#/components/schemas/NotificationSettingValue' + autoInstanceFollowing: + $ref: '#/components/schemas/NotificationSettingValue' responses: '204': description: successful operation - "/videos/{id}/description": + /users/me/history/videos: get: + summary: List watched videos history + security: + - OAuth2: [] tags: - - Video - consumes: - - application/json - produces: - - application/json + - My History parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/search' responses: '200': description: successful operation - schema: - type: string - "/videos/{id}/views": + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + /users/me/history/videos/remove: post: + summary: Clear video history + security: + - OAuth2: [] tags: - - Video - consumes: - - application/json - produces: - - application/json - parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - My History + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + beforeDate: + description: history before this date will be deleted + type: string + format: date-time responses: '204': description: successful operation - /videos/upload: + /users/me/avatar/pick: post: + summary: Update my user avatar security: - - OAuth2: [ ] + - OAuth2: [] tags: - - Video - consumes: - - multipart/form-data - produces: - - application/json - parameters: - - name: videofile - in: formData - type: file - required: true - description: 'Video file' - - name: thumbnailfile - in: formData - type: file - required: true - description: 'Video thumbnail file' - - name: previewfile - in: formData - type: file - required: true - description: 'Video preview file' - - name: category - in: formData - type: number - description: 'Video category' - - name: licence - in: formData - type: number - description: 'Video licence' - - name: language - in: formData - type: string - description: 'Video language' - - name: description - in: formData - type: string - description: 'Video description' - - name: support - in: formData - type: string - description: 'Text describing how to support the video uploader' - - name: channelId - in: formData - required: true - type: number - description: 'Channel id that will contain this video' - - name: nsfw - in: formData - required: true - type: boolean - description: 'Whether or not this video contains sensitive content' - - name: name - in: formData - required: true - type: string - description: 'Video name' - - name: tags - in: formData - type: string[] - description: 'Video tags' - - name: commentsEnabled - in: formData - type: boolean - description: 'Enable or disable comments for this video' - - name: privacy - in: formData - required: true - type: string - enum: [Public, Unlisted, Private] - description: 'Video privacy' + - My User responses: '200': description: successful operation - schema: - $ref: '#/definitions/VideoUploadResponse' - /videos/abuse: - get: + content: + application/json: + schema: + type: object + properties: + avatar: + $ref: '#/components/schemas/ActorImage' + '413': + description: image file too large + headers: + X-File-Maximum-Size: + schema: + type: string + format: Nginx size + description: Maximum file size for the avatar + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + avatarfile: + description: The file to upload + type: string + format: binary + encoding: + avatarfile: + contentType: image/png, image/jpeg + /users/me/avatar: + delete: + summary: Delete my avatar security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoAbuse - consumes: - - application/json - produces: - - application/json - parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - My User + responses: + '204': + description: successful operation + + /videos/ownership: + get: + summary: List video ownership changes + tags: + - Video Ownership Change + security: + - OAuth2: [] responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/VideoAbuse' - "/videos/{id}/abuse": + '/videos/ownership/{id}/accept': post: - security: - - OAuth2: [ ] + summary: Accept ownership change request tags: - - VideoAbuse - consumes: - - application/json - produces: - - application/json + - Video Ownership Change + security: + - OAuth2: [] parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - $ref: '#/components/parameters/idOrUUID' responses: '204': description: successful operation - "/videos/{videoId}/blacklist": + '403': + description: cannot terminate an ownership change of another user + '404': + description: video owneship change not found + '/videos/ownership/{id}/refuse': post: - security: - - OAuth2: [ ] + summary: Refuse ownership change request tags: - - VideoBlacklist - consumes: - - application/json - produces: - - application/json + - Video Ownership Change + security: + - OAuth2: [] parameters: - - name: videoId - in: path - required: true - type: string - description: 'The video id ' + - $ref: '#/components/parameters/idOrUUID' responses: '204': description: successful operation - delete: - security: - - OAuth2: [ ] + '403': + description: cannot terminate an ownership change of another user + '404': + description: video owneship change not found + '/videos/{id}/give-ownership': + post: + summary: Request ownership change tags: - - VideoBlacklist - consumes: - - application/json - produces: - - application/json + - Video Ownership Change + security: + - OAuth2: [] parameters: - - name: videoId - in: path - required: true - type: string - description: 'The video id ' + - $ref: '#/components/parameters/idOrUUID' + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + username: + type: string + required: + - username responses: '204': description: successful operation - /videos/blacklist: + '400': + description: changing video ownership to a remote account is not supported yet + '404': + description: video not found + /videos: get: - security: - - OAuth2: [ ] + summary: List videos tags: - - VideoBlacklist - consumes: - - application/json - produces: - - application/json + - Video parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/categoryOneOf' + - $ref: '#/components/parameters/isLive' + - $ref: '#/components/parameters/tagsOneOf' + - $ref: '#/components/parameters/tagsAllOf' + - $ref: '#/components/parameters/licenceOneOf' + - $ref: '#/components/parameters/languageOneOf' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/skipCount' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/videosSort' responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/VideoBlacklist' - /video-channels: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + /videos/categories: get: + summary: List available video categories + operationId: getCategories tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json - parameters: - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - Video responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/VideoChannel' - /accounts/{accountId}/video-channels: + content: + application/json: + schema: + type: array + items: + type: string + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/videos/categories + /videos/licences: get: + summary: List available video licences + operationId: getLicences tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json - parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' + - Video responses: '200': description: successful operation - schema: - type: array - items: - $ref: '#/definitions/VideoChannel' - post: - security: - - OAuth2: [ ] - tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json - parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' - - in: body - name: body - schema: - $ref: '#/definitions/VideoChannelInput' - responses: - '204': - description: successful operation - "/account/{accountId}/video-channels/{id}": + content: + application/json: + schema: + type: array + items: + type: string + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/videos/licences + /videos/languages: get: + summary: List available video languages + operationId: getLanguages tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json - parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' - - name: id - in: path - required: true - type: string - description: 'The video channel id ' + - Video responses: '200': description: successful operation - schema: - $ref: '#/definitions/VideoChannel' + content: + application/json: + schema: + type: array + items: + type: string + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/videos/languages + /videos/privacies: + get: + summary: List available video privacy policies + operationId: getPrivacyPolicies + tags: + - Video + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + type: string + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/videos/privacies + '/videos/{id}': put: + summary: Update a video security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json + - Video parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' - - name: id - in: path - required: true - type: string - description: 'The video channel id ' - - in: body - name: body - schema: - $ref: '#/definitions/VideoChannelInput' + - $ref: '#/components/parameters/idOrUUID' responses: '204': description: successful operation + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + thumbnailfile: + description: Video thumbnail file + type: string + format: binary + previewfile: + description: Video preview file + type: string + format: binary + category: + $ref: '#/components/schemas/VideoCategorySet' + licence: + $ref: '#/components/schemas/VideoLicenceSet' + language: + $ref: '#/components/schemas/VideoLanguageSet' + privacy: + $ref: '#/components/schemas/VideoPrivacySet' + description: + description: Video description + type: string + waitTranscoding: + description: Whether or not we wait transcoding before publish the video + type: string + support: + description: A text tell the audience how to support the video creator + example: Please support our work on https://soutenir.framasoft.org/en/ <3 + type: string + nsfw: + description: Whether or not this video contains sensitive content + type: boolean + name: + description: Video name + type: string + minLength: 3 + maxLength: 120 + tags: + description: Video tags (maximum 5 tags each between 2 and 30 characters) + type: array + minItems: 1 + maxItems: 5 + items: + type: string + minLength: 2 + maxLength: 30 + commentsEnabled: + description: Enable or disable comments for this video + type: boolean + originallyPublishedAt: + description: Date when the content was originally published + type: string + format: date-time + scheduleUpdate: + $ref: '#/components/schemas/VideoScheduledUpdate' + encoding: + thumbnailfile: + contentType: image/jpeg + previewfile: + contentType: image/jpeg + get: + summary: Get a video + tags: + - Video + parameters: + - $ref: '#/components/parameters/idOrUUID' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoDetails' delete: + summary: Delete a video security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json + - Video parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' - - name: id - in: path - required: true - type: string - description: 'The video channel id ' + - $ref: '#/components/parameters/idOrUUID' responses: '204': description: successful operation - "/account/{accountId}/video-channels/{id}/videos": + '/videos/{id}/description': get: + summary: Get complete video description tags: - - VideoChannel - consumes: - - application/json - produces: - - application/json + - Video parameters: - - name: accountId - in: path - required: true - type: string - description: 'The account id ' - - name: id - in: path - required: true - type: string - description: 'The video channel id ' + - $ref: '#/components/parameters/idOrUUID' responses: '200': description: successful operation - schema: - $ref: '#/definitions/Video' - "/videos/{videoId}/comment-threads": - get: + content: + application/json: + schema: + nullable: true + type: string + minLength: 3 + maxLength: 10000 + 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)** + '/videos/{id}/views': + post: + summary: Add a view to a video tags: - - VideoComment - consumes: - - application/json - produces: - - application/json + - Video parameters: - - name: videoId - in: path - required: true - type: string - description: 'The video id ' - - name: start - in: query - required: false - type: number - description: 'starting page' - - name: stop - in: query - required: false - type: number - description: 'stopping page' - - name: sort - in: query - required: false - type: number - description: 'sorting' + - $ref: '#/components/parameters/idOrUUID' responses: - '200': + '204': description: successful operation - schema: - $ref: '#/definitions/CommentThreadResponse' + '/videos/{id}/watching': + put: + summary: Set watching progress of a video + tags: + - Video + security: + - OAuth2: [] + parameters: + - $ref: '#/components/parameters/idOrUUID' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserWatchingVideo' + required: true + responses: + '204': + description: successful operation + /videos/upload: post: + summary: Upload a video + description: Uses a single request to upload a video. + operationId: uploadLegacy security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoComment - consumes: - - application/json - produces: - - application/json - parameters: - - name: videoId - in: path - required: true - type: string - description: 'The video id ' + - Video + - Video Upload responses: '200': description: successful operation - schema: - $ref: '#/definitions/CommentThreadPostResponse' - "/videos/{videoId}/comment-threads/{threadId}": - get: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoUploadResponse' + '400': + description: invalid file field, schedule date or parameter + '403': + description: video didn't pass upload filter + '408': + description: upload has timed out + '413': + description: video file too large, due to quota or max body size limit set by the reverse-proxy + headers: + X-File-Maximum-Size: + schema: + type: string + format: Nginx size + description: Maximum file size for the video + '415': + description: video type unsupported + '422': + description: video unreadable + 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_PATH="https://peertube2.cpy.re/api/v1" + ## AUTH + client_id=$(curl -s "$API_PATH/oauth-clients/local" | jq -r ".client_id") + client_secret=$(curl -s "$API_PATH/oauth-clients/local" | jq -r ".client_secret") + token=$(curl -s "$API_PATH/users/token" \ + --data client_id="$client_id" \ + --data client_secret="$client_secret" \ + --data grant_type=password \ + --data response_type=code \ + --data username="$USERNAME" \ + --data password="$PASSWORD" \ + | jq -r ".access_token") + ## VIDEO UPLOAD + curl -s "$API_PATH/videos/upload" \ + -H "Authorization: Bearer $token" \ + --max-time 600 \ + --form videofile=@"$FILE_PATH" \ + --form channelId=$CHANNEL_ID \ + --form name="$NAME" + /videos/upload-resumable: + post: + summary: Initialize the resumable upload of a video + description: Uses [a resumable protocol](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) to initialize the upload of a video + operationId: uploadResumableInit + security: + - OAuth2: [] tags: - - VideoComment - consumes: - - application/json - produces: - - application/json + - Video + - Video Upload parameters: - - name: videoId - in: path + - name: X-Upload-Content-Length + in: header + schema: + type: number + example: 2469036 required: true - type: string - description: 'The video id ' - - name: threadId - in: path + description: Number of bytes that will be uploaded in subsequent requests. Set this value to the size of the file you are uploading. + - name: X-Upload-Content-Type + in: header + schema: + type: string + format: mimetype + example: video/mp4 required: true - type: string - description: 'The thread id ' + description: MIME type of the file that you are uploading. Depending on your instance settings, acceptable values might vary. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoUploadRequestResumable' responses: '200': - description: successful operation - schema: - $ref: '#/definitions/VideoCommentThreadTree' - "/videos/{videoId}/comments/{commentId}": - post: + description: file already exists, send a [`resume`](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) request instead + '201': + description: created + headers: + Location: + schema: + type: string + format: url + example: /api/v1/videos/upload-resumable?upload_id=471e97554f21dec3b8bb5d4602939c51 + Content-Length: + schema: + type: number + example: 0 + '400': + description: invalid file field, schedule date or parameter + '413': + description: video file too large, due to quota, absolute max file size or concurrent partial upload limit + '415': + description: video type unsupported + put: + summary: Send chunk for the resumable upload of a video + description: Uses [a resumable protocol](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) to continue, pause or resume the upload of a video + operationId: uploadResumable security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoComment - consumes: - - application/json - produces: - - application/json + - Video + - Video Upload parameters: - - name: videoId + - name: upload_id in: path required: true - type: string - description: 'The video id ' - - name: commentId - in: path + description: | + Created session id to proceed with. If you didn't send chunks in the last 12 hours, it is + not valid anymore and you need to initialize a new upload. + schema: + type: string + - name: Content-Range + in: header + schema: + type: string + example: bytes 0-262143/2469036 required: true - type: string - description: 'The comment id ' + description: | + Specifies the bytes in the file that the request is uploading. + + For example, a value of `bytes 0-262143/1000000` shows that the request is sending the first + 262144 bytes (256 x 1024) in a 2,469,036 byte file. + - name: Content-Length + in: header + schema: + type: number + example: 262144 + required: true + description: | + Size of the chunk that the request is sending. + + The chunk size __must be a multiple of 256 KB__, and unlike [Google Resumable](https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol) + doesn't mandate for chunks to have the same size throughout the upload sequence. + + 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. + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary responses: '200': - description: successful operation - schema: - $ref: '#/definitions/CommentThreadPostResponse' + description: last chunk received + headers: + Content-Length: + schema: + type: number + content: + application/json: + schema: + $ref: '#/components/schemas/VideoUploadResponse' + '308': + description: resume incomplete + headers: + Range: + schema: + type: string + example: bytes=0-262143 + Content-Length: + schema: + type: number + example: 0 + '403': + description: video didn't pass upload filter + '413': + description: video file too large, due to quota or max body size limit set by the reverse-proxy + '422': + description: video unreadable delete: + summary: Cancel the resumable upload of a video, deleting any data uploaded so far + description: Uses [a resumable protocol](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) to cancel the upload of a video + operationId: uploadResumableCancel security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoComment - consumes: - - application/json - produces: - - application/json + - Video + - Video Upload parameters: - - name: videoId + - name: upload_id in: path required: true - type: string - description: 'The video id ' - - name: commentId - in: path + description: | + Created session id to proceed with. If you didn't send chunks in the last 12 hours, it is + not valid anymore and the upload session has already been deleted with its data ;-) + schema: + type: string + - name: Content-Length + in: header required: true - type: string - description: 'The comment id ' + schema: + type: number + example: 0 responses: '204': + description: upload cancelled + headers: + Content-Length: + schema: + type: number + example: 0 + /videos/imports: + post: + summary: Import a video + description: Import a torrent or magnetURI or HTTP resource (if enabled by the instance administrator) + operationId: importVideo + security: + - OAuth2: [] + tags: + - Video + - 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': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoUploadResponse' + '400': + description: '`magnetUri` or `targetUrl` or a torrent file missing' + '403': + description: video didn't pass pre-import filter + '409': + description: HTTP or Torrent/magnetURI import not enabled + + /videos/live: + post: + summary: Create a live + operationId: createLive + security: + - OAuth2: [] + tags: + - Live Videos + - Video + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoUploadResponse' + '403': + description: live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + channelId: + description: Channel id that will contain this live video + type: integer + saveReplay: + type: boolean + permanentLive: + description: User can stream multiple times in a permanent live + type: boolean + thumbnailfile: + description: Live video/replay thumbnail file + type: string + format: binary + previewfile: + description: Live video/replay preview file + type: string + format: binary + privacy: + $ref: '#/components/schemas/VideoPrivacySet' + category: + $ref: '#/components/schemas/VideoCategorySet' + licence: + $ref: '#/components/schemas/VideoLicenceSet' + language: + $ref: '#/components/schemas/VideoLanguageSet' + description: + description: Live video/replay description + type: string + support: + description: A text tell the audience how to support the creator + example: Please support our work on https://soutenir.framasoft.org/en/ <3 + type: string + nsfw: + description: Whether or not this live video/replay contains sensitive content + type: boolean + name: + description: Live video/replay name + type: string + minLength: 3 + maxLength: 120 + tags: + description: Live video/replay tags (maximum 5 tags each between 2 and 30 characters) + type: array + minItems: 1 + maxItems: 5 + items: + type: string + minLength: 2 + maxLength: 30 + commentsEnabled: + description: Enable or disable comments for this live video/replay + type: boolean + downloadEnabled: + description: Enable or disable downloading for the replay of this live + type: boolean + required: + - channelId + - name + encoding: + thumbnailfile: + contentType: image/jpeg + previewfile: + contentType: image/jpeg + + /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': description: successful operation - "/videos/{id}/rate": + content: + application/json: + schema: + $ref: '#/components/schemas/LiveVideoResponse' put: + summary: Update information about a live + operationId: updateLiveId security: - - OAuth2: [ ] + - OAuth2: [] tags: - - VideoRate - consumes: - - application/json - produces: - - application/json + - Live Videos + - Video parameters: - - name: id - in: path - required: true - type: string - description: 'The video id ' + - $ref: '#/components/parameters/idOrUUID' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LiveVideoUpdate' responses: '204': description: successful operation -definitions: - VideoConstantNumber: - properties: - id: - type: number - label: - type: string - VideoConstantString: - properties: - id: - type: string - label: - type: string - VideoPrivacy: - type: string - enum: [Public, Unlisted, Private] - Video: - properties: - id: - type: number - uuid: - type: string - createdAt: - type: string - publishedAt: - type: string - updatedAt: - type: string - category: - $ref: "#/definitions/VideoConstantNumber" - licence: - $ref: "#/definitions/VideoConstantNumber" - language: - $ref: "#/definitions/VideoConstantString" - privacy: - $ref: "#/definitions/VideoPrivacy" - description: - type: string - duration: - type: number - isLocal: - type: boolean - name: - type: string - thumbnailPath: - type: string - previewPath: - type: string - embedPath: - type: string - views: - type: number - likes: - type: number - dislikes: - type: number - nsfw: - type: boolean - account: - type: object - properties: - name: - type: string - displayName: + '400': + description: bad parameters or trying to update a live that has already started + '403': + description: trying to save replay of the live but saving replay is not enabled on the instance + + /users/me/abuses: + get: + summary: List my abuses + operationId: getMyAbuses + security: + - OAuth2: [] + tags: + - Abuses + - My User + parameters: + - name: id + in: query + description: only list the report with this id + 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': + description: successful operation + content: + application/json: + schema: + type: object + properties: + total: + type: integer + example: 1 + data: + type: array + items: + $ref: '#/components/schemas/Abuse' + + /abuses: + get: + summary: List abuses + operationId: getAbuses + security: + - OAuth2: + - admin + - moderator + tags: + - Abuses + parameters: + - name: id + in: query + description: only list the report with this id + schema: + type: integer + - name: predefinedReason + in: query + description: predefined reason the listed reports should contain + schema: + $ref: '#/components/schemas/PredefinedAbuseReasons' + - name: search + in: query + description: plain search that will match with video titles, reporter names and more + schema: type: string - url: + - name: state + in: query + schema: + $ref: '#/components/schemas/AbuseStateSet' + - name: searchReporter + in: query + description: only list reports of a specific reporter + schema: type: string - host: + - name: searchReportee + description: only list reports of a specific reportee + in: query + schema: type: string - avatar: - $ref: "#/definitions/Avatar" - VideoAbuse: - properties: - id: - type: number - reason: - type: string - reporterAccount: - $ref: "#/definitions/Account" - video: - type: object - properties: - id: - type: number - name: + - name: searchVideo + in: query + description: only list reports of a specific video + schema: type: string - uuid: + - name: searchVideoChannel + in: query + description: only list reports of a specific video channel + schema: type: string - url: + - name: videoIs + in: query + description: only list blacklisted or deleted videos + schema: type: string - createdAt: - type: string - VideoBlacklist: - properties: - id: - type: number - videoId: - type: number - createdAt: - type: string - updatedAt: - type: string - name: - type: string - uuid: - type: string - description: - type: string - duration: - type: number - views: - type: number - likes: - type: number - dislikes: - type: number - nsfw: - type: boolean - VideoChannel: - properties: - displayName: - type: string - description: - type: string - isLocal: - type: boolean - ownerAccount: - type: object - properties: - id: - type: number - uuid: + enum: + - 'deleted' + - 'blacklisted' + - name: filter + in: query + description: only list account, comment or video reports + schema: type: string - VideoComment: - properties: - id: - type: number - url: - type: string - text: - type: string - threadId: - type: number - inReplyToCommentId: - type: number - videoId: - type: number - createdAt: - type: string - updatedAt: - type: string - totalReplies: - type: number - account: - $ref: "#/definitions/Account" - VideoCommentThreadTree: - properties: - comment: - $ref: "#/definitions/VideoComment" - children: - type: array - items: - $ref: "#/definitions/VideoCommentThreadTree" - Avatar: - properties: - path: - type: string - createdAt: - type: string - updatedAt: + enum: + - 'video' + - 'comment' + - 'account' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/abusesSort' + responses: + '200': + description: successful operation + 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 + security: + - OAuth2: [] + tags: + - Abuses + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + reason: + description: Reason why the user reports this video + type: string + minLength: 2 + maxLength: 3000 + predefinedReasons: + $ref: '#/components/schemas/PredefinedAbuseReasons' + video: + type: object + properties: + id: + description: Video id to report + allOf: + - $ref: '#/components/schemas/Video/properties/id' + startAt: + type: integer + format: seconds + description: Timestamp in the video that marks the beginning of the report + minimum: 0 + endAt: + type: integer + format: seconds + description: Timestamp in the video that marks the ending of the report + minimum: 0 + comment: + type: object + properties: + id: + description: Comment id to report + allOf: + - $ref: '#/components/schemas/VideoComment/properties/id' + account: + type: object + properties: + id: + description: Account id to report + type: integer + required: + - reason + responses: + '204': + description: successful operation + '400': + description: incorrect request parameters + '/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 + description: Update the report comment visible only to the moderation team + minLength: 2 + maxLength: 3000 + responses: + '204': + description: successful operation + '404': + description: abuse not found + delete: + tags: + - Abuses + summary: Delete an abuse + security: + - OAuth2: + - admin + - moderator + parameters: + - $ref: '#/components/parameters/abuseId' + responses: + '204': + description: successful operation + '404': + description: block not found + '/abuses/{abuseId}/messages': + get: + summary: List messages of an abuse + security: + - OAuth2: [] + tags: + - Abuses + parameters: + - $ref: '#/components/parameters/abuseId' + responses: + '200': + description: successful operation + content: + application/json: + schema: + 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: + description: Message to send + type: string + minLength: 2 + maxLength: 3000 + required: + - message + responses: + '200': + description: successful operation + '400': + description: incorrect request parameters + '/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': + description: successful operation + + '/videos/{id}/blacklist': + post: + summary: Block a video + security: + - OAuth2: + - admin + - moderator + tags: + - Video Blocks + parameters: + - $ref: '#/components/parameters/idOrUUID' + responses: + '204': + description: successful operation + delete: + summary: Unblock a video by its id + security: + - OAuth2: + - admin + - moderator + tags: + - Video Blocks + parameters: + - $ref: '#/components/parameters/idOrUUID' + responses: + '204': + description: successful operation + '404': + description: block not found + /videos/blacklist: + get: + tags: + - Video Blocks + summary: List video blocks + security: + - OAuth2: + - admin + - moderator + parameters: + - name: type + in: query + description: > + 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 + description: plain search that will match with video titles, and more + schema: + type: string + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/blacklistsSort' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + total: + type: integer + example: 1 + data: + type: array + items: + $ref: '#/components/schemas/VideoBlacklist' + /videos/{id}/captions: + get: + summary: List captions of a video + tags: + - Video Captions + parameters: + - $ref: '#/components/parameters/idOrUUID' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + total: + type: integer + example: 1 + data: + type: array + items: + $ref: '#/components/schemas/VideoCaption' + /videos/{id}/captions/{captionLanguage}: + put: + summary: Add or replace a video caption + 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: + description: The file to upload. + type: string + format: binary + encoding: + captionfile: + contentType: text/vtt, application/x-subrip, text/plain + responses: + '204': + description: successful operation + '404': + description: video or language not found + delete: + summary: Delete a video caption + security: + - OAuth2: + - user + tags: + - Video Captions + parameters: + - $ref: '#/components/parameters/idOrUUID' + - $ref: '#/components/parameters/captionLanguage' + responses: + '204': + description: successful operation + '404': + description: video or language or caption for that language not found + /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': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannelList' + post: + summary: Create a video channel + operationId: createVideoChannel + security: + - OAuth2: [] + tags: + - Video Channels + responses: + '204': + description: successful operation + content: + application/json: + schema: + type: object + properties: + videoChannel: + type: object + properties: + id: + $ref: '#/components/schemas/VideoChannel/properties/id' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannelCreate' + '/video-channels/{channelHandle}': + get: + summary: Get a video channel + operationId: getVideoChannel + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannel' + put: + summary: Update a video channel + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '204': + description: successful operation + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannelUpdate' + delete: + summary: Delete a video channel + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '204': + description: successful operation + '/video-channels/{channelHandle}/videos': + get: + summary: List videos of a video channel + tags: + - Video + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + - $ref: '#/components/parameters/categoryOneOf' + - $ref: '#/components/parameters/isLive' + - $ref: '#/components/parameters/tagsOneOf' + - $ref: '#/components/parameters/tagsAllOf' + - $ref: '#/components/parameters/licenceOneOf' + - $ref: '#/components/parameters/languageOneOf' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/skipCount' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/videosSort' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + '/video-channels/{channelHandle}/avatar/pick': + post: + summary: Update channel avatar + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + avatar: + $ref: '#/components/schemas/ActorImage' + '413': + description: image file too large + headers: + X-File-Maximum-Size: + schema: + type: string + format: Nginx size + description: Maximum file size for the avatar + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + avatarfile: + description: The file to upload. + type: string + format: binary + encoding: + avatarfile: + contentType: image/png, image/jpeg + '/video-channels/{channelHandle}/avatar': + delete: + summary: Delete channel avatar + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '204': + description: successful operation + + + '/video-channels/{channelHandle}/banner/pick': + post: + summary: Update channel banner + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + banner: + $ref: '#/components/schemas/ActorImage' + '413': + description: image file too large + headers: + X-File-Maximum-Size: + schema: + type: string + format: Nginx size + description: Maximum file size for the banner + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + bannerfile: + description: The file to upload. + type: string + format: binary + encoding: + bannerfile: + contentType: image/png, image/jpeg + '/video-channels/{channelHandle}/banner': + delete: + summary: Delete channel banner + security: + - OAuth2: [] + tags: + - Video Channels + parameters: + - $ref: '#/components/parameters/channelHandle' + responses: + '204': + description: successful operation + + /video-playlists/privacies: + get: + summary: List available playlist privacy policies + operationId: getPlaylistPrivacyPolicies + tags: + - Video Playlists + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + type: string + examples: + nightly: + externalValue: https://peertube2.cpy.re/api/v1/video-playlists/privacies + + /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' + responses: + '200': + description: successful operation + 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 + description: If the video playlist is set as public, `videoChannelId` is mandatory. + operationId: createPlaylist + security: + - OAuth2: [] + tags: + - Video Playlists + responses: + '200': + description: successful operation + 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' + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + displayName: + description: Video playlist display name + type: string + minLength: 1 + maxLength: 120 + thumbnailfile: + description: Video playlist thumbnail file + type: string + format: binary + privacy: + $ref: '#/components/schemas/VideoPlaylistPrivacySet' + description: + description: Video playlist description + type: string + minLength: 3 + maxLength: 1000 + videoChannelId: + allOf: + - $ref: '#/components/schemas/id' + description: Video channel in which the playlist will be published + required: + - displayName + encoding: + thumbnailfile: + contentType: image/jpeg + + /video-playlists/{playlistId}: + get: + summary: Get a video playlist + tags: + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoPlaylist' + put: + summary: Update a video playlist + description: 'If the video playlist is set as public, the playlist must have a assigned channel.' + security: + - OAuth2: [] + tags: + - Video Playlists + responses: + '204': + description: successful operation + parameters: + - $ref: '#/components/parameters/playlistId' + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + displayName: + description: Video playlist display name + type: string + minLength: 1 + maxLength: 120 + thumbnailfile: + description: Video playlist thumbnail file + type: string + format: binary + privacy: + $ref: '#/components/schemas/VideoPlaylistPrivacySet' + description: + description: Video playlist description + type: string + videoChannelId: + allOf: + - $ref: '#/components/schemas/id' + description: Video channel in which the playlist will be published + encoding: + thumbnailfile: + contentType: image/jpeg + delete: + summary: Delete a video playlist + security: + - OAuth2: [] + tags: + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + responses: + '204': + description: successful operation + + /video-playlists/{playlistId}/videos: + get: + summary: 'List videos of a playlist' + tags: + - Videos + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + post: + summary: Add a video in a playlist + security: + - OAuth2: [] + tags: + - Videos + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + responses: + '200': + description: successful operation + 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' + description: Video to add in the playlist + startTimestamp: + type: integer + format: seconds + description: Start the video at this specific timestamp + stopTimestamp: + type: integer + format: seconds + description: Stop the video at this specific timestamp + required: + - videoId + + /video-playlists/{playlistId}/videos/reorder: + post: + summary: 'Reorder a playlist' + security: + - OAuth2: [] + tags: + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + responses: + '204': + description: successful operation + requestBody: + content: + application/json: + schema: + type: object + properties: + startPosition: + type: integer + description: 'Start position of the element to reorder' + minimum: 1 + insertAfterPosition: + type: integer + description: 'New position for the block to reorder, to add the block before the first element' + minimum: 0 + reorderLength: + type: integer + description: 'How many element from `startPosition` to reorder' + minimum: 1 + required: + - startPosition + - insertAfterPosition + + /video-playlists/{playlistId}/videos/{playlistElementId}: + put: + summary: Update a playlist element + security: + - OAuth2: [] + tags: + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + - $ref: '#/components/parameters/playlistElementId' + responses: + '204': + description: successful operation + requestBody: + content: + application/json: + schema: + type: object + properties: + startTimestamp: + type: integer + format: seconds + description: Start the video at this specific timestamp + stopTimestamp: + type: integer + format: seconds + description: Stop the video at this specific timestamp + delete: + summary: Delete an element from a playlist + security: + - OAuth2: [] + tags: + - Video Playlists + parameters: + - $ref: '#/components/parameters/playlistId' + - $ref: '#/components/parameters/playlistElementId' + responses: + '204': + description: successful operation + + '/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 + description: The video ids to check + schema: + type: array + items: + $ref: '#/components/schemas/Video/properties/id' + responses: + '200': + description: successful operation + 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 + stopTimestamp: + type: integer + format: seconds + + '/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 + description: include view statistics for the last 30 days (only if authentified as the account user) + schema: + type: boolean + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannelList' + '/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 + description: Optionally filter which ratings to retrieve + schema: + type: string + enum: + - like + - dislike + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/VideoRating' + '/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' + responses: + '200': + description: successful operation + 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': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/CommentThreadPostResponse' + '404': + description: video does not exist + requestBody: + content: + application/json: + schema: + type: object + properties: + text: + allOf: + - $ref: '#/components/schemas/VideoComment/properties/text' + format: markdown + maxLength: 10000 + required: + - text + + '/videos/{id}/comment-threads/{threadId}': + get: + summary: Get a thread + tags: + - Video Comments + parameters: + - $ref: '#/components/parameters/idOrUUID' + - $ref: '#/components/parameters/threadId' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoCommentThreadTree' + '/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' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/CommentThreadPostResponse' + '404': + description: thread or video does not exist + 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': + description: successful operation + '403': + description: cannot remove comment of another user + '404': + description: comment or video does not exist + '409': + description: comment is already deleted + '/videos/{id}/rate': + put: + summary: Like/dislike a video + security: + - OAuth2: [] + tags: + - Video Rates + parameters: + - $ref: '#/components/parameters/idOrUUID' + requestBody: + content: + application/json: + schema: + type: object + properties: + rating: + type: string + enum: + - like + - dislike + required: + - rating + responses: + '204': + description: successful operation + '404': + description: video does not exist + /search/videos: + get: + tags: + - Search + summary: Search videos + parameters: + - name: search + in: query + required: true + allowEmptyValue: false + description: > + 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/categoryOneOf' + - $ref: '#/components/parameters/isLive' + - $ref: '#/components/parameters/tagsOneOf' + - $ref: '#/components/parameters/tagsAllOf' + - $ref: '#/components/parameters/licenceOneOf' + - $ref: '#/components/parameters/languageOneOf' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + - $ref: '#/components/parameters/skipCount' + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/searchTarget' + - $ref: '#/components/parameters/videosSearchSort' + - name: startDate + in: query + description: Get videos that are published after this date + schema: + type: string + format: date-time + - name: endDate + in: query + description: Get videos that are published before this date + schema: + type: string + format: date-time + - name: originallyPublishedStartDate + in: query + description: Get videos that are originally published after this date + schema: + type: string + format: date-time + - name: originallyPublishedEndDate + in: query + description: Get videos that are originally published before this date + schema: + type: string + format: date-time + - name: durationMin + in: query + description: Get videos that have this minimum duration + schema: + type: integer + - name: durationMax + in: query + description: Get videos that have this maximum duration + schema: + type: integer + callbacks: + 'searchTarget === search-index': + $ref: '#/components/callbacks/searchIndex' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse' + '500': + description: search index unavailable + /search/video-channels: + get: + tags: + - Search + summary: Search channels + parameters: + - name: search + in: query + required: true + description: > + 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' + callbacks: + 'searchTarget === search-index': + $ref: '#/components/callbacks/searchIndex' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoChannelList' + '500': + description: search index unavailable + /blocklist/accounts: + get: + tags: + - Account Blocks + summary: List account blocks + security: + - OAuth2: + - admin + parameters: + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' + responses: + '200': + description: successful operation + post: + tags: + - Account Blocks + summary: Block an account + security: + - OAuth2: + - admin + requestBody: + content: + application/json: + schema: + type: object + properties: + accountName: + type: string + example: chocobozzz@example.org + description: account to block, in the form `username@domain` + required: + - accountName + responses: + '200': + description: successful operation + '409': + description: self-blocking forbidden + '/blocklist/accounts/{accountName}': + delete: + tags: + - Account Blocks + summary: Unblock an account by its handle + security: + - OAuth2: + - admin + parameters: + - name: accountName + in: path + required: true + description: account to unblock, in the form `username@domain` + schema: + type: string + responses: + '201': + description: successful operation + '404': + description: account or account block does not exist + /blocklist/servers: + get: + tags: + - Server Blocks + summary: List server blocks + security: + - OAuth2: + - admin + parameters: + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/sort' + responses: + '200': + description: successful operation + post: + tags: + - Server Blocks + summary: Block a server + security: + - OAuth2: + - admin + requestBody: + content: + application/json: + schema: + type: object + properties: + host: + type: string + format: hostname + description: server domain to block + required: + - host + responses: + '200': + description: successful operation + '409': + description: self-blocking forbidden + '/blocklist/servers/{host}': + delete: + tags: + - Server Blocks + summary: Unblock a server by its domain + security: + - OAuth2: + - admin + parameters: + - name: host + in: path + required: true + description: server domain to unblock + schema: + type: string + format: hostname + responses: + '201': + description: successful operation + '404': + description: account block does not exist + /redundancy/{host}: + put: + tags: + - Instance Redundancy + summary: Update a server redundancy policy + security: + - OAuth2: + - admin + parameters: + - name: host + in: path + required: true + description: server domain to mirror + schema: + type: string + format: hostname + requestBody: + content: + application/json: + schema: + type: object + properties: + redundancyAllowed: + type: boolean + description: allow mirroring of the host's local videos + required: + - redundancyAllowed + responses: + '204': + description: successful operation + '404': + description: server is not already known + /redundancy/videos: + get: + tags: + - Video Mirroring + summary: List videos being mirrored + security: + - OAuth2: + - admin + parameters: + - name: target + in: query + required: true + description: direction of the mirror + schema: + type: string + enum: + - my-videos + - remote-videos + - $ref: '#/components/parameters/start' + - $ref: '#/components/parameters/count' + - $ref: '#/components/parameters/videoRedundanciesSort' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/VideoRedundancy' + post: + tags: + - Video Mirroring + summary: Mirror a video + security: + - OAuth2: + - admin + requestBody: + content: + application/json: + schema: + type: object + properties: + videoId: + $ref: '#/components/schemas/Video/properties/id' + required: + - videoId + responses: + '204': + description: successful operation + '400': + description: cannot mirror a local video + '404': + description: video does not exist + '409': + description: video is already mirrored + /redundancy/videos/{redundancyId}: + delete: + tags: + - Video Mirroring + summary: Delete a mirror done on a video + security: + - OAuth2: + - admin + parameters: + - name: redundancyId + in: path + required: true + description: id of an existing redundancy on a video + schema: + type: string + responses: + '204': + description: successful operation + '404': + description: video redundancy not found + '/feeds/video-comments.{format}': + get: + tags: + - Feeds + summary: List comments on videos + parameters: + - name: format + in: path + required: true + description: 'format expected (we focus on making `rss` the most featureful ; it serves [Media RSS](https://www.rssboard.org/media-rss))' + schema: + type: string + enum: + - xml + - rss + - rss2 + - atom + - atom1 + - json + - json1 + - name: videoId + in: query + description: 'limit listing to a specific video' + schema: + type: string + - name: accountId + in: query + description: 'limit listing to a specific account' + schema: + type: string + - name: accountName + in: query + description: 'limit listing to a specific account' + schema: + type: string + - name: videoChannelId + in: query + description: 'limit listing to a specific video channel' + schema: + type: string + - name: videoChannelName + in: query + description: 'limit listing to a specific video channel' + schema: + type: string + responses: + '204': + description: successful operation + 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?filter=local + application/rss+xml: + schema: + $ref: '#/components/schemas/VideoCommentsForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/video-comments.rss?filter=local + text/xml: + schema: + $ref: '#/components/schemas/VideoCommentsForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/video-comments.xml?filter=local + application/atom+xml: + schema: + $ref: '#/components/schemas/VideoCommentsForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/video-comments.atom?filter=local + application/json: + schema: + type: object + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/video-comments.json?filter=local + '400': + x-summary: field inconsistencies + description: > + Arises when: + - videoId filter is mixed with a channel filter + '404': + description: video, video channel or account not found + '406': + description: accept header unsupported + '/feeds/videos.{format}': + get: + tags: + - Feeds + summary: List videos + parameters: + - name: format + in: path + required: true + description: 'format expected (we focus on making `rss` the most featureful ; it serves [Media RSS](https://www.rssboard.org/media-rss))' + schema: + type: string + enum: + - xml + - rss + - rss2 + - atom + - atom1 + - json + - json1 + - name: accountId + in: query + description: 'limit listing to a specific account' + schema: + type: string + - name: accountName + in: query + description: 'limit listing to a specific account' + schema: + type: string + - name: videoChannelId + in: query + description: 'limit listing to a specific video channel' + schema: + type: string + - name: videoChannelName + in: query + description: 'limit listing to a specific video channel' + schema: + type: string + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + responses: + '204': + description: successful operation + 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?filter=local + application/rss+xml: + schema: + $ref: '#/components/schemas/VideosForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/videos.rss?filter=local + text/xml: + schema: + $ref: '#/components/schemas/VideosForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/videos.xml?filter=local + application/atom+xml: + schema: + $ref: '#/components/schemas/VideosForXML' + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/videos.atom?filter=local + application/json: + schema: + type: object + examples: + nightly: + externalValue: https://peertube2.cpy.re/feeds/videos.json?filter=local + '404': + description: video channel or account not found + '406': + description: accept header unsupported + '/feeds/subscriptions.{format}': + get: + tags: + - Feeds + - Account + summary: List videos of subscriptions tied to a token + parameters: + - name: format + in: path + required: true + description: 'format expected (we focus on making `rss` the most featureful ; it serves [Media RSS](https://www.rssboard.org/media-rss))' + schema: + type: string + enum: + - xml + - rss + - rss2 + - atom + - atom1 + - json + - json1 + - name: accountId + in: query + description: limit listing to a specific account + schema: + type: string + required: true + - name: token + in: query + description: private token allowing access + schema: + type: string + required: true + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/nsfw' + - $ref: '#/components/parameters/filter' + responses: + '204': + description: successful operation + 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': + description: accept header unsupported + /plugins: + get: + tags: + - Plugins + summary: List plugins + 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': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/PluginResponse' + /plugins/available: + get: + tags: + - Plugins + summary: List available plugins + 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': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/PluginResponse' + '503': + description: plugin index unavailable + /plugins/install: + post: + tags: + - Plugins + summary: Install a plugin + 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': + description: successful operation + '400': + description: should have either `npmName` or `path` set + /plugins/update: + post: + tags: + - Plugins + summary: Update a plugin + 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': + description: successful operation + '400': + description: should have either `npmName` or `path` set + '404': + description: existing plugin not found + /plugins/uninstall: + post: + tags: + - Plugins + summary: Uninstall a plugin + security: + - OAuth2: + - admin + requestBody: + content: + application/json: + schema: + type: object + properties: + npmName: + type: string + description: name of the plugin/theme in its package.json + example: peertube-plugin-auth-ldap + required: + - npmName + responses: + '204': + description: successful operation + '404': + description: existing plugin not found + /plugins/{npmName}: + get: + tags: + - Plugins + summary: Get a plugin + security: + - OAuth2: + - admin + parameters: + - $ref: '#/components/parameters/npmName' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Plugin' + '404': + description: plugin not found + /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': + description: successful operation + '404': + description: plugin not found + /plugins/{npmName}/public-settings: + get: + tags: + - Plugins + summary: Get a plugin's public settings + parameters: + - $ref: '#/components/parameters/npmName' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: true + '404': + description: plugin not found + /plugins/{npmName}/registered-settings: + get: + tags: + - Plugins + summary: Get a plugin's registered settings + security: + - OAuth2: + - admin + parameters: + - $ref: '#/components/parameters/npmName' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: true + '404': + description: plugin not found +servers: + - url: 'https://peertube2.cpy.re/api/v1' + description: Live Test Server (live data - latest nightly version) + - url: 'https://peertube3.cpy.re/api/v1' + description: Live Test Server (live data - latest RC version) + - url: 'https://peertube.cpy.re/api/v1' + description: Live Test Server (live data - stable version) +components: + parameters: + start: + name: start + in: query + required: false + description: Offset used to paginate results + schema: + type: integer + minimum: 0 + count: + name: count + in: query + required: false + description: "Number of items to return" + schema: + type: integer + default: 15 + maximum: 100 + minimum: 1 + sort: + name: sort + in: query + required: false + description: Sort column + schema: + type: string + example: -createdAt + search: + name: search + in: query + required: false + description: Plain text search, applied to various parts of the model depending on endpoint + schema: + type: string + searchTarget: + name: searchTarget + in: query + required: false + description: > + 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 - Actor: - properties: - id: - type: number - uuid: + enum: + - 'local' + - 'search-index' + videosSort: + name: sort + in: query + required: false + description: Sort videos by criteria + schema: type: string - url: + enum: + - name + - -duration + - -createdAt + - -publishedAt + - -views + - -likes + - -trending + - -hot + videosSearchSort: + name: sort + in: query + required: false + description: Sort videos by criteria + schema: type: string - name: + enum: + - name + - -duration + - -createdAt + - -publishedAt + - -views + - -likes + - -match + commentsSort: + name: sort + in: query + required: false + description: Sort comments by criteria + schema: type: string - host: + enum: + - -createdAt + - -totalReplies + blacklistsSort: + name: sort + in: query + required: false + description: Sort blacklists by criteria + schema: type: string - followingCount: - type: number - followersCount: - type: number - createdAt: + enum: + - -id + - name + - -duration + - -views + - -likes + - -dislikes + - -uuid + - -createdAt + usersSearch: + name: search + in: query + required: false + description: Plain text search that will match with user usernames or emails + schema: + type: string + usersBlocked: + name: blocked + in: query + required: false + description: Filter results down to (un)banned users + schema: + type: boolean + usersSort: + name: sort + in: query + required: false + description: Sort users by criteria + schema: + type: string + enum: + - -id + - -username + - -createdAt + abusesSort: + name: sort + in: query + required: false + description: Sort abuses by criteria + schema: + type: string + enum: + - -id + - -createdAt + - -state + videoRedundanciesSort: + name: sort + in: query + required: false + description: Sort abuses by criteria + schema: + type: string + enum: + - name + name: + name: name + in: path + required: true + description: The username or handle of the account + schema: + type: string + example: chocobozzz | chocobozzz@example.org + id: + name: id + in: path + required: true + description: The user id + schema: + $ref: '#/components/schemas/id' + idOrUUID: + name: id + in: path + required: true + description: The object id or uuid + schema: + oneOf: + - $ref: '#/components/schemas/id' + - $ref: '#/components/schemas/UUIDv4' + playlistId: + name: playlistId + in: path + required: true + description: Playlist id + schema: + $ref: '#/components/schemas/VideoPlaylist/properties/id' + playlistElementId: + name: playlistElementId + in: path + required: true + description: Playlist element id + schema: + $ref: '#/components/schemas/id' + abuseId: + name: abuseId + in: path + required: true + description: Abuse id + schema: + $ref: '#/components/schemas/Abuse/properties/id' + abuseMessageId: + name: abuseMessageId + in: path + required: true + description: Abuse message id + schema: + $ref: '#/components/schemas/AbuseMessage/properties/id' + captionLanguage: + name: captionLanguage + in: path + required: true + description: The caption language + schema: + $ref: '#/components/schemas/VideoLanguageSet' + channelHandle: + name: channelHandle + in: path + required: true + description: The video channel handle + schema: + type: string + example: my_username | my_username@example.com + subscriptionHandle: + name: subscriptionHandle + in: path + required: true + description: The subscription handle + schema: + type: string + example: my_username | my_username@example.com + threadId: + name: threadId + in: path + required: true + description: The thread id (root comment id) + schema: + $ref: '#/components/schemas/VideoCommentThreadTree/properties/comment/properties/id' + commentId: + name: commentId + in: path + required: true + description: The comment id + schema: + $ref: '#/components/schemas/VideoComment/properties/id' + isLive: + name: isLive + in: query + required: false + description: whether or not the video is a live + schema: + type: boolean + categoryOneOf: + name: categoryOneOf + in: query + required: false + description: category id of the video (see [/videos/categories](#operation/getCategories)) + schema: + oneOf: + - $ref: '#/components/schemas/VideoCategorySet' + - type: array + items: + $ref: '#/components/schemas/VideoCategorySet' + style: form + explode: false + tagsOneOf: + name: tagsOneOf + in: query + required: false + description: tag(s) of the video + schema: + oneOf: + - type: string + - type: array + maxItems: 5 + items: + type: string + style: form + explode: false + tagsAllOf: + name: tagsAllOf + in: query + required: false + description: tag(s) of the video, where all should be present in the video + schema: + oneOf: + - type: string + - type: array + items: + type: string + style: form + explode: false + languageOneOf: + name: languageOneOf + in: query + required: false + description: language id of the video (see [/videos/languages](#operation/getLanguages)). Use `_unknown` to filter on videos that don't have a video language + schema: + oneOf: + - $ref: '#/components/schemas/VideoLanguageSet' + - type: array + items: + $ref: '#/components/schemas/VideoLanguageSet' + style: form + explode: false + licenceOneOf: + name: licenceOneOf + in: query + required: false + description: licence id of the video (see [/videos/licences](#operation/getLicences)) + schema: + oneOf: + - $ref: '#/components/schemas/VideoLicenceSet' + - type: array + items: + $ref: '#/components/schemas/VideoLicenceSet' + style: form + explode: false + skipCount: + name: skipCount + in: query + required: false + description: if you don't need the `total` in the response + schema: + type: string + enum: + - 'true' + - 'false' + default: 'false' + nsfw: + name: nsfw + in: query + required: false + description: whether to include nsfw videos, if any + schema: + type: string + enum: + - 'true' + - 'false' + filter: + name: filter + in: query + required: false + description: > + Special filters which might require special rights: + * `local` - only videos local to the instance + * `all-local` - only videos local to the instance, but showing private and unlisted videos (requires Admin privileges) + * `all` - all videos, showing private and unlisted videos (requires Admin privileges) + schema: + type: string + enum: + - local + - all-local + subscriptionsUris: + name: uris + in: query + required: true + description: list of uris to check if each is part of the user subscriptions + schema: + type: array + items: + type: string + format: uri + npmName: + name: npmName + in: path + required: true + description: name of the plugin/theme on npmjs.com or in its package.json + schema: + type: string + example: peertube-plugin-auth-ldap + jobType: + name: jobType + in: query + required: false + description: job type + schema: + type: string + enum: + - activitypub-follow + - activitypub-http-broadcast + - activitypub-http-fetcher + - activitypub-http-unicast + - email + - video-transcoding + - video-file-import + - video-import + - videos-views + - activitypub-refresher + - video-redundancy + - video-live-ending + securitySchemes: + OAuth2: + description: | + Authenticating via OAuth requires the following steps: + - Have an activated account + - [Generate](https://docs.joinpeertube.org/api-rest-getting-started) a + Bearer Token for that account at `/api/v1/users/token` + - Make authenticated requests, putting *Authorization: Bearer * + - Profit, depending on the role assigned to the account + + Note that the __access token is valid for 1 day__ and, and is given + along with a __refresh token valid for 2 weeks__. + type: oauth2 + flows: + password: + tokenUrl: 'https://peertube.example.com/api/v1/users/token' + scopes: + admin: Admin scope + moderator: Moderator scope + user: User scope + schemas: + # Resuable 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 + username: + type: string + description: immutable name of the user, used to find or mention its actor + example: chocobozzz + pattern: '/^[a-z0-9._]{1,50}$/' + minLength: 1 + maxLength: 50 + usernameChannel: + type: string + description: immutable name of the channel, used to interact with its actor + example: framasoft_videos + pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' + password: + type: string + format: password + minLength: 6 + maxLength: 255 + + VideoCategorySet: + type: integer + description: category id of the video (see [/videos/categories](#operation/getCategories)) + example: 15 + VideoConstantNumber-Category: + properties: + id: + $ref: '#/components/schemas/VideoCategorySet' + label: + type: string + example: Science & Technology + + VideoLicenceSet: + type: integer + description: licence id of the video (see [/videos/licences](#operation/getLicences)) + example: 2 + VideoConstantNumber-Licence: + properties: + id: + $ref: '#/components/schemas/VideoLicenceSet' + label: + type: string + example: Attribution - Share Alike + + VideoLanguageSet: + type: string + description: language id of the video (see [/videos/languages](#operation/getLanguages)) + example: en + VideoConstantString-Language: + properties: + id: + $ref: '#/components/schemas/VideoLanguageSet' + label: + type: string + example: English + + VideoPlaylistPrivacySet: + type: integer + enum: + - 1 + - 2 + - 3 + description: Video playlist privacy policy (see [/video-playlists/privacies]) + VideoPlaylistPrivacyConstant: + properties: + id: + $ref: '#/components/schemas/VideoPlaylistPrivacySet' + label: + type: string + + VideoPlaylistTypeSet: + type: integer + enum: + - 1 + - 2 + description: The video playlist type (Regular = `1`, Watch Later = `2`) + VideoPlaylistTypeConstant: + properties: + id: + $ref: '#/components/schemas/VideoPlaylistTypeSet' + label: + type: string + + VideoPrivacySet: + type: integer + enum: + - 1 + - 2 + - 3 + - 4 + description: privacy id of the video (see [/videos/privacies](#operation/getPrivacyPolicies)) + VideoPrivacyConstant: + properties: + id: + $ref: '#/components/schemas/VideoPrivacySet' + label: + type: string + + NSFWPolicy: + type: string + enum: + - display + - blur + - do_not_list + + UserRole: + type: integer + enum: + - 0 + - 1 + - 2 + description: 'The user role (Admin = `0`, Moderator = `1`, User = `2`)' + example: 2 + UserAdminFlags: + type: integer + enum: + - 0 + - 1 + description: 'Admin flags for the user (None = `0`, Bypass video blacklist = `1`)' + example: 1 + + VideoStateConstant: + properties: + id: + type: integer + enum: + - 1 + - 2 + - 3 + description: 'The video state (Published = `1`, to transcode = `2`, to import = `3`)' + label: + type: string + + AbuseStateSet: + type: integer + enum: + - 1 + - 2 + - 3 + description: 'The abuse state (Pending = `1`, Rejected = `2`, Accepted = `3`)' + AbuseStateConstant: + properties: + id: + $ref: '#/components/schemas/AbuseStateSet' + label: + type: string + AbusePredefinedReasons: + type: array + items: type: string - updatedAt: + enum: + - violentOrAbusive + - hatefulOrAbusive + - spamOrMisleading + - privacy + - rights + - serverRules + - thumbnails + - captions + example: [spamOrMisleading] + + VideoResolutionSet: + type: integer + description: | + 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: + description: resolutions and their labels for the video + properties: + id: + $ref: '#/components/schemas/VideoResolutionSet' + label: + type: string + example: 240p + VideoScheduledUpdate: + properties: + privacy: + $ref: '#/components/schemas/VideoPrivacySet' + updateAt: + type: string + format: date + description: When to update the video + required: + - updateAt + AccountSummary: + properties: + id: + type: integer + name: + type: string + displayName: + type: string + url: + type: string + format: url + host: + type: string + format: hostname + avatar: + nullable: true + allOf: + - $ref: '#/components/schemas/ActorImage' + VideoChannelSummary: + properties: + id: + $ref: '#/components/schemas/id' + name: + type: string + displayName: + type: string + url: + type: string + format: url + host: + type: string + format: hostname + avatar: + nullable: true + allOf: + - $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' + VideoFile: + readOnly: true + properties: + magnetUri: + type: string + format: uri + description: magnet URI allowing to resolve the video via BitTorrent without a metainfo file + example: magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F9c9de5e8-0a1e-484a-b099-e80766180a6d-240.torrent&xt=urn:btih:38b4747ff788b30bf61f59d1965cd38f9e48e01f&dn=What+is+PeerTube%3F&tr=wss%3A%2F%2Fframatube.org%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F9c9de5e8-0a1e-484a-b099-e80766180a6d-240.mp4 + pattern: /magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i + resolution: + $ref: '#/components/schemas/VideoResolutionConstant' + size: + type: integer + description: Video file size in bytes + torrentUrl: + type: string + description: Direct URL of the torrent file + format: url + torrentDownloadUrl: + type: string + description: URL endpoint that transfers the torrent file as an attachment (so that the browser opens a download dialog) + format: url + fileUrl: + type: string + description: Direct URL of the video + format: url + fileDownloadUrl: + type: string + description: URL endpoint that transfers the video file as an attachment (so that the browser opens a download dialog) + format: url + fps: + type: number + description: Frames per second of the video file + metadataUrl: + type: string + format: url + description: URL dereferencing the output of ffprobe on the file + VideoStreamingPlaylists: + allOf: + - type: object + properties: + id: + $ref: '#/components/schemas/id' + type: + type: integer + enum: + - 1 + description: | + 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 + description: | + 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' + Video: + properties: + id: + description: object id for the video + allOf: + - $ref: '#/components/schemas/id' + uuid: + description: universal identifier for the video, that can be used across instances + allOf: + - $ref: '#/components/schemas/UUIDv4' + isLive: + type: boolean + createdAt: + type: string + format: date-time + example: 2017-10-01T10:52:46.396Z + description: time at which the video object was first drafted + publishedAt: + type: string + format: date-time + example: 2018-10-01T10:52:46.396Z + description: time at which the video was marked as ready for playback (with restrictions depending on `privacy`). Usually set after a `state` evolution. + updatedAt: + type: string + format: date-time + example: 2021-05-04T08:01:01.502Z + description: last time the video's metadata was modified + originallyPublishedAt: + type: string + format: date-time + example: 2010-10-01T10:52:46.396Z + description: used to represent a date of first publication, prior to the practical publication date of `publishedAt` + category: + allOf: + - $ref: '#/components/schemas/VideoConstantNumber-Category' + description: category in which the video is classified + licence: + allOf: + - $ref: '#/components/schemas/VideoConstantNumber-Licence' + description: licence under which the video is distributed + language: + allOf: + - $ref: '#/components/schemas/VideoConstantString-Language' + description: main language used in the video + privacy: + allOf: + - $ref: '#/components/schemas/VideoPrivacyConstant' + description: privacy policy used to distribute the video + description: + 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)**\r\n*A decentralized video hosting network, based on fr... + minLength: 3 + maxLength: 250 + description: | + truncated description of the video, written in Markdown. + Resolve `descriptionPath` to get the full description of maximum `10000` characters. + duration: + type: integer + example: 1419 + format: seconds + description: duration of the video in seconds + isLocal: + type: boolean + name: + type: string + description: title of the video + example: What is PeerTube? + minLength: 3 + maxLength: 120 + thumbnailPath: + type: string + example: /static/thumbnails/a65bc12f-9383-462e-81ae-8207e8b434ee.jpg + previewPath: + type: string + example: /lazy-static/previews/a65bc12f-9383-462e-81ae-8207e8b434ee.jpg + 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 + nsfw: + type: boolean + waitTranscoding: + type: boolean + nullable: true + state: + allOf: + - $ref: '#/components/schemas/VideoStateConstant' + description: represents the internal state of the video processing within the PeerTube instance + 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 + VideoDetails: + allOf: + - $ref: '#/components/schemas/Video' + - type: object + properties: + descriptionPath: + type: string + example: /api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d/description + description: path at which to get the full description of maximum `10000` characters + support: + type: string + description: A text tell the audience how to support the video creator + 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 + commentsEnabled: + type: boolean + downloadEnabled: + type: boolean + trackerUrls: + type: array + 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' + description: | + WebTorrent/raw video files. If WebTorrent 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' + description: | + 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: + files: + type: array + items: + $ref: '#/components/schemas/FileRedundancyInformation' + streamingPlaylists: + type: array + items: + $ref: '#/components/schemas/FileRedundancyInformation' + VideoImportStateConstant: + properties: + id: + type: integer + enum: + - 1 + - 2 + - 3 + description: 'The video import state (Pending = `1`, Success = `2`, Failed = `3`)' + 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: + readOnly: true + allOf: + - $ref: '#/components/schemas/id' + targetUrl: + type: string + format: url + description: remote URL where to find the import's source video + example: https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d + magnetUri: + type: string + format: uri + description: magnet URI allowing to resolve the import's source video + example: magnet:?xs=https%3A%2F%2Fframatube.org%2Fstatic%2Ftorrents%2F9c9de5e8-0a1e-484a-b099-e80766180a6d-240.torrent&xt=urn:btih:38b4747ff788b30bf61f59d1965cd38f9e48e01f&dn=What+is+PeerTube%3F&tr=wss%3A%2F%2Fframatube.org%2Ftracker%2Fsocket&tr=https%3A%2F%2Fframatube.org%2Ftracker%2Fannounce&ws=https%3A%2F%2Fframatube.org%2Fstatic%2Fwebseed%2F9c9de5e8-0a1e-484a-b099-e80766180a6d-240.mp4 + pattern: /magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i + torrentfile: + writeOnly: true + type: string + format: binary + description: Torrent file containing only the video file + torrentName: + readOnly: true + type: string + state: + readOnly: true + allOf: + - $ref: '#/components/schemas/VideoImportStateConstant' + error: + readOnly: true + type: string + createdAt: + readOnly: true + type: string + format: date-time + updatedAt: + readOnly: true + type: string + format: date-time + video: + readOnly: true + 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: + $ref: '#/components/schemas/VideoInfo' + 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: + properties: + id: + $ref: '#/components/schemas/id' + videoId: + $ref: '#/components/schemas/Video/properties/id' + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + name: + type: string + minLength: 3 + maxLength: 120 + uuid: + $ref: '#/components/schemas/UUIDv4' + description: + type: string + minLength: 3 + maxLength: 10000 + duration: + type: integer + views: + type: integer + likes: + type: integer + dislikes: + type: integer + nsfw: + type: boolean + VideoPlaylist: + properties: + id: + $ref: '#/components/schemas/id' + uuid: + $ref: '#/components/schemas/UUIDv4' + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + description: + type: string + minLength: 3 + maxLength: 1000 + displayName: + type: string + minLength: 1 + maxLength: 120 + isLocal: + type: boolean + videoLength: + type: integer + minimum: 0 + thumbnailPath: + type: string + privacy: + $ref: '#/components/schemas/VideoPlaylistPrivacyConstant' + type: + $ref: '#/components/schemas/VideoPlaylistTypeConstant' + ownerAccount: + $ref: '#/components/schemas/AccountSummary' + videoChannel: + $ref: '#/components/schemas/VideoChannelSummary' + VideoComment: + properties: + id: + $ref: '#/components/schemas/id' + url: + type: string + format: url + text: + type: string + format: html + description: Text of the comment + 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 + 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 + items: + $ref: '#/components/schemas/VideoCommentThreadTree' + VideoCaption: + properties: + language: + $ref: '#/components/schemas/VideoConstantString-Language' + captionPath: + type: string + ActorImage: + properties: + path: + type: string + 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 + avatar: + nullable: true + type: object + properties: + path: + type: string + Actor: + properties: + id: + $ref: '#/components/schemas/id' + url: + type: string + format: url + name: + description: immutable name of the actor, used to find or mention it + allOf: + - $ref: '#/components/schemas/username' + host: + type: string + format: hostname + description: server on which the actor is resident + hostRedundancyAllowed: + type: boolean + description: whether this actor's host allows redundancy of its videos + followingCount: + type: integer + minimum: 0 + description: number of actors subscribed to by this actor, as seen by this instance + followersCount: + type: integer + minimum: 0 + description: number of followers of this actor, as seen by this instance + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + avatar: + $ref: '#/components/schemas/ActorImage' + Account: + allOf: + - $ref: '#/components/schemas/Actor' + - properties: + userId: + description: object id for the user tied to this account + allOf: + - $ref: '#/components/schemas/User/properties/id' + displayName: + type: string + description: editable name of the account, displayed in its representations + minLength: 3 + maxLength: 120 + description: + type: string + description: text or bio displayed on the account's profile + UserWatchingVideo: + properties: + currentTime: + type: integer + format: seconds + description: timestamp within the video, in seconds + example: 5 + ServerConfig: + properties: + instance: + type: object + properties: + name: + type: string + shortDescription: + type: string + defaultClientRoute: + type: string + isNSFW: + type: boolean + defaultNSFWPolicy: + type: string + customizations: + type: object + properties: + javascript: + type: string + css: + type: string + 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 + webtorrent: + 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 + autoBlacklist: + type: object + properties: + videos: + type: object + properties: + ofUsers: + 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 + ServerConfigAbout: + properties: + instance: + type: object + properties: + name: + type: string + shortDescription: + type: string + description: + type: string + terms: + type: string + ServerConfigCustom: + properties: + instance: + type: object + properties: + name: + type: string + shortDescription: + type: string + description: + type: string + terms: + type: string + defaultClientRoute: + type: string + isNSFW: + type: boolean + defaultNSFWPolicy: + 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 + whitelisted: + type: boolean + 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 + description: Settings that apply to new users, if registration is enabled + properties: + videoQuota: + type: integer + example: 16810141515 + videoQuotaDaily: + type: integer + example: 1681014151 + transcoding: + type: object + description: Settings pertaining to transcoding jobs + properties: + enabled: + type: boolean + allowAdditionalExtensions: + type: boolean + description: Allow your users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, m2ts, .mxf, .nut videos + allowAudioFiles: + type: boolean + description: If a user uploads an audio file, PeerTube will create a video by merging the preview file and the audio file + threads: + type: integer + description: Amount of threads used by ffmpeg for 1 transcoding job + concurrency: + type: number + description: Amount of transcoding jobs to execute in parallel + profile: + type: string + enum: + - default + description: | + New profiles can be added by plugins ; available in core PeerTube: 'default'. + resolutions: + type: object + description: Resolutions to transcode _new videos_ to + properties: + 0p: + type: boolean + 240p: + type: boolean + 360p: + type: boolean + 480p: + type: boolean + 720p: + type: boolean + 1080p: + type: boolean + 1440p: + type: boolean + 2160p: + type: boolean + webtorrent: + type: object + description: WebTorrent-specific settings + properties: + enabled: + type: boolean + hls: + type: object + description: HLS-specific settings + properties: + enabled: + type: boolean + import: + type: object + properties: + videos: + type: object + properties: + http: + type: object + properties: + enabled: + type: boolean + torrent: + type: object + properties: + enabled: + type: boolean + autoBlacklist: + type: object + properties: + videos: + type: object + properties: + ofUsers: + type: object + properties: + enabled: + type: boolean + followers: + type: object + properties: + instance: + type: object + properties: + enabled: + type: boolean + manualApproval: + type: boolean + Follow: + properties: + id: + $ref: '#/components/schemas/id' + follower: + $ref: '#/components/schemas/Actor' + following: + $ref: '#/components/schemas/Actor' + score: + type: number + description: score reflecting the reachability of the actor, with steps of `10` and a base score of `1000`. + state: + type: string + enum: + - pending + - accepted + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + + PredefinedAbuseReasons: + description: Reason categories that help triage reports + type: array + maxItems: 8 + items: type: string - avatar: - $ref: "#/definitions/Avatar" - Account: - allOf: - - $ref: "#/definitions/Actor" - - properties: - displayName: + enum: + - violentOrAbusive + - hatefulOrAbusive + - spamOrMisleading + - privacy + - rights + - serverRules + - thumbnails + - captions + + Job: + properties: + id: + $ref: '#/components/schemas/id' + state: + type: string + enum: + - active + - completed + - failed + - waiting + - delayed + type: + type: string + enum: + - activitypub-http-unicast + - activitypub-http-broadcast + - activitypub-http-fetcher + - activitypub-follow + - video-file-import + - video-transcoding + - email + - video-import + - videos-views + - activitypub-refresher + - video-redundancy + 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 + AddUserResponse: + properties: + user: + type: object + properties: + id: + $ref: '#/components/schemas/id' + account: + type: object + properties: + id: + $ref: '#/components/schemas/id' + VideoUploadRequestCommon: + properties: + name: + description: Video name + type: string + example: What is PeerTube? + minLength: 3 + maxLength: 120 + channelId: + description: Channel id that will contain this video + 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' + description: + description: Video description + 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: + description: Whether or not we wait transcoding before publish the video + type: boolean + support: + description: A text tell the audience how to support the video creator + example: Please support our work on https://soutenir.framasoft.org/en/ <3 + type: string + nsfw: + description: Whether or not this video contains sensitive content + type: boolean + tags: + description: Video tags (maximum 5 tags each between 2 and 30 characters) + type: array + minItems: 1 + maxItems: 5 + uniqueItems: true + example: + - framasoft + - peertube + items: type: string - User: - properties: - id: - type: number - username: - type: string - email: - type: string - displayNSFW: - type: boolean - autoPlayVideo: - type: boolean - role: - type: string - enum: [User, Moderator, Administrator] - videoQuota: - type: number - createdAt: - type: string - account: - $ref: "#/definitions/Account" - videoChannels: - type: array - items: - $ref: "#/definitions/VideoChannel" - ServerConfig: - properties: - signup: - type: object - properties: - allowed: - type: boolean - transcoding: + minLength: 2 + maxLength: 30 + commentsEnabled: + description: Enable or disable comments for this video + type: boolean + downloadEnabled: + description: Enable or disable downloading for this video + type: boolean + originallyPublishedAt: + description: Date when the content was originally published + type: string + format: date-time + scheduleUpdate: + $ref: '#/components/schemas/VideoScheduledUpdate' + thumbnailfile: + description: Video thumbnail file + type: string + format: binary + previewfile: + description: Video preview file + type: string + format: binary + required: + - channelId + - name + VideoUploadRequestLegacy: + allOf: + - $ref: '#/components/schemas/VideoUploadRequestCommon' + - type: object + required: + - videofile + properties: + videofile: + description: Video file + type: string + format: binary + VideoUploadRequestResumable: + allOf: + - $ref: '#/components/schemas/VideoUploadRequestCommon' + - type: object + required: + - filename + properties: + filename: + description: Video filename including extension + type: string + format: filename + example: what_is_peertube.mp4 + thumbnailfile: + description: Video thumbnail file + type: string + format: binary + previewfile: + description: Video preview file + type: string + format: binary + VideoUploadResponse: + properties: + video: + type: object + properties: + id: + $ref: '#/components/schemas/Video/properties/id' + uuid: + $ref: '#/components/schemas/Video/properties/uuid' + CommentThreadResponse: + properties: + total: + type: integer + example: 1 + data: + type: array + maxItems: 100 + items: + $ref: '#/components/schemas/VideoComment' + CommentThreadPostResponse: + properties: + comment: + $ref: '#/components/schemas/VideoComment' + VideoListResponse: + properties: + total: + type: integer + example: 1 + data: + type: array + maxItems: 100 + items: + $ref: '#/components/schemas/Video' + User: + properties: + account: + $ref: '#/components/schemas/Account' + autoPlayNextVideo: + type: boolean + description: Automatically start playing the upcoming video after the currently playing video + autoPlayNextVideoPlaylist: + type: boolean + description: Automatically start playing the video on the playlist after the currently playing video + autoPlayVideo: + type: boolean + description: Automatically start playing the video on the watch page + blocked: + type: boolean + blockedReason: + type: string + createdAt: + type: string + email: + type: string + format: email + description: The user email + emailVerified: + type: boolean + description: Has the user confirmed their email address? + id: + allOf: + - $ref: '#/components/schemas/id' + readOnly: true + pluginAuth: + type: string + description: Auth plugin to use to authenticate the user + lastLoginDate: + type: string + format: date-time + noInstanceConfigWarningModal: + type: boolean + noWelcomeModal: + type: boolean + nsfwPolicy: + $ref: '#/components/schemas/NSFWPolicy' + role: + $ref: '#/components/schemas/UserRole' + roleLabel: + type: string + enum: + - User + - Moderator + - Administrator + theme: + type: string + description: Theme enabled by this user + username: + $ref: '#/components/schemas/username' + videoChannels: + type: array + items: + $ref: '#/components/schemas/VideoChannel' + videoQuota: + type: integer + description: The user video quota in bytes + example: -1 + videoQuotaDaily: + type: integer + description: The user daily video quota in bytes + example: -1 + webtorrentEnabled: + type: boolean + description: Enable P2P in the player + UserWithStats: + allOf: + - $ref: '#/components/schemas/User' + - properties: + # optionally present fields: they require WITH_STATS scope + videosCount: + type: integer + description: Count of videos published + abusesCount: + type: integer + description: Count of reports/abuses of which the user is a target + abusesAcceptedCount: + type: integer + description: Count of reports/abuses created by the user and accepted/acted upon by the moderation team + abusesCreatedCount: + type: integer + description: Count of reports/abuses created by the user + videoCommentsCount: + type: integer + description: Count of comments published + AddUser: + properties: + username: + $ref: '#/components/schemas/username' + password: + $ref: '#/components/schemas/password' + email: + type: string + format: email + description: The user email + videoQuota: + type: integer + description: The user video quota in bytes + example: -1 + videoQuotaDaily: + type: integer + description: The user daily video quota in bytes + example: -1 + channelName: + $ref: '#/components/schemas/usernameChannel' + role: + $ref: '#/components/schemas/UserRole' + adminFlags: + $ref: '#/components/schemas/UserAdminFlags' + required: + - username + - password + - email + - videoQuota + - videoQuotaDaily + - role + UpdateUser: + properties: + email: + description: The updated email of the user + allOf: + - $ref: '#/components/schemas/User/properties/email' + emailVerified: + type: boolean + description: Set the email as verified + videoQuota: + type: integer + description: The updated video quota of the user in bytes + videoQuotaDaily: + type: integer + description: The updated daily video quota of the user in bytes + pluginAuth: + type: string + nullable: true + description: The auth plugin to use to authenticate the user + example: 'peertube-plugin-auth-saml2' + role: + $ref: '#/components/schemas/UserRole' + adminFlags: + $ref: '#/components/schemas/UserAdminFlags' + UpdateMe: + # see shared/models/users/user-update-me.model.ts: + properties: + password: + $ref: '#/components/schemas/password' + currentPassword: + $ref: '#/components/schemas/password' + email: + description: new email used for login and service communications + allOf: + - $ref: '#/components/schemas/User/properties/email' + displayName: + type: string + description: new name of the user in its representations + minLength: 3 + maxLength: 120 + displayNSFW: + type: string + description: new NSFW display policy + enum: + - 'true' + - 'false' + - both + webTorrentEnabled: + type: boolean + description: whether to enable P2P in the player or not + autoPlayVideo: + type: boolean + description: new preference regarding playing videos automatically + autoPlayNextVideo: + type: boolean + description: new preference regarding playing following videos automatically + autoPlayNextVideoPlaylist: + type: boolean + description: new preference regarding playing following playlist videos automatically + videosHistoryEnabled: + type: boolean + description: whether to keep track of watched history or not + videoLanguages: + type: array + items: + type: string + description: list of languages to filter videos down to + theme: + type: string + noInstanceConfigWarningModal: + type: boolean + noWelcomeModal: + type: boolean + GetMeVideoRating: + properties: + id: + $ref: '#/components/schemas/id' + rating: + type: string + enum: + - like + - dislike + - none + description: Rating of the video + required: + - id + - rating + VideoRating: + properties: + video: + $ref: '#/components/schemas/Video' + rating: + type: string + enum: + - like + - dislike + - none + description: Rating of the video + required: + - video + - rating + RegisterUser: + properties: + username: + description: immutable name of the user, used to find or mention its actor + allOf: + - $ref: '#/components/schemas/username' + password: + $ref: '#/components/schemas/password' + email: + type: string + format: email + description: email of the user, used for login or service communications + displayName: + type: string + description: editable name of the user, displayed in its representations + minLength: 1 + maxLength: 120 + channel: + type: object + description: channel base information used to create the first channel of the user + properties: + name: + $ref: '#/components/schemas/usernameChannel' + displayName: + $ref: '#/components/schemas/VideoChannel/properties/displayName' + required: + - username + - password + - email + + VideoChannel: + properties: + # GET/POST/PUT properties + displayName: + type: string + description: editable name of the channel, displayed in its representations + example: Videos of Framasoft + minLength: 1 + maxLength: 120 + description: + type: string + example: Videos made with <3 by Framasoft + minLength: 3 + maxLength: 1000 + support: + type: string + description: text shown by default on all videos of this channel, to tell the audience how to support it + example: Please support our work on https://soutenir.framasoft.org/en/ <3 + minLength: 3 + maxLength: 1000 + # GET-only properties + id: + readOnly: true + allOf: + - $ref: '#/components/schemas/id' + isLocal: + readOnly: true + type: boolean + updatedAt: + readOnly: true + type: string + format: date-time + ownerAccount: + readOnly: true + nullable: true + type: object + properties: + id: + type: integer + uuid: + $ref: '#/components/schemas/UUIDv4' + VideoChannelCreate: + allOf: + - $ref: '#/components/schemas/VideoChannel' + - properties: + name: + description: username of the channel to create + allOf: + - $ref: '#/components/schemas/usernameChannel' + required: + - name + - displayName + VideoChannelUpdate: + allOf: + - $ref: '#/components/schemas/VideoChannel' + - properties: + bulkVideosSupportUpdate: + type: boolean + description: Update the support field for all videos of this channel + VideoChannelList: + properties: + total: + type: integer + example: 1 + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/VideoChannel' + - $ref: '#/components/schemas/Actor' + + MRSSPeerLink: + type: object + xml: + name: 'media:peerLink' + properties: + href: + type: string + xml: + attribute: true + type: + type: string + enum: + - application/x-bittorrent + xml: + attribute: true + MRSSGroupContent: + type: object + xml: + name: 'media:content' + properties: + url: + type: string + format: url + xml: + attribute: true + fileSize: + type: integer + xml: + attribute: true + type: + type: string + xml: + attribute: true + framerate: + type: integer + xml: + attribute: true + duration: + type: integer + xml: + attribute: true + height: + type: integer + xml: + attribute: true + lang: + type: string + xml: + attribute: true + VideoCommentsForXML: + type: array + xml: + wrapped: true + name: 'channel' + items: type: object + xml: + name: 'item' properties: - enabledResolutions: - type: array - items: - type: number - avatar: + link: + type: string + format: url + guid: + type: string + pubDate: + type: string + format: date-time + 'content:encoded': + type: string + 'dc:creator': + type: string + VideosForXML: + type: array + xml: + wrapped: true + name: 'channel' + items: type: object + xml: + name: 'item' properties: - file: + link: + type: string + format: url + description: video watch page URL + guid: + type: string + description: video canonical URL + pubDate: + type: string + format: date-time + description: video publication date + description: + type: string + description: video description + 'content:encoded': + type: string + description: video description + 'dc:creator': + type: string + description: publisher user name + 'media:category': + type: integer + description: video category (MRSS) + 'media:community': type: object + description: see [media:community](https://www.rssboard.org/media-rss#media-community) (MRSS) properties: - size: + 'media:statistics': type: object properties: - max: - type: number - extensions: + views: + type: integer + xml: + attribute: true + 'media:embed': + type: object + properties: + url: + type: string + format: url + description: video embed path, relative to the canonical URL domain (MRSS) + xml: + attribute: true + 'media:player': + type: object + properties: + url: + type: string + format: url + description: video watch path, relative to the canonical URL domain (MRSS) + xml: + attribute: true + 'media:thumbnail': + type: object + properties: + url: + type: string + format: url + xml: + attribute: true + height: + type: integer + xml: + attribute: true + width: + type: integer + xml: + attribute: true + 'media:title': + type: string + description: see [media:title](https://www.rssboard.org/media-rss#media-title) (MRSS). We only use `plain` titles. + 'media:description': + type: string + 'media:rating': + type: string + enum: + - nonadult + - adult + description: see [media:rating](https://www.rssboard.org/media-rss#media-rating) (MRSS) + 'enclosure': + type: object + description: main streamable file for the video + properties: + url: + type: string + format: url + xml: + attribute: true + type: + type: string + enum: + - application/x-bittorrent + xml: + attribute: true + length: + type: integer + xml: + attribute: true + 'media:group': type: array + description: list of streamable files for the video. see [media:peerLink](https://www.rssboard.org/media-rss#media-peerlink) and [media:content](https://www.rssboard.org/media-rss#media-content) or (MRSS) items: + anyOf: + - $ref: '#/components/schemas/MRSSPeerLink' + - $ref: '#/components/schemas/MRSSGroupContent' + NotificationSettingValue: + type: integer + description: > + Notification type + + - `0` NONE + + - `1` WEB + + - `2` EMAIL + enum: + - 0 + - 1 + - 3 + Notification: + properties: + id: + $ref: '#/components/schemas/id' + type: + type: integer + description: > + Notification type, following the `UserNotificationType` enum: + + - `1` NEW_VIDEO_FROM_SUBSCRIPTION + + - `2` NEW_COMMENT_ON_MY_VIDEO + + - `3` NEW_ABUSE_FOR_MODERATORS + + - `4` BLACKLIST_ON_MY_VIDEO + + - `5` UNBLACKLIST_ON_MY_VIDEO + + - `6` MY_VIDEO_PUBLISHED + + - `7` MY_VIDEO_IMPORT_SUCCESS + + - `8` MY_VIDEO_IMPORT_ERROR + + - `9` NEW_USER_REGISTRATION + + - `10` NEW_FOLLOW + + - `11` COMMENT_MENTION + + - `12` VIDEO_AUTO_BLACKLIST_FOR_MODERATORS + + - `13` NEW_INSTANCE_FOLLOWER + + - `14` AUTO_INSTANCE_FOLLOWING + read: + type: boolean + video: + nullable: true + allOf: + - $ref: '#/components/schemas/VideoInfo' + - type: object + properties: + channel: + $ref: '#/components/schemas/ActorInfo' + videoImport: + nullable: true + type: object + properties: + id: + $ref: '#/components/schemas/id' + video: + nullable: true + $ref: '#/components/schemas/VideoInfo' + torrentName: type: string - video: - type: object - properties: - file: - type: object - properties: - extensions: - type: array - items: + nullable: true + magnetUri: + $ref: '#/components/schemas/VideoImport/properties/magnetUri' + targetUri: + type: string + format: uri + nullable: true + comment: + nullable: true + type: object + properties: + id: + $ref: '#/components/schemas/id' + threadId: + type: integer + video: + $ref: '#/components/schemas/VideoInfo' + account: + $ref: '#/components/schemas/ActorInfo' + videoAbuse: + nullable: true + type: object + properties: + id: + $ref: '#/components/schemas/id' + video: + allOf: + - $ref: '#/components/schemas/VideoInfo' + videoBlacklist: + nullable: true + type: object + properties: + id: + $ref: '#/components/schemas/id' + video: + allOf: + - $ref: '#/components/schemas/VideoInfo' + account: + nullable: true + allOf: + - $ref: '#/components/schemas/ActorInfo' + actorFollow: + type: object + nullable: true + properties: + id: + $ref: '#/components/schemas/id' + follower: + $ref: '#/components/schemas/ActorInfo' + state: + type: string + enum: + - pending + - accepted + following: + type: object + properties: + type: type: string - Follow: - properties: - id: - type: number - follower: - $ref: "#/definitions/Actor" - following: - $ref: "#/definitions/Actor" - score: - type: number - state: - type: string - enum: [pending, accepted] - createdAt: - type: string - updatedAt: - type: string - Job: - properties: - id: - type: number - state: - type: string - enum: [pending, processing, error, success] - category: - type: string - enum: [transcoding, activitypub-http] - handlerName: - type: string - handlerInputData: - type: string - createdAt: - type: string - updatedAt: - type: string + enum: + - account + - channel + - instance + name: + type: string + displayName: + type: string + host: + type: string + format: hostname + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + NotificationListResponse: + properties: + total: + type: integer + example: 1 + data: + type: array + maxItems: 100 + items: + $ref: '#/components/schemas/Notification' + Plugin: + properties: + name: + type: string + example: peertube-plugin-auth-ldap + type: + type: integer + description: > + - `1`: PLUGIN -# Api responses - AddUserResponse: - properties: - id: - type: number - uuid: - type: string - VideoUploadResponse: - properties: - video: - type: object - properties: - id: - type: number - uuid: - type: string - CommentThreadResponse: - properties: - total: - type: number - data: - type: array - items: - $ref: "#/definitions/VideoComment" - CommentThreadPostResponse: - properties: - comment: - $ref: "#/definitions/VideoComment" - -# Request bodies - AddUser: - properties: - username: - type: string - description: 'The user username ' - password: - type: string - description: 'The user password ' - email: - type: string - description: 'The user email ' - videoQuota: - type: string - description: 'The user videoQuota ' - role: - type: string - description: 'The user role ' - required: - - username - - password - - email - - videoQuota - - role - UpdateUser: - properties: - id: - type: string - description: 'The user id ' - email: - type: string - description: 'The updated email of the user ' - videoQuota: - type: string - description: 'The updated videoQuota of the user ' - role: - type: string - description: 'The updated role of the user ' - required: - - id - - email - - videoQuota - - role - UpdateMe: - properties: - password: - type: string - description: 'Your new password ' - email: - type: string - description: 'Your new email ' - displayNSFW: - type: string - description: 'Your new displayNSFW ' - autoPlayVideo: - type: string - description: 'Your new autoPlayVideo ' - required: - - password - - email - - displayNSFW - - autoPlayVideo - GetMeVideoRating: - properties: - id: - type: string - description: 'Id of the video ' - rating: - type: number - description: 'Rating of the video ' - required: - - id - - rating - RegisterUser: - properties: - username: - type: string - description: 'The username of the user ' - password: - type: string - description: 'The password of the user ' - email: - type: string - description: 'The email of the user ' - required: - - username - - password - - email - VideoChannelInput: - properties: - name: - type: string - description: - type: string + - `2`: THEME + enum: + - 1 + - 2 + latestVersion: + type: string + example: 0.0.3 + version: + type: string + example: 0.0.1 + enabled: + type: boolean + uninstalled: + type: boolean + peertubeEngine: + type: string + example: 2.2.0 + description: + type: string + homepage: + type: string + format: url + example: https://framagit.org/framasoft/peertube/official-plugins/tree/master/peertube-plugin-auth-ldap + settings: + type: object + additionalProperties: true + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + PluginResponse: + properties: + total: + type: integer + example: 1 + data: + type: array + maxItems: 100 + items: + $ref: '#/components/schemas/Plugin' + + LiveVideoUpdate: + properties: + saveReplay: + type: boolean + permanentLive: + description: User can stream multiple times in a permanent live + type: boolean + + LiveVideoResponse: + properties: + rtmpUrl: + type: string + streamKey: + type: string + description: RTMP stream key to use to stream into this live video + saveReplay: + type: boolean + permanentLive: + description: User can stream multiple times in a permanent live + type: boolean + + + + callbacks: + searchIndex: + 'https://search.example.org/api/v1/search/videos': + post: + summary: third-party search index MAY be used instead of the local index, if enabled by the instance admin. see `searchTarget` + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/VideoListResponse'