]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - support/doc/api/openapi.yaml
fix video playlistId/videoId for video playlists in openapi spec
[github/Chocobozzz/PeerTube.git] / support / doc / api / openapi.yaml
index 9434af9049097b15e9d76156bcde36d69582845a..f99d49fefab5b717769f66dc26ea95c8676a557f 100644 (file)
@@ -1,7 +1,7 @@
 openapi: 3.0.0
 info:
   title: PeerTube
-  version: 2.2.0
+  version: 3.2.0-rc.1
   contact:
     name: PeerTube Community
     url: 'https://joinpeertube.org'
@@ -12,42 +12,110 @@ info:
     url: 'https://joinpeertube.org/img/brand.png'
     altText: PeerTube Project Homepage
   description: |
-    # Introduction
-
     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. No official
-    SDK is currently provided, but the spec API is fully compatible with
+    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.
+    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 [Quick Start guide](https://docs.joinpeertube.org/#/api-rest-getting-started) so you can play with the PeerTube API.
+    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, you are given the possibility to generate
-    sessions, and authenticate using this session token. One session token can
-    currently be used at a time.
+    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
-    format.
+    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.
 
     ```
     {
-      "code": "unauthorized_request", // example inner error code
-      "error": "Token is invalid." // example exposed error message
+      "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<sup>*</sup>    | 5 minutes                 |
+    | `POST /users/ask-send-verify-email` | 3    | 5 minutes                 |
+
+    Depending on the endpoint, <sup>*</sup>failed requests are not taken into account. A service
+    limit is announced by a `429 Too Many Requests` status code.
+
+    You can get details about the current state of your rate limit by reading the
+    following headers:
+
+    | Header                  | Description                                                |
+    |-------------------------|------------------------------------------------------------|
+    | `X-RateLimit-Limit`     | Number of max requests allowed in the current time period  |
+    | `X-RateLimit-Remaining` | Number of remaining requests in the current time period    |
+    | `X-RateLimit-Reset`     | Timestamp of end of current time period as UNIX timestamp  |
+    | `Retry-After`           | Seconds to delay after the first `429` is received         |
 externalDocs:
   url: https://docs.joinpeertube.org/api-rest-reference.html
 tags:
   - name: Accounts
     description: >
-      Using some features of PeerTube require authentication, for which Accounts
+      Accounts encompass remote accounts discovered across the federation,
+      and correspond to the main Actor, along with video channels a user can create, which
+      are also Actors.
+
+      When a comment is posted, it is done with your Account's Actor.
+  - name: Users
+    description: >
+      Using some features of PeerTube require authentication, for which User
       provide different levels of permission as well as associated user
-      information. Accounts also encompass remote accounts discovered across the federation.
+      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
@@ -63,12 +131,71 @@ tags:
       server then deals with inter-server ActivityPub operations and propagates
       information across its social graph by posting activities to actors' inbox
       endpoints.
-  - name: Video Abuses
+    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: |
-      Video abuses deal with reports of local or remote videos alike.
+      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.
@@ -78,25 +205,11 @@ tags:
 
       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 Comments
-    description: >
-      Operations dealing with comments to a video. Comments are organized in
-      threads.
-  - name: Video Playlists
-    description: >
-      Operations dealing with playlists of videos. Playlists are bound to users
-      and/or channels.
-  - name: Video Channels
-    description: >
-      Operations dealing with creation, modification and video listing of a
-      user's channels.
-  - name: Video Blacklist
-    description: >
-      Operations dealing with blacklisting videos (removing them from view and
-      preventing interactions).
-  - name: Video Rates
-    description: >
-      Like/dislike a video.
+  - 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:
@@ -104,27 +217,36 @@ x-tagGroups:
       - Users
       - My User
       - My Subscriptions
+      - My Notifications
+      - My History
   - name: Videos
     tags:
       - Video
-      - Video Caption
+      - Video Upload
+      - Video Captions
       - Video Channels
       - Video Comments
-      - Video Following
       - Video Rates
       - Video Playlists
       - Video Ownership Change
+      - Video Mirroring
+      - Live Videos
+      - Feeds
   - name: Search
     tags:
       - Search
   - name: Moderation
     tags:
-      - Video Abuses
+      - Abuses
       - Video Blocks
+      - Account Blocks
+      - Server Blocks
   - name: Instance Configuration
     tags:
       - Config
       - Instance Follows
+      - Instance Redundancy
+      - Plugins
   - name: Jobs
     tags:
       - Job
@@ -143,6 +265,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/Account'
+        '404':
+          description: account not found
   '/accounts/{name}/videos':
     get:
       tags:
@@ -152,6 +276,7 @@ paths:
       parameters:
         - $ref: '#/components/parameters/name'
         - $ref: '#/components/parameters/categoryOneOf'
+        - $ref: '#/components/parameters/isLive'
         - $ref: '#/components/parameters/tagsOneOf'
         - $ref: '#/components/parameters/tagsAllOf'
         - $ref: '#/components/parameters/licenceOneOf'
@@ -169,7 +294,7 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/VideoListResponse'
-      x-code-samples:
+      x-codeSamples:
         - lang: JavaScript
           source: |
             fetch('https://peertube2.cpy.re/api/v1/accounts/{name}/videos')
@@ -180,8 +305,8 @@ paths:
             })
         - lang: Shell
           source: |
-            # pip install httpie
-            http -b GET https://peertube2.cpy.re/api/v1/accounts/{name}/videos
+            ## DEPENDENCIES: jq
+            curl -s https://peertube2.cpy.re/api/v1/accounts/{name}/videos | jq
         - lang: Ruby
           source: |
             require 'net/http'
@@ -233,6 +358,9 @@ paths:
             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
@@ -245,6 +373,9 @@ paths:
             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
@@ -252,7 +383,7 @@ paths:
         - Config
       security:
         - OAuth2:
-            - admin
+          - admin
       responses:
         '200':
           description: successful operation
@@ -266,17 +397,23 @@ paths:
         - Config
       security:
         - OAuth2:
-            - admin
+          - 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
+          - admin
       responses:
         '200':
           description: successful operation
@@ -285,22 +422,24 @@ paths:
       summary: List instance jobs
       security:
         - OAuth2:
-            - admin
+          - admin
       tags:
         - Job
       parameters:
         - name: state
           in: path
           required: true
-          description: The state of the job
+          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'
@@ -310,14 +449,21 @@ paths:
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/Job'
+                type: object
+                properties:
+                  total:
+                    type: integer
+                    example: 1
+                  data:
+                    type: array
+                    maxItems: 100
+                    items:
+                      $ref: '#/components/schemas/Job'
   '/server/following/{host}':
     delete:
       security:
         - OAuth2:
-            - admin
+          - admin
       tags:
         - Instance Follows
       summary: Unfollow a server
@@ -328,6 +474,7 @@ paths:
           description: 'The host to unfollow '
           schema:
             type: string
+            format: hostname
       responses:
         '201':
           description: successful operation
@@ -353,8 +500,25 @@ paths:
     get:
       tags:
         - Instance Follows
-      summary: List instance followings
+      summary: List instances followed by the server
       parameters:
+        - name: state
+          in: query
+          schema:
+            type: string
+            enum:
+              - pending
+              - accepted
+        - name: actorType
+          in: query
+          schema:
+            type: string
+            enum:
+              - Person
+              - Application
+              - Group
+              - Service
+              - Organization
         - $ref: '#/components/parameters/start'
         - $ref: '#/components/parameters/count'
         - $ref: '#/components/parameters/sort'
@@ -370,47 +534,79 @@ paths:
     post:
       security:
         - OAuth2:
-            - admin
+          - admin
       tags:
         - Instance Follows
       summary: Follow a server
       responses:
         '204':
           description: successful operation
+        '500':
+          description: cannot follow a non-HTTPS server
       requestBody:
         content:
           application/json:
             schema:
-              $ref: '#/components/schemas/Follow'
+              type: object
+              properties:
+                hosts:
+                  type: array
+                  items:
+                    type: string
+                    format: hostname
+                  uniqueItems: true
   /users:
     post:
       summary: Create a user
       security:
         - OAuth2:
-            - admin
+          - admin
       tags:
         - Users
       responses:
         '200':
-          description: successful operation
+          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: User to create
+        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:
         - Users
       parameters:
+        - $ref: '#/components/parameters/usersSearch'
+        - $ref: '#/components/parameters/usersBlocked'
         - $ref: '#/components/parameters/start'
         - $ref: '#/components/parameters/count'
         - $ref: '#/components/parameters/usersSort'
@@ -424,15 +620,16 @@ paths:
                 items:
                   $ref: '#/components/schemas/User'
   '/users/{id}':
+    parameters:
+      - $ref: '#/components/parameters/id'
     delete:
       summary: Delete a user
       security:
         - OAuth2:
-            - admin
+          - admin
       tags:
         - Users
-      parameters:
-        - $ref: '#/components/parameters/id'
+      operationId: delUserId
       responses:
         '204':
           description: successful operation
@@ -442,23 +639,32 @@ paths:
         - OAuth2: []
       tags:
         - Users
+      operationId: getUserId
       parameters:
-        - $ref: '#/components/parameters/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
+          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:
-                $ref: '#/components/schemas/User'
+                oneOf:
+                  - $ref: '#/components/schemas/User'
+                  - $ref: '#/components/schemas/UserWithStats'
     put:
       summary: Update a user
       security:
         - OAuth2: []
       tags:
         - Users
-      parameters:
-        - $ref: '#/components/parameters/id'
+      operationId: putUserId
       responses:
         '204':
           description: successful operation
@@ -520,7 +726,7 @@ paths:
       summary: Get video imports of my user
       security:
         - OAuth2:
-            - user
+          - user
       tags:
         - Videos
         - My User
@@ -534,7 +740,7 @@ paths:
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/VideoImport'
+                $ref: '#/components/schemas/VideoImportsList'
   /users/me/video-quota-used:
     get:
       summary: Get my user used quota
@@ -549,7 +755,16 @@ paths:
           content:
             application/json:
               schema:
-                type: number
+                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
@@ -562,9 +777,9 @@ paths:
         - name: videoId
           in: path
           required: true
-          description: 'The video id '
+          description: The video id
           schema:
-            type: string
+            $ref: '#/components/schemas/Video/properties/id'
       responses:
         '200':
           description: successful operation
@@ -597,7 +812,7 @@ paths:
       summary: Get my user subscriptions
       security:
         - OAuth2:
-            - user
+          - user
       tags:
         - My Subscriptions
       parameters:
@@ -607,13 +822,33 @@ paths:
       responses:
         '200':
           description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/VideoChannelList'
     post:
+      tags:
+        - My Subscriptions
       summary: Add subscription to my user
       security:
         - OAuth2:
-            - user
-      tags:
-        - My Subscriptions
+          - 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
@@ -622,7 +857,7 @@ paths:
       summary: Get if subscriptions exist for my user
       security:
         - OAuth2:
-            - user
+          - user
       tags:
         - My Subscriptions
       parameters:
@@ -645,6 +880,7 @@ paths:
         - Videos
       parameters:
         - $ref: '#/components/parameters/categoryOneOf'
+        - $ref: '#/components/parameters/isLive'
         - $ref: '#/components/parameters/tagsOneOf'
         - $ref: '#/components/parameters/tagsAllOf'
         - $ref: '#/components/parameters/licenceOneOf'
@@ -667,7 +903,7 @@ paths:
       summary: Get subscription of my user
       security:
         - OAuth2:
-            - user
+          - user
       tags:
         - My Subscriptions
       parameters:
@@ -683,7 +919,7 @@ paths:
       summary: Delete subscription of my user
       security:
         - OAuth2:
-            - user
+          - user
       tags:
         - My Subscriptions
       parameters:
@@ -691,6 +927,140 @@ paths:
       responses:
         '200':
           description: successful operation
+  /users/me/notifications:
+    get:
+      summary: List my notifications
+      security:
+        - OAuth2: []
+      tags:
+        - My Notifications
+      parameters:
+        - name: unread
+          in: query
+          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
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/NotificationListResponse'
+  /users/me/notifications/read:
+    post:
+      summary: Mark notifications as read by their id
+      security:
+        - OAuth2: []
+      tags:
+        - My Notifications
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                ids:
+                  type: array
+                  description: ids of the notifications to mark as read
+                  items:
+                    type: integer
+              required:
+                - ids
+      responses:
+        '204':
+          description: successful operation
+  /users/me/notifications/read-all:
+    post:
+      summary: Mark all my notification as read
+      security:
+        - OAuth2: []
+      tags:
+        - My Notifications
+      responses:
+        '204':
+          description: successful operation
+  /users/me/notification-settings:
+    put:
+      summary: Update my notification settings
+      security:
+        - OAuth2: []
+      tags:
+        - 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
+  /users/me/history/videos:
+    get:
+      summary: List watched videos history
+      security:
+        - OAuth2: []
+      tags:
+        - My History
+      parameters:
+        - $ref: '#/components/parameters/start'
+        - $ref: '#/components/parameters/count'
+        - $ref: '#/components/parameters/search'
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/VideoListResponse'
+  /users/me/history/videos/remove:
+    post:
+      summary: Clear video history
+      security:
+        - OAuth2: []
+      tags:
+        - My History
+      requestBody:
+        content:
+          multipart/form-data:
+            schema:
+              type: object
+              properties:
+                beforeDate:
+                  description: history before this date will be deleted
+                  type: string
+                  format: date-time
+      responses:
+        '204':
+          description: successful operation
   /users/me/avatar/pick:
     post:
       summary: Update my user avatar
@@ -704,7 +1074,18 @@ paths:
           content:
             application/json:
               schema:
-                $ref: '#/components/schemas/Avatar'
+                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:
@@ -712,12 +1093,23 @@ paths:
               type: object
               properties:
                 avatarfile:
-                  description: The file to upload.
+                  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: []
+      tags:
+        - My User
+      responses:
+        '204':
+          description: successful operation
+
   /videos/ownership:
     get:
       summary: List video ownership changes
@@ -740,6 +1132,10 @@ paths:
       responses:
         '204':
           description: successful operation
+        '403':
+          description: cannot terminate an ownership change of another user
+        '404':
+          description: video owneship change not found
   '/videos/ownership/{id}/refuse':
     post:
       summary: Refuse ownership change request
@@ -752,6 +1148,10 @@ paths:
       responses:
         '204':
           description: successful operation
+        '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
@@ -776,7 +1176,9 @@ paths:
         '204':
           description: successful operation
         '400':
-          description: 'Changing video ownership to a remote account is not supported yet'
+          description: changing video ownership to a remote account is not supported yet
+        '404':
+          description: video not found
   /videos:
     get:
       summary: List videos
@@ -784,6 +1186,7 @@ paths:
         - Video
       parameters:
         - $ref: '#/components/parameters/categoryOneOf'
+        - $ref: '#/components/parameters/isLive'
         - $ref: '#/components/parameters/tagsOneOf'
         - $ref: '#/components/parameters/tagsAllOf'
         - $ref: '#/components/parameters/licenceOneOf'
@@ -804,6 +1207,7 @@ paths:
   /videos/categories:
     get:
       summary: List available video categories
+      operationId: getCategories
       tags:
         - Video
       responses:
@@ -815,9 +1219,13 @@ paths:
                 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:
         - Video
       responses:
@@ -829,9 +1237,13 @@ paths:
                 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:
         - Video
       responses:
@@ -843,9 +1255,13 @@ paths:
                 type: array
                 items:
                   type: string
+              examples:
+                nightly:
+                  externalValue: https://peertube2.cpy.re/api/v1/videos/languages
   /videos/privacies:
     get:
-      summary: List available video privacies
+      summary: List available video privacy policies
+      operationId: getPrivacyPolicies
       tags:
         - Video
       responses:
@@ -857,6 +1273,9 @@ paths:
                 type: array
                 items:
                   type: string
+              examples:
+                nightly:
+                  externalValue: https://peertube2.cpy.re/api/v1/videos/privacies
   '/videos/{id}':
     put:
       summary: Update a video
@@ -884,14 +1303,11 @@ paths:
                   type: string
                   format: binary
                 category:
-                  description: Video category
-                  type: string
+                  $ref: '#/components/schemas/VideoCategorySet'
                 licence:
-                  description: Video licence
-                  type: string
+                  $ref: '#/components/schemas/VideoLicenceSet'
                 language:
-                  description: Video language
-                  type: string
+                  $ref: '#/components/schemas/VideoLanguageSet'
                 privacy:
                   $ref: '#/components/schemas/VideoPrivacySet'
                 description:
@@ -901,14 +1317,17 @@ paths:
                   description: Whether or not we wait transcoding before publish the video
                   type: string
                 support:
-                  description: Text describing how to support the video uploader
+                  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: string
+                  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
@@ -920,7 +1339,7 @@ paths:
                     maxLength: 30
                 commentsEnabled:
                   description: Enable or disable comments for this video
-                  type: string
+                  type: boolean
                 originallyPublishedAt:
                   description: Date when the content was originally published
                   type: string
@@ -969,7 +1388,12 @@ paths:
           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
@@ -1001,10 +1425,13 @@ paths:
   /videos/upload:
     post:
       summary: Upload a video
+      description: Uses a single request to upload a video.
+      operationId: uploadLegacy
       security:
         - OAuth2: []
       tags:
         - Video
+        - Video Upload
       responses:
         '200':
           description: successful operation
@@ -1012,81 +1439,29 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/VideoUploadResponse'
+        '400':
+          description: invalid file field, schedule date or parameter
         '403':
-          description: 'The user video quota is exceeded with this video.'
+          description: video didn't pass upload filter
         '408':
-          description: 'Upload has timed out'
+          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: 'Invalid input file.'
+          description: video unreadable
       requestBody:
         content:
           multipart/form-data:
             schema:
-              type: object
-              properties:
-                videofile:
-                  description: Video file
-                  type: string
-                  format: binary
-                channelId:
-                  description: Channel id that will contain this video
-                  type: number
-                thumbnailfile:
-                  description: Video thumbnail file
-                  type: string
-                  format: binary
-                previewfile:
-                  description: Video preview file
-                  type: string
-                  format: binary
-                privacy:
-                  $ref: '#/components/schemas/VideoPrivacySet'
-                category:
-                  description: Video category
-                  type: string
-                licence:
-                  description: Video licence
-                  type: string
-                language:
-                  description: Video language
-                  type: string
-                description:
-                  description: Video description
-                  type: string
-                waitTranscoding:
-                  description: Whether or not we wait transcoding before publish the video
-                  type: string
-                support:
-                  description: Text describing how to support the video uploader
-                  type: string
-                nsfw:
-                  description: Whether or not this video contains sensitive content
-                  type: string
-                name:
-                  description: Video name
-                  type: string
-                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: string
-                originallyPublishedAt:
-                  description: Date when the content was originally published
-                  type: string
-                  format: date-time
-                scheduleUpdate:
-                  $ref: '#/components/schemas/VideoScheduledUpdate'
-              required:
-                - videofile
-                - channelId
-                - name
+              $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
@@ -1094,11 +1469,10 @@ paths:
                 contentType: image/jpeg
               previewfile:
                 contentType: image/jpeg
-      x-code-samples:
+      x-codeSamples:
         - lang: Shell
           source: |
-            ## DEPENDENCIES: httpie, jq
-            # pip install httpie
+            ## DEPENDENCIES: jq
             USERNAME="<your_username>"
             PASSWORD="<your_password>"
             FILE_PATH="<your_file_path>"
@@ -1107,26 +1481,228 @@ paths:
 
             API_PATH="https://peertube2.cpy.re/api/v1"
             ## AUTH
-            client_id=$(http -b GET "$API_PATH/oauth-clients/local" | jq -r ".client_id")
-            client_secret=$(http -b GET "$API_PATH/oauth-clients/local" | jq -r ".client_secret")
-            token=$(http -b --form POST "$API_PATH/users/token" \
-              client_id="$client_id" client_secret="$client_secret" grant_type=password response_type=code \
-              username=$USERNAME \
-              password=$PASSWORD \
+            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
-            http -b --form POST "$API_PATH/videos/upload" \
-              videofile@$FILE_PATH \
-              channelId=$CHANNEL_ID \
-              name=$NAME \
-              "Authorization:Bearer $token"
+            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:
+        - Video
+        - Video Upload
+      parameters:
+        - name: X-Upload-Content-Length
+          in: header
+          schema:
+            type: number
+            example: 2469036
+          required: true
+          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
+          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: 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: []
+      tags:
+        - Video
+        - Video Upload
+      parameters:
+        - name: upload_id
+          in: path
+          required: true
+          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
+          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: 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: []
+      tags:
+        - Video
+        - Video Upload
+      parameters:
+        - name: upload_id
+          in: path
+          required: true
+          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
+          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':
@@ -1135,61 +1711,55 @@ paths:
             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:
-                torrentfile:
-                  description: Torrent File
-                  type: string
-                  format: binary
-                targetUrl:
-                  description: HTTP target URL
-                  type: string
-                magnetUri:
-                  description: Magnet URI
-                  type: string
                 channelId:
-                  description: Channel id that will contain this video
-                  type: number
+                  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: Video thumbnail file
+                  description: Live video/replay thumbnail file
                   type: string
                   format: binary
                 previewfile:
-                  description: Video preview file
+                  description: Live video/replay preview file
                   type: string
                   format: binary
                 privacy:
                   $ref: '#/components/schemas/VideoPrivacySet'
                 category:
-                  description: Video category
-                  type: string
+                  $ref: '#/components/schemas/VideoCategorySet'
                 licence:
-                  description: Video licence
-                  type: string
+                  $ref: '#/components/schemas/VideoLicenceSet'
                 language:
-                  description: Video language
-                  type: string
+                  $ref: '#/components/schemas/VideoLanguageSet'
                 description:
-                  description: Video description
-                  type: string
-                waitTranscoding:
-                  description: Whether or not we wait transcoding before publish the video
+                  description: Live video/replay description
                   type: string
                 support:
-                  description: Text describing how to support the video uploader
+                  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 video contains sensitive content
-                  type: string
+                  description: Whether or not this live video/replay contains sensitive content
+                  type: boolean
                 name:
-                  description: Video name
+                  description: Live video/replay name
                   type: string
+                  minLength: 3
+                  maxLength: 120
                 tags:
-                  description: Video tags (maximum 5 tags each between 2 and 30 characters)
+                  description: Live video/replay tags (maximum 5 tags each between 2 and 30 characters)
                   type: array
                   minItems: 1
                   maxItems: 5
@@ -1198,182 +1768,426 @@ paths:
                     minLength: 2
                     maxLength: 30
                 commentsEnabled:
-                  description: Enable or disable comments for this video
-                  type: string
-                scheduleUpdate:
-                  $ref: '#/components/schemas/VideoScheduledUpdate'
+                  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:
-              torrentfile:
-                contentType: application/x-bittorrent
               thumbnailfile:
                 contentType: image/jpeg
               previewfile:
                 contentType: image/jpeg
-  /videos/abuse:
+
+  /videos/live/{id}:
     get:
-      summary: List video abuses
+      summary: Get information about a live
+      operationId: getLiveId
       security:
-        - OAuth2:
-            - admin
-            - moderator
+        - OAuth2: []
       tags:
-        - Video Abuses
+        - Live Videos
+        - Video
       parameters:
-        - $ref: '#/components/parameters/start'
-        - $ref: '#/components/parameters/count'
-        - $ref: '#/components/parameters/abusesSort'
+        - $ref: '#/components/parameters/idOrUUID'
       responses:
         '200':
           description: successful operation
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoAbuse'
-  '/videos/{id}/abuse':
-    post:
-      summary: Report an abuse
-      security:
-        - OAuth2: []
-      tags:
-        - Video Abuses
-        - Videos
-      parameters:
-        - $ref: '#/components/parameters/idOrUUID'
-      requestBody:
-        required: true
-        content:
-          application/json:
-            schema:
-              type: object
-              properties:
-                reason:
-                  description: Reason why the user reports this video
-                  type: string
-                predefinedReasons:
-                  description: Reason categories that help triage reports
-                  type: array
-                  items:
-                    type: string
-                    enum:
-                    - violentOrAbusive
-                    - hatefulOrAbusive
-                    - spamOrMisleading
-                    - privacy
-                    - rights
-                    - serverRules
-                    - thumbnails
-                    - captions
-                startAt:
-                  type: number
-                  description: Timestamp in the video that marks the beginning of the report
-                endAt:
-                  type: number
-                  description: Timestamp in the video that marks the ending of the report
-              required:
-                - reason
-      responses:
-        '204':
-          description: successful operation
-  '/videos/{id}/abuse/{abuseId}':
+                $ref: '#/components/schemas/LiveVideoResponse'
     put:
-      summary: Update an abuse
+      summary: Update information about a live
+      operationId: updateLiveId
       security:
-        - OAuth2:
-          - admin
-          - moderator
+        - OAuth2: []
       tags:
-        - Video Abuses
-      responses:
-        '204':
-          description: successful operation
+        - Live Videos
+        - Video
       parameters:
         - $ref: '#/components/parameters/idOrUUID'
-        - $ref: '#/components/parameters/abuseId'
       requestBody:
         content:
           application/json:
             schema:
-              type: object
-              properties:
-                state:
-                  $ref: '#/components/schemas/VideoAbuseStateSet'
-                moderationComment:
-                  type: string
-                  description: 'Update the comment of the video abuse for other admin/moderators'
-    delete:
-      summary: Delete an abuse
-      security:
-        - OAuth2:
-            - admin
-            - moderator
-      tags:
-        - Video Abuses
+              $ref: '#/components/schemas/LiveVideoUpdate'
       responses:
         '204':
           description: successful operation
-      parameters:
-        - $ref: '#/components/parameters/idOrUUID'
-        - $ref: '#/components/parameters/abuseId'
+        '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
 
-  '/videos/{id}/blacklist':
-    post:
-      summary: Blacklist a video
-      security:
-        - OAuth2:
-            - admin
-            - moderator
-      tags:
-        - Video Blacklist
-      parameters:
-        - $ref: '#/components/parameters/idOrUUID'
-      responses:
-        '204':
-          description: successful operation
-    delete:
-      summary: Delete an entry of the blacklist of a video by its id
-      security:
-        - OAuth2:
-            - admin
-            - moderator
-      tags:
-        - Video Blacklist
-      parameters:
-        - $ref: '#/components/parameters/idOrUUID'
-      responses:
-        '204':
-          description: successful operation
-  /videos/blacklist:
+  /users/me/abuses:
     get:
-      summary: List blacklisted videos
+      summary: List my abuses
+      operationId: getMyAbuses
       security:
-        - OAuth2:
-            - admin
-            - moderator
+        - OAuth2: []
       tags:
-        - Video Blacklist
+        - 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'
-        - $ref: '#/components/parameters/blacklistsSort'
       responses:
         '200':
           description: successful operation
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoBlacklist'
-  /videos/{id}/captions:
-    get:
+                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
+        - name: state
+          in: query
+          schema:
+            $ref: '#/components/schemas/AbuseStateSet'
+        - name: searchReporter
+          in: query
+          description: only list reports of a specific reporter
+          schema:
+            type: string
+        - name: searchReportee
+          description: only list reports of a specific reportee
+          in: query
+          schema:
+            type: string
+        - name: searchVideo
+          in: query
+          description: only list reports of a specific video
+          schema:
+            type: string
+        - name: searchVideoChannel
+          in: query
+          description: only list reports of a specific video channel
+          schema:
+            type: string
+        - name: videoIs
+          in: query
+          description: only list blacklisted or deleted videos
+          schema:
+            type: string
+            enum:
+            - 'deleted'
+            - 'blacklisted'
+        - name: filter
+          in: query
+          description: only list account, comment or video reports
+          schema:
+            type: string
+            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 Caption
+        - Video Captions
       parameters:
         - $ref: '#/components/parameters/idOrUUID'
       responses:
@@ -1386,6 +2200,7 @@ paths:
                 properties:
                   total:
                     type: integer
+                    example: 1
                   data:
                     type: array
                     items:
@@ -1393,8 +2208,11 @@ paths:
   /videos/{id}/captions/{captionLanguage}:
     put:
       summary: Add or replace a video caption
+      security:
+        - OAuth2:
+          - user
       tags:
-        - Video Caption
+        - Video Captions
       parameters:
         - $ref: '#/components/parameters/idOrUUID'
         - $ref: '#/components/parameters/captionLanguage'
@@ -1414,19 +2232,27 @@ paths:
       responses:
         '204':
           description: successful operation
+        '404':
+          description: video or language not found
     delete:
       summary: Delete a video caption
+      security:
+        - OAuth2:
+          - user
       tags:
-        - Video Caption
+        - 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:
@@ -1439,11 +2265,10 @@ paths:
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoChannel'
+                $ref: '#/components/schemas/VideoChannelList'
     post:
       summary: Create a video channel
+      operationId: createVideoChannel
       security:
         - OAuth2: []
       tags:
@@ -1451,6 +2276,16 @@ paths:
       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:
@@ -1459,6 +2294,7 @@ paths:
   '/video-channels/{channelHandle}':
     get:
       summary: Get a video channel
+      operationId: getVideoChannel
       tags:
         - Video Channels
       parameters:
@@ -1506,6 +2342,7 @@ paths:
       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'
@@ -1523,25 +2360,136 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/VideoListResponse'
-
-  /video-playlists/privacies:
-    get:
-      summary: List available playlist privacies
+  '/video-channels/{channelHandle}/avatar/pick':
+    post:
+      summary: Update channel avatar
+      security:
+        - OAuth2: []
       tags:
-        - Video Playlists
+        - Video Channels
+      parameters:
+        - $ref: '#/components/parameters/channelHandle'
       responses:
         '200':
           description: successful operation
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  type: string
+                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:
@@ -1554,12 +2502,19 @@ paths:
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoPlaylist'
+                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, the videoChannelId is mandatory.'
+      description: If the video playlist is set as public, `videoChannelId` is mandatory.
+      operationId: createPlaylist
       security:
         - OAuth2: []
       tags:
@@ -1576,9 +2531,9 @@ paths:
                     type: object
                     properties:
                       id:
-                        type: number
+                        $ref: '#/components/schemas/VideoPlaylist/properties/id'
                       uuid:
-                        type: string
+                        $ref: '#/components/schemas/VideoPlaylist/properties/uuid'
       requestBody:
         content:
           multipart/form-data:
@@ -1588,6 +2543,8 @@ paths:
                 displayName:
                   description: Video playlist display name
                   type: string
+                  minLength: 1
+                  maxLength: 120
                 thumbnailfile:
                   description: Video playlist thumbnail file
                   type: string
@@ -1597,19 +2554,25 @@ paths:
                 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
-                  type: number
               required:
                 - displayName
+            encoding:
+              thumbnailfile:
+                contentType: image/jpeg
 
-  /video-playlists/{id}:
+  /video-playlists/{playlistId}:
     get:
       summary: Get a video playlist
       tags:
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       responses:
         '200':
           description: successful operation
@@ -1628,7 +2591,7 @@ paths:
         '204':
           description: successful operation
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       requestBody:
         content:
           multipart/form-data:
@@ -1638,6 +2601,8 @@ paths:
                 displayName:
                   description: Video playlist display name
                   type: string
+                  minLength: 1
+                  maxLength: 120
                 thumbnailfile:
                   description: Video playlist thumbnail file
                   type: string
@@ -1648,8 +2613,12 @@ paths:
                   description: Video playlist description
                   type: string
                 videoChannelId:
+                  allOf:
+                    - $ref: '#/components/schemas/id'
                   description: Video channel in which the playlist will be published
-                  type: number
+            encoding:
+              thumbnailfile:
+                contentType: image/jpeg
     delete:
       summary: Delete a video playlist
       security:
@@ -1657,19 +2626,19 @@ paths:
       tags:
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       responses:
         '204':
           description: successful operation
 
-  /video-playlists/{id}/videos:
+  /video-playlists/{playlistId}/videos:
     get:
       summary: 'List videos of a playlist'
       tags:
         - Videos
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       responses:
         '200':
           description: successful operation
@@ -1678,14 +2647,14 @@ paths:
               schema:
                 $ref: '#/components/schemas/VideoListResponse'
     post:
-      summary: 'Add a video in a playlist'
+      summary: Add a video in a playlist
       security:
         - OAuth2: []
       tags:
         - Videos
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       responses:
         '200':
           description: successful operation
@@ -1698,7 +2667,8 @@ paths:
                     type: object
                     properties:
                       id:
-                        type: number
+                        type: integer
+                        example: 2
       requestBody:
         content:
           application/json:
@@ -1706,18 +2676,22 @@ paths:
               type: object
               properties:
                 videoId:
-                  type: number
-                  description: 'Video to add in the playlist'
+                  oneOf:
+                    - $ref: '#/components/schemas/Video/properties/uuid'
+                    - $ref: '#/components/schemas/Video/properties/id'
+                  description: Video to add in the playlist
                 startTimestamp:
-                  type: number
-                  description: 'Start the video at this specific timestamp (in seconds)'
+                  type: integer
+                  format: seconds
+                  description: Start the video at this specific timestamp
                 stopTimestamp:
-                  type: number
-                  description: 'Stop the video at this specific timestamp (in seconds)'
+                  type: integer
+                  format: seconds
+                  description: Stop the video at this specific timestamp
               required:
                 - videoId
 
-  /video-playlists/{id}/videos/reorder:
+  /video-playlists/{playlistId}/videos/reorder:
     post:
       summary: 'Reorder a playlist'
       security:
@@ -1725,7 +2699,7 @@ paths:
       tags:
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
       responses:
         '204':
           description: successful operation
@@ -1736,27 +2710,30 @@ paths:
               type: object
               properties:
                 startPosition:
-                  type: number
-                  description: 'Start position of the element to reorder (starts from 1)'
+                  type: integer
+                  description: 'Start position of the element to reorder'
+                  minimum: 1
                 insertAfterPosition:
-                  type: number
-                  description: 'New position for the block to reorder (starts from 0, to add the block before the first element)'
+                  type: integer
+                  description: 'New position for the block to reorder, to add the block before the first element'
+                  minimum: 0
                 reorderLength:
-                  type: number
-                  description: 'How many element from startPosition to reorder (minimum length is 1)'
+                  type: integer
+                  description: 'How many element from `startPosition` to reorder'
+                  minimum: 1
               required:
                 - startPosition
                 - insertAfterPosition
 
-  /video-playlists/{id}/videos/{playlistElementId}:
+  /video-playlists/{playlistId}/videos/{playlistElementId}:
     put:
-      summary: 'Update a playlist element'
+      summary: Update a playlist element
       security:
         - OAuth2: []
       tags:
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
         - $ref: '#/components/parameters/playlistElementId'
       responses:
         '204':
@@ -1768,19 +2745,21 @@ paths:
               type: object
               properties:
                 startTimestamp:
-                  type: number
-                  description: 'Start the video at this specific timestamp (in seconds)'
+                  type: integer
+                  format: seconds
+                  description: Start the video at this specific timestamp
                 stopTimestamp:
-                  type: number
-                  description: 'Stop the video at this specific timestamp (in seconds)'
+                  type: integer
+                  format: seconds
+                  description: Stop the video at this specific timestamp
     delete:
-      summary: 'Delete an element from a playlist'
+      summary: Delete an element from a playlist
       security:
         - OAuth2: []
       tags:
         - Video Playlists
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - $ref: '#/components/parameters/playlistId'
         - $ref: '#/components/parameters/playlistElementId'
       responses:
         '204':
@@ -1788,7 +2767,7 @@ paths:
 
   '/users/me/video-playlists/videos-exist':
     get:
-      summary: 'Check video exists in my playlists'
+      summary: Check video exists in my playlists
       security:
         - OAuth2: []
       tags:
@@ -1801,7 +2780,7 @@ paths:
           schema:
             type: array
             items:
-              type: number
+              $ref: '#/components/schemas/Video/properties/id'
       responses:
         '200':
           description: successful operation
@@ -1816,13 +2795,15 @@ paths:
                       type: object
                       properties:
                         playlistElementId:
-                          type: number
+                          type: integer
                         playlistId:
-                          type: number
+                          type: integer
                         startTimestamp:
-                          type: number
+                          type: integer
+                          format: seconds
                         stopTimestamp:
-                          type: number
+                          type: integer
+                          format: seconds
 
   '/accounts/{name}/video-channels':
     get:
@@ -1832,15 +2813,21 @@ paths:
         - 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:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoChannel'
+                $ref: '#/components/schemas/VideoChannelList'
   '/accounts/{name}/ratings':
     get:
       summary: List ratings of an account
@@ -1903,6 +2890,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/CommentThreadPostResponse'
+        '404':
+          description: video does not exist
       requestBody:
         content:
           application/json:
@@ -1910,8 +2899,10 @@ paths:
               type: object
               properties:
                 text:
-                  type: string
-                  description: 'Text comment'
+                  allOf:
+                    - $ref: '#/components/schemas/VideoComment/properties/text'
+                  format: markdown
+                  maxLength: 10000
               required:
                 - text
 
@@ -1947,6 +2938,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/CommentThreadPostResponse'
+        '404':
+          description: thread or video does not exist
       requestBody:
         content:
           application/json:
@@ -1954,8 +2947,10 @@ paths:
               type: object
               properties:
                 text:
-                  type: string
-                  description: 'Text comment'
+                  allOf:
+                    - $ref: '#/components/schemas/VideoComment/properties/text'
+                  format: markdown
+                  maxLength: 10000
               required:
                 - text
 
@@ -1971,6 +2966,12 @@ paths:
       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
@@ -1980,16 +2981,42 @@ paths:
         - 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'
@@ -2001,55 +3028,43 @@ paths:
         - $ref: '#/components/parameters/count'
         - $ref: '#/components/parameters/searchTarget'
         - $ref: '#/components/parameters/videosSearchSort'
-        - 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 video information and interact with it.
-          schema:
-            type: string
         - name: startDate
           in: query
-          required: true
           description: Get videos that are published after this date
           schema:
             type: string
             format: date-time
         - name: endDate
           in: query
-          required: true
           description: Get videos that are published before this date
           schema:
             type: string
             format: date-time
         - name: originallyPublishedStartDate
           in: query
-          required: true
           description: Get videos that are originally published after this date
           schema:
             type: string
             format: date-time
         - name: originallyPublishedEndDate
           in: query
-          required: true
           description: Get videos that are originally published before this date
           schema:
             type: string
             format: date-time
         - name: durationMin
           in: query
-          required: true
           description: Get videos that have this minimum duration
           schema:
-            type: number
+            type: integer
         - name: durationMax
           in: query
-          required: true
           description: Get videos that have this maximum duration
           schema:
-            type: number
+            type: integer
+      callbacks:
+        'searchTarget === search-index':
+          $ref: '#/components/callbacks/searchIndex'
       responses:
         '200':
           description: successful operation
@@ -2057,16 +3072,14 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/VideoListResponse'
+        '500':
+          description: search index unavailable
   /search/video-channels:
     get:
       tags:
         - Search
       summary: Search channels
       parameters:
-        - $ref: '#/components/parameters/start'
-        - $ref: '#/components/parameters/count'
-        - $ref: '#/components/parameters/searchTarget'
-        - $ref: '#/components/parameters/sort'
         - name: search
           in: query
           required: true
@@ -2076,123 +3089,858 @@ paths:
             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:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoChannel'
-servers:
-  - url: 'https://peertube.cpy.re/api/v1'
-    description: Live Test Server (live data - stable version)
-  - url: 'https://peertube2.cpy.re/api/v1'
-    description: Live Test Server (live data - latest nighlty version)
-  - url: 'https://peertube3.cpy.re/api/v1'
-    description: Live Test Server (live data - latest RC version)
-components:
-  parameters:
-    start:
-      name: start
-      in: query
-      required: false
-      description: Offset
-      schema:
-        type: number
-    count:
-      name: count
-      in: query
-      required: false
-      description: "Number of items (max: 100)"
-      schema:
-        type: number
-    sort:
-      name: sort
-      in: query
-      required: false
-      description: Sort column (-createdAt for example)
-      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 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 has not the ability to make a remote URI search, then redirect the user on the origin instance or fetch
-          the data from the origin instance API
-      schema:
-        type: string
-        enum:
-          - 'local'
-          - 'search-index'
-    videosSort:
-      name: sort
-      in: query
-      required: false
-      description: Sort videos by criteria
-      schema:
-        type: string
-        enum:
-        - -name
-        - -duration
-        - -createdAt
-        - -publishedAt
-        - -views
-        - -likes
-        - -trending
-    videosSearchSort:
-      name: sort
-      in: query
-      required: false
-      description: Sort videos by criteria
-      schema:
-        type: string
-        enum:
-        - -name
-        - -duration
-        - -createdAt
-        - -publishedAt
-        - -views
-        - -likes
-        - -match
-    commentsSort:
-      name: sort
-      in: query
-      required: false
-      description: Sort comments by criteria
-      schema:
-        type: string
-        enum:
-        - -createdAt
-        - -totalReplies
-    blacklistsSort:
-      name: sort
-      in: query
-      required: false
-      description: Sort blacklists by criteria
-      schema:
-        type: string
-        enum:
-        - -id
-        - -name
-        - -duration
-        - -views
-        - -likes
-        - -dislikes
-        - -uuid
-        - -createdAt
-    usersSort:
-      name: sort
+                $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
+        enum:
+          - 'local'
+          - 'search-index'
+    videosSort:
+      name: sort
+      in: query
+      required: false
+      description: Sort videos by criteria
+      schema:
+        type: string
+        enum:
+        - name
+        - -duration
+        - -createdAt
+        - -publishedAt
+        - -views
+        - -likes
+        - -trending
+        - -hot
+    videosSearchSort:
+      name: sort
+      in: query
+      required: false
+      description: Sort videos by criteria
+      schema:
+        type: string
+        enum:
+        - name
+        - -duration
+        - -createdAt
+        - -publishedAt
+        - -views
+        - -likes
+        - -match
+    commentsSort:
+      name: sort
+      in: query
+      required: false
+      description: Sort comments by criteria
+      schema:
+        type: string
+        enum:
+        - -createdAt
+        - -totalReplies
+    blacklistsSort:
+      name: sort
+      in: query
+      required: false
+      description: Sort blacklists by criteria
+      schema:
+        type: string
+        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
@@ -2213,89 +3961,122 @@ components:
         - -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 name of the account (chocobozzz or chocobozzz@peertube.cpy.re for
-        example)
+      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:
-        type: number
+        $ref: '#/components/schemas/id'
     idOrUUID:
       name: id
       in: path
       required: true
       description: The object id or uuid
       schema:
-        type: string
+        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:
-        type: number
+        $ref: '#/components/schemas/id'
     abuseId:
       name: abuseId
       in: path
       required: true
-      description: Video abuse id
+      description: Abuse id
       schema:
-        type: number
+        $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:
-        type: string
+        $ref: '#/components/schemas/VideoLanguageSet'
     channelHandle:
       name: channelHandle
       in: path
       required: true
-      description: "The video channel handle (example: 'my_username@example.com' or 'my_username')"
+      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 (example: 'my_username@example.com' or 'my_username')"
+      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:
-        type: number
+        $ref: '#/components/schemas/VideoCommentThreadTree/properties/comment/properties/id'
     commentId:
       name: commentId
       in: path
       required: true
       description: The comment id
       schema:
-        type: number
+        $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)
+      description: category id of the video (see [/videos/categories](#operation/getCategories))
       schema:
         oneOf:
-        - type: number
+        - $ref: '#/components/schemas/VideoCategorySet'
         - type: array
           items:
-            type: number
+            $ref: '#/components/schemas/VideoCategorySet'
       style: form
       explode: false
     tagsOneOf:
@@ -2307,6 +4088,7 @@ components:
         oneOf:
         - type: string
         - type: array
+          maxItems: 5
           items:
             type: string
       style: form
@@ -2328,26 +4110,26 @@ components:
       name: languageOneOf
       in: query
       required: false
-      description: language id of the video (see /videos/languages). Use _unknown to filter on videos that don't have a video language
+      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:
-        - type: string
+        - $ref: '#/components/schemas/VideoLanguageSet'
         - type: array
           items:
-            type: string
+            $ref: '#/components/schemas/VideoLanguageSet'
       style: form
       explode: false
     licenceOneOf:
       name: licenceOneOf
       in: query
       required: false
-      description: licence id of the video (see /videos/licences)
+      description: licence id of the video (see [/videos/licences](#operation/getLicences))
       schema:
         oneOf:
-        - type: number
+        - $ref: '#/components/schemas/VideoLicenceSet'
         - type: array
           items:
-            type: number
+            $ref: '#/components/schemas/VideoLicenceSet'
       style: form
       explode: false
     skipCount:
@@ -2360,6 +4142,7 @@ components:
         enum:
           - 'true'
           - 'false'
+        default: 'false'
     nsfw:
       name: nsfw
       in: query
@@ -2375,9 +4158,10 @@ components:
       in: query
       required: false
       description: >
-        Special filters (local for instance) which might require special rights:
+        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:
@@ -2392,21 +4176,47 @@ components:
         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: >
-        In the header: *Authorization: Bearer <token\>*
-
-
+      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 <token\>*
+        - Profit, depending on the role assigned to the account
 
-
-        - Have an account with sufficient authorization levels
-
-        - [Generate](https://docs.joinpeertube.org/#/api-rest-getting-started) a
-        Bearer Token
-
-        - Make Authenticated Requests
+        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:
@@ -2416,18 +4226,71 @@ components:
             moderator: Moderator scope
             user: User scope
   schemas:
-    VideoConstantNumber:
+    # 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:
-          type: number
+          $ref: '#/components/schemas/VideoCategorySet'
         label:
           type: string
-    VideoConstantString:
+          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
@@ -2435,7 +4298,7 @@ components:
         - 1
         - 2
         - 3
-      description: 'The video playlist privacy (Public = 1, Unlisted = 2, Private = 3)'
+      description: Video playlist privacy policy (see [/video-playlists/privacies])
     VideoPlaylistPrivacyConstant:
       properties:
         id:
@@ -2448,7 +4311,7 @@ components:
       enum:
         - 1
         - 2
-      description: 'The video playlist type (Regular = 1, Watch Later = 2)'
+      description: The video playlist type (Regular = `1`, Watch Later = `2`)
     VideoPlaylistTypeConstant:
       properties:
         id:
@@ -2463,7 +4326,7 @@ components:
         - 2
         - 3
         - 4
-      description: 'The video privacy (Public = 1, Unlisted = 2, Private = 3, Internal = 4)'
+      description: privacy id of the video (see [/videos/privacies](#operation/getPrivacyPolicies))
     VideoPrivacyConstant:
       properties:
         id:
@@ -2479,12 +4342,20 @@ components:
         - do_not_list
 
     UserRole:
-      type: number
+      type: integer
       enum:
         - 0
         - 1
         - 2
-      description: 'The user role (Admin = 0, Moderator = 1, User = 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:
@@ -2494,24 +4365,24 @@ components:
             - 1
             - 2
             - 3
-          description: 'The video state (Published = 1, to transcode = 2, to import = 3)'
+          description: 'The video state (Published = `1`, to transcode = `2`, to import = `3`)'
         label:
           type: string
 
-    VideoAbuseStateSet:
+    AbuseStateSet:
       type: integer
       enum:
         - 1
         - 2
         - 3
-      description: 'The video playlist privacy (Pending = 1, Rejected = 2, Accepted = 3)'
-    VideoAbuseStateConstant:
+      description: 'The abuse state (Pending = `1`, Rejected = `2`, Accepted = `3`)'
+    AbuseStateConstant:
       properties:
         id:
-          $ref: '#/components/schemas/VideoAbuseStateSet'
+          $ref: '#/components/schemas/AbuseStateSet'
         label:
           type: string
-    VideoAbusePredefinedReasons:
+    AbusePredefinedReasons:
       type: array
       items:
         type: string
@@ -2524,14 +4395,23 @@ components:
         - 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:
-          type: integer
-          description: 'Video resolution (240, 360, 720 ...)'
+          $ref: '#/components/schemas/VideoResolutionSet'
         label:
           type: string
+          example: 240p
     VideoScheduledUpdate:
       properties:
         privacy:
@@ -2545,83 +4425,118 @@ components:
     AccountSummary:
       properties:
         id:
-          type: number
+          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/Avatar'
+            - $ref: '#/components/schemas/ActorImage'
     VideoChannelSummary:
       properties:
         id:
-          type: number
+          $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/Avatar'
+            - $ref: '#/components/schemas/ActorImage'
     PlaylistElement:
       properties:
         position:
-          type: number
+          type: integer
         startTimestamp:
-          type: number
+          type: integer
+          format: seconds
         stopTimestamp:
-          type: number
+          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: number
-          description: 'Video file size in bytes'
+          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:
-        id:
-          type: number
-        type:
-          type: number
-          enum:
-            - 1
-          description: 'Playlist type (HLS = 1)'
         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:
@@ -2631,55 +4546,113 @@ components:
             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:
-          type: number
+          description: object id for the video
+          allOf:
+            - $ref: '#/components/schemas/id'
         uuid:
-          type: string
+          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:
-          $ref: '#/components/schemas/VideoConstantNumber'
+          allOf:
+            - $ref: '#/components/schemas/VideoConstantNumber-Category'
+          description: category in which the video is classified
         licence:
-          $ref: '#/components/schemas/VideoConstantNumber'
+          allOf:
+            - $ref: '#/components/schemas/VideoConstantNumber-Licence'
+          description: licence under which the video is distributed
         language:
-          $ref: '#/components/schemas/VideoConstantString'
+          allOf:
+            - $ref: '#/components/schemas/VideoConstantString-Language'
+          description: main language used in the video
         privacy:
-          $ref: '#/components/schemas/VideoPrivacyConstant'
+          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: number
+          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: number
+          type: integer
+          example: 1337
         likes:
-          type: number
+          type: integer
+          example: 42
         dislikes:
-          type: number
+          type: integer
+          example: 7
         nsfw:
           type: boolean
         waitTranscoding:
           type: boolean
           nullable: true
         state:
-          $ref: '#/components/schemas/VideoStateConstant'
+          allOf:
+            - $ref: '#/components/schemas/VideoStateConstant'
+          description: represents the internal state of the video processing within the PeerTube instance
         scheduledUpdate:
           nullable: true
           allOf:
@@ -2699,7 +4672,7 @@ components:
           type: object
           properties:
             currentTime:
-              type: number
+              type: integer
     VideoDetails:
       allOf:
         - $ref: '#/components/schemas/Video'
@@ -2707,20 +4680,27 @@ components:
           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
-            files:
-              type: array
-              items:
-                $ref: '#/components/schemas/VideoFile'
+                minLength: 2
+                maxLength: 30
             commentsEnabled:
               type: boolean
             downloadEnabled:
@@ -2729,10 +4709,75 @@ components:
               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:
@@ -2741,118 +4786,183 @@ components:
             - 1
             - 2
             - 3
-          description: 'The video import state (Pending = 1, Success = 2, Failed = 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:
-          type: number
+          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:
-          type: object
-          properties:
-            id:
-              $ref: '#/components/schemas/VideoImportStateConstant'
-            label:
-              type: string
+          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:
-          $ref: '#/components/schemas/Video'
-    VideoAbuse:
+          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:
-          type: number
+          $ref: '#/components/schemas/id'
         reason:
           type: string
+          example: The video is a spam
+          minLength: 2
+          maxLength: 3000
         predefinedReasons:
-          $ref: '#/components/schemas/VideoAbusePredefinedReasons'
+          $ref: '#/components/schemas/AbusePredefinedReasons'
         reporterAccount:
           $ref: '#/components/schemas/Account'
         state:
-          $ref: '#/components/schemas/VideoAbuseStateConstant'
+          $ref: '#/components/schemas/AbuseStateConstant'
         moderationComment:
           type: string
+          example: Decided to ban the server since it spams us regularly
+          minLength: 2
+          maxLength: 3000
         video:
-          type: object
-          properties:
-            id:
-              type: number
-            name:
-              type: string
-            uuid:
-              type: string
+          $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:
-          type: number
+          $ref: '#/components/schemas/id'
         videoId:
-          type: number
+          $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:
-          type: string
+          $ref: '#/components/schemas/UUIDv4'
         description:
           type: string
+          minLength: 3
+          maxLength: 10000
         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: integer
+        views:
+          type: integer
+        likes:
+          type: integer
+        dislikes:
+          type: integer
+        nsfw:
           type: boolean
-        ownerAccount:
-          type: object
-          properties:
-            id:
-              type: number
-            uuid:
-              type: string
     VideoPlaylist:
       properties:
         id:
-          type: number
+          $ref: '#/components/schemas/id'
+        uuid:
+          $ref: '#/components/schemas/UUIDv4'
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         description:
           type: string
-        uuid:
-          type: string
+          minLength: 3
+          maxLength: 1000
         displayName:
           type: string
+          minLength: 1
+          maxLength: 120
         isLocal:
           type: boolean
         videoLength:
-          type: number
+          type: integer
+          minimum: 0
         thumbnailPath:
           type: string
         privacy:
@@ -2866,25 +4976,44 @@ components:
     VideoComment:
       properties:
         id:
-          type: number
+          $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:
-          type: number
+          $ref: '#/components/schemas/id'
         inReplyToCommentId:
-          type: number
+          nullable: true
+          allOf:
+            - $ref: '#/components/schemas/id'
         videoId:
-          type: number
+          $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: number
+          type: integer
+          minimum: 0
         totalReplies:
-          type: number
+          type: integer
+          minimum: 0
         account:
           $ref: '#/components/schemas/Account'
     VideoCommentThreadTree:
@@ -2898,109 +5027,93 @@ components:
     VideoCaption:
       properties:
         language:
-          $ref: '#/components/schemas/VideoConstantString'
+          $ref: '#/components/schemas/VideoConstantString-Language'
         captionPath:
           type: string
-    Avatar:
+    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:
-          type: number
+          $ref: '#/components/schemas/id'
         url:
           type: string
+          format: url
         name:
-          type: string
+          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: number
+          type: integer
+          minimum: 0
+          description: number of actors subscribed to by this actor, as seen by this instance
         followersCount:
-          type: number
+          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/Avatar'
+          $ref: '#/components/schemas/ActorImage'
     Account:
       allOf:
         - $ref: '#/components/schemas/Actor'
         - properties:
             userId:
-              type: string
+              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
-    User:
-      properties:
-        id:
-          type: number
-        username:
-          type: string
-        email:
-          type: string
-        theme:
-          type: string
-          description: 'Theme enabled by this user'
-        emailVerified:
-          type: boolean
-          description: 'Is email verified?'
-        nsfwPolicy:
-          $ref: '#/components/schemas/NSFWPolicy'
-        webtorrentEnabled:
-          type: boolean
-        autoPlayVideo:
-          type: boolean
-        role:
-          $ref: '#/components/schemas/UserRole'
-        roleLabel:
-          type: string
-          enum:
-            - User
-            - Moderator
-            - Administrator
-        videoQuota:
-          type: number
-        videoQuotaDaily:
-          type: number
-        videosCount:
-          type: number
-        videoAbusesCount:
-          type: number
-        videoAbusesAcceptedCount:
-          type: number
-        videoAbusesCreatedCount:
-          type: number
-        videoCommentsCount:
-          type: number
-        noInstanceConfigWarningModal:
-          type: boolean
-        noWelcomeModal:
-          type: boolean
-        blocked:
-          type: boolean
-        blockedReason:
-          type: string
-        createdAt:
-          type: string
-        account:
-          $ref: '#/components/schemas/Account'
-        videoChannels:
-          type: array
-          items:
-            $ref: '#/components/schemas/VideoChannel'
+              description: text or bio displayed on the account's profile
     UserWatchingVideo:
       properties:
         currentTime:
-          type: number
+          type: integer
+          format: seconds
+          description: timestamp within the video, in seconds
+          example: 5
     ServerConfig:
       properties:
         instance:
@@ -3086,7 +5199,7 @@ components:
             enabledResolutions:
               type: array
               items:
-                type: number
+                $ref: '#/components/schemas/VideoResolutionSet'
         import:
           type: object
           properties:
@@ -3124,7 +5237,7 @@ components:
                   type: object
                   properties:
                     max:
-                      type: number
+                      type: integer
             extensions:
               type: array
               items:
@@ -3143,7 +5256,7 @@ components:
                   type: object
                   properties:
                     max:
-                      type: number
+                      type: integer
             file:
               type: object
               properties:
@@ -3161,7 +5274,7 @@ components:
                   type: object
                   properties:
                     max:
-                      type: number
+                      type: integer
                 extensions:
                   type: array
                   items:
@@ -3170,9 +5283,11 @@ components:
           type: object
           properties:
             videoQuota:
-              type: number
+              type: integer
+              example: 16810141515
             videoQuotaDaily:
-              type: number
+              type: integer
+              example: 1681014151
         trending:
           type: object
           properties:
@@ -3180,7 +5295,7 @@ components:
               type: object
               properties:
                 intervalDays:
-                  type: number
+                  type: integer
         tracker:
           type: object
           properties:
@@ -3197,6 +5312,7 @@ components:
                   properties:
                     indexUrl:
                       type: string
+                      format: url
     ServerConfigAbout:
       properties:
         instance:
@@ -3258,19 +5374,19 @@ components:
               type: object
               properties:
                 size:
-                  type: number
+                  type: integer
             captions:
               type: object
               properties:
                 size:
-                  type: number
+                  type: integer
         signup:
           type: object
           properties:
             enabled:
               type: boolean
             limit:
-              type: number
+              type: integer
             requiresEmailVerification:
               type: boolean
         admin:
@@ -3278,6 +5394,7 @@ components:
           properties:
             email:
               type: string
+              format: email
         contactForm:
           type: object
           properties:
@@ -3285,25 +5402,44 @@ components:
               type: boolean
         user:
           type: object
+          description: Settings that apply to new users, if registration is enabled
           properties:
             videoQuota:
-              type: number
+              type: integer
+              example: 16810141515
             videoQuotaDaily:
-              type: number
+              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:
@@ -3314,10 +5450,19 @@ components:
                   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
@@ -3361,13 +5506,14 @@ components:
     Follow:
       properties:
         id:
-          type: number
+          $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:
@@ -3375,53 +5521,200 @@ components:
             - 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
+        enum:
+        - violentOrAbusive
+        - hatefulOrAbusive
+        - spamOrMisleading
+        - privacy
+        - rights
+        - serverRules
+        - thumbnails
+        - captions
+
     Job:
       properties:
         id:
-          type: number
+          $ref: '#/components/schemas/id'
         state:
           type: string
           enum:
-            - pending
-            - processing
-            - error
-            - success
-        category:
+            - active
+            - completed
+            - failed
+            - waiting
+            - delayed
+        type:
           type: string
           enum:
-            - transcoding
-            - activitypub-http
-        handlerName:
-          type: string
-        handlerInputData:
-          type: string
+            - 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
-        updatedAt:
+          format: date-time
+        finishedOn:
           type: string
+          format: date-time
+        processedOn:
+          type: string
+          format: date-time
     AddUserResponse:
       properties:
-        id:
-          type: number
-        uuid:
+        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
+            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:
-              type: number
+              $ref: '#/components/schemas/Video/properties/id'
             uuid:
-              type: string
+              $ref: '#/components/schemas/Video/properties/uuid'
     CommentThreadResponse:
       properties:
         total:
-          type: number
+          type: integer
+          example: 1
         data:
           type: array
+          maxItems: 100
           items:
             $ref: '#/components/schemas/VideoComment'
     CommentThreadPostResponse:
@@ -3431,30 +5724,127 @@ components:
     VideoListResponse:
       properties:
         total:
-          type: number
+          type: integer
+          example: 1
         data:
           type: array
+          maxItems: 100
           items:
             $ref: '#/components/schemas/Video'
-    AddUser:
+    User:
       properties:
-        username:
+        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
-          description: 'The user username '
-        password:
+        createdAt:
           type: string
-          description: 'The user password. If the smtp server is configured, you can leave empty and an email will be sent '
         email:
           type: string
-          description: 'The user email '
+          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
-          description: 'The user videoQuota '
+          format: email
+          description: The user email
+        videoQuota:
+          type: integer
+          description: The user video quota in bytes
+          example: -1
         videoQuotaDaily:
-          type: string
-          description: 'The user daily video quota '
+          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
@@ -3464,53 +5854,88 @@ components:
         - role
     UpdateUser:
       properties:
-        id:
-          type: string
-          description: 'The user id '
         email:
-          type: string
-          description: 'The updated email of the user '
+          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: string
-          description: 'The updated videoQuota of the user '
+          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
-          description: 'The updated daily video quota of the user '
+          nullable: true
+          description: The auth plugin to use to authenticate the user
+          example: 'peertube-plugin-auth-saml2'
         role:
           $ref: '#/components/schemas/UserRole'
-      required:
-        - id
-        - email
-        - videoQuota
-        - videoQuotaDaily
-        - role
+        adminFlags:
+          $ref: '#/components/schemas/UserAdminFlags'
     UpdateMe:
+      # see shared/models/users/user-update-me.model.ts:
       properties:
         password:
-          type: string
-          description: 'Your new 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: 'Your new email '
+          description: new name of the user in its representations
+          minLength: 3
+          maxLength: 120
         displayNSFW:
           type: string
-          description: 'Your new displayNSFW '
+          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
-          description: 'Your new autoPlayVideo '
-      required:
-        - password
-        - email
-        - displayNSFW
-        - autoPlayVideo
+        noInstanceConfigWarningModal:
+          type: boolean
+        noWelcomeModal:
+          type: boolean
     GetMeVideoRating:
       properties:
         id:
-          type: string
-          description: 'Id of the video '
+          $ref: '#/components/schemas/id'
         rating:
-          type: number
-          description: 'Rating of the video '
+          type: string
+          enum:
+            - like
+            - dislike
+            - none
+          description: Rating of the video
       required:
         - id
         - rating
@@ -3519,61 +5944,544 @@ components:
         video:
           $ref: '#/components/schemas/Video'
         rating:
-          type: number
-          description: 'Rating of the video'
+          type: string
+          enum:
+            - like
+            - dislike
+            - none
+          description: Rating of the video
       required:
         - video
         - rating
     RegisterUser:
       properties:
         username:
-          type: string
-          description: 'The username of the user '
+          description: immutable name of the user, used to find or mention its actor
+          allOf:
+            - $ref: '#/components/schemas/username'
         password:
-          type: string
-          description: 'The password of the user '
+          $ref: '#/components/schemas/password'
         email:
           type: string
-          description: 'The email of the user '
+          format: email
+          description: email of the user, used for login or service communications
         displayName:
           type: string
-          description: 'The user display name'
+          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:
-              type: string
-              description: 'The default channel name'
+              $ref: '#/components/schemas/usernameChannel'
             displayName:
-              type: string
-              description: 'The default channel display name'
-
+              $ref: '#/components/schemas/VideoChannel/properties/displayName'
       required:
         - username
         - password
         - email
-    VideoChannelCreate:
+
+    VideoChannel:
       properties:
-        name:
-          type: string
+        # 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:
-        displayName:
+        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:
+          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:
+          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:
+              'media:statistics':
+                type: object
+                properties:
+                  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
+              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
+                  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
+
+            - `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
-        support:
+        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
-        bulkVideosSupportUpdate:
+        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
-          description: 'Update all videos support field of this channel'
 
+
+
+  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'