]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - support/doc/api/openapi.yaml
Handle playlist position in URL
[github/Chocobozzz/PeerTube.git] / support / doc / api / openapi.yaml
index ac44cf91d1eec9f4fa3959ef8d6cf8246d6937c4..9922a321605d4d3b576e1c50255eb22aefd8b33f 100644 (file)
@@ -1,7 +1,7 @@
 openapi: 3.0.0
 info:
   title: PeerTube
-  version: 2.2.0
+  version: 2.3.0
   contact:
     name: PeerTube Community
     url: 'https://joinpeertube.org'
@@ -31,6 +31,11 @@ info:
     sessions, and authenticate using this session token. 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
@@ -48,9 +53,29 @@ externalDocs:
 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 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
@@ -66,9 +91,24 @@ 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`.
+    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.
@@ -109,22 +149,24 @@ x-tagGroups:
       - Users
       - My User
       - My Subscriptions
+      - My Notifications
   - name: Videos
     tags:
       - Video
-      - Video Caption
+      - Video Captions
       - Video Channels
       - Video Comments
       - Video Rates
       - Video Playlists
       - Video Ownership Change
+      - Video Mirroring
       - Feeds
   - name: Search
     tags:
       - Search
   - name: Moderation
     tags:
-      - Video Abuses
+      - Abuses
       - Video Blocks
       - Account Blocks
       - Server Blocks
@@ -132,6 +174,8 @@ x-tagGroups:
     tags:
       - Config
       - Instance Follows
+      - Instance Redundancy
+      - Plugins
   - name: Jobs
     tags:
       - Job
@@ -189,8 +233,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'
@@ -279,6 +323,12 @@ paths:
       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:
@@ -319,9 +369,16 @@ 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:
@@ -337,6 +394,7 @@ paths:
           description: 'The host to unfollow '
           schema:
             type: string
+            format: hostname
       responses:
         '201':
           description: successful operation
@@ -362,8 +420,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'
@@ -386,11 +461,20 @@ paths:
       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
@@ -401,11 +485,29 @@ paths:
         - 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:
@@ -416,10 +518,13 @@ paths:
     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'
@@ -433,6 +538,8 @@ paths:
                 items:
                   $ref: '#/components/schemas/User'
   '/users/{id}':
+    parameters:
+      - $ref: '#/components/parameters/id'
     delete:
       summary: Delete a user
       security:
@@ -440,8 +547,7 @@ paths:
             - admin
       tags:
         - Users
-      parameters:
-        - $ref: '#/components/parameters/id'
+      operationId: delUserId
       responses:
         '204':
           description: successful operation
@@ -451,8 +557,7 @@ paths:
         - OAuth2: []
       tags:
         - Users
-      parameters:
-        - $ref: '#/components/parameters/id'
+      operationId: getUserId
       responses:
         '200':
           description: successful operation
@@ -466,8 +571,7 @@ paths:
         - OAuth2: []
       tags:
         - Users
-      parameters:
-        - $ref: '#/components/parameters/id'
+      operationId: putUserId
       responses:
         '204':
           description: successful operation
@@ -617,12 +721,28 @@ paths:
         '200':
           description: successful operation
     post:
+      tags:
+        - My Subscriptions
       summary: Add subscription to my user
       security:
         - OAuth2:
             - user
-      tags:
-        - My Subscriptions
+      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
@@ -700,6 +820,102 @@ 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/avatar/pick:
     post:
       summary: Update my user avatar
@@ -834,6 +1050,9 @@ 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
@@ -848,6 +1067,9 @@ 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
@@ -862,6 +1084,9 @@ 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
@@ -876,6 +1101,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
@@ -904,10 +1132,12 @@ paths:
                   format: binary
                 category:
                   description: Video category
-                  type: string
+                  type: integer
+                  example: 4
                 licence:
                   description: Video licence
-                  type: string
+                  type: integer
+                  example: 2
                 language:
                   description: Video language
                   type: string
@@ -920,11 +1150,12 @@ 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 my work on <insert crowdfunding plateform>! <3
                   type: string
                 nsfw:
                   description: Whether or not this video contains sensitive content
-                  type: string
+                  type: boolean
                 name:
                   description: Video name
                   type: string
@@ -939,7 +1170,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
@@ -1032,11 +1263,11 @@ paths:
               schema:
                 $ref: '#/components/schemas/VideoUploadResponse'
         '403':
-          description: 'The user video quota is exceeded with this video.'
+          description: user video quota is exceeded with this video
         '408':
-          description: 'Upload has timed out'
+          description: upload has timed out
         '422':
-          description: 'Invalid input file.'
+          description: invalid input file
       requestBody:
         content:
           multipart/form-data:
@@ -1062,13 +1293,15 @@ paths:
                   $ref: '#/components/schemas/VideoPrivacySet'
                 category:
                   description: Video category
-                  type: string
+                  type: integer
+                  example: 4
                 licence:
                   description: Video licence
                   type: string
                 language:
                   description: Video language
-                  type: string
+                  type: integer
+                  example: 2
                 description:
                   description: Video description
                   type: string
@@ -1076,11 +1309,12 @@ 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 my work on <insert crowdfunding plateform>! <3
                   type: string
                 nsfw:
                   description: Whether or not this video contains sensitive content
-                  type: string
+                  type: boolean
                 name:
                   description: Video name
                   type: string
@@ -1096,7 +1330,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
@@ -1117,8 +1351,7 @@ paths:
       x-code-samples:
         - lang: Shell
           source: |
-            ## DEPENDENCIES: httpie, jq
-            # pip install httpie
+            ## DEPENDENCIES: jq
             USERNAME="<your_username>"
             PASSWORD="<your_password>"
             FILE_PATH="<your_file_path>"
@@ -1127,19 +1360,23 @@ 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/imports:
     post:
       summary: Import a video
@@ -1193,7 +1430,8 @@ 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 my work on <insert crowdfunding plateform>! <3
                   type: string
                 nsfw:
                   description: Whether or not this video contains sensitive content
@@ -1236,16 +1474,104 @@ paths:
           description: HTTP or Torrent/magnetURI import not enabled
         '400':
           description: '`magnetUri` or `targetUrl` or a torrent file missing'
-  /videos/abuse:
+
+  /users/me/abuses:
+    get:
+      summary: List my abuses
+      security:
+        - OAuth2: []
+      tags:
+        - Abuses
+        - My User
+      parameters:
+        - name: id
+          in: query
+          description: only list the report with this id
+          schema:
+            type: integer
+        - name: state
+          in: query
+          schema:
+            $ref: '#/components/schemas/AbuseStateSet'
+        - $ref: '#/components/parameters/start'
+        - $ref: '#/components/parameters/count'
+        - $ref: '#/components/parameters/abusesSort'
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/Abuse'
+
+  /abuses:
     get:
-      summary: List video abuses
+      summary: List abuses
       security:
         - OAuth2:
           - admin
           - moderator
       tags:
-        - Video Abuses
+        - 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'
@@ -1257,17 +1583,14 @@ paths:
               schema:
                 type: array
                 items:
-                  $ref: '#/components/schemas/VideoAbuse'
-  '/videos/{id}/abuse':
+                  $ref: '#/components/schemas/Abuse'
+
     post:
       summary: Report an abuse
       security:
         - OAuth2: []
       tags:
-        - Video Abuses
-        - Videos
-      parameters:
-        - $ref: '#/components/parameters/idOrUUID'
+        - Abuses
       requestBody:
         required: true
         content:
@@ -1278,32 +1601,44 @@ paths:
                 reason:
                   description: Reason why the user reports this video
                   type: string
+                  minLength: 4
                 predefinedReasons:
-                  description: Reason categories that help triage reports
-                  type: array
-                  items:
-                    type: string
-                    enum:
-                    - violentOrAbusive
-                    - hatefulOrAbusive
-                    - spamOrMisleading
-                    - privacy
-                    - rights
-                    - serverRules
-                    - thumbnails
-                    - captions
-                startAt:
-                  type: integer
-                  description: Timestamp in the video that marks the beginning of the report
-                endAt:
-                  type: integer
-                  description: Timestamp in the video that marks the ending of the report
+                  $ref: '#/components/schemas/PredefinedAbuseReasons'
+
+                video:
+                  type: object
+                  properties:
+                    id:
+                      description: Video id to report
+                      type: number
+                    startAt:
+                      type: integer
+                      description: Timestamp in the video that marks the beginning of the report
+                      minimum: 0
+                    endAt:
+                      type: integer
+                      description: Timestamp in the video that marks the ending of the report
+                      minimum: 0
+                comment:
+                  type: object
+                  properties:
+                    id:
+                      description: Comment id to report
+                      type: number
+                account:
+                  type: object
+                  properties:
+                    id:
+                      description: Account id to report
+                      type: number
               required:
                 - reason
       responses:
         '204':
           description: successful operation
-  '/videos/{id}/abuse/{abuseId}':
+        '400':
+          description: incorrect request parameters
+  '/abuses/{abuseId}':
     put:
       summary: Update an abuse
       security:
@@ -1311,14 +1646,8 @@ paths:
           - admin
           - moderator
       tags:
-        - Video Abuses
-      responses:
-        '204':
-          description: successful operation
-        '404':
-          description: video abuse not found
+        - Abuses
       parameters:
-        - $ref: '#/components/parameters/idOrUUID'
         - $ref: '#/components/parameters/abuseId'
       requestBody:
         content:
@@ -1327,26 +1656,87 @@ paths:
               type: object
               properties:
                 state:
-                  $ref: '#/components/schemas/VideoAbuseStateSet'
+                  $ref: '#/components/schemas/AbuseStateSet'
                 moderationComment:
                   type: string
-                  description: 'Update the comment of the video abuse for other admin/moderators'
+                  description: Update the report comment visible only to the moderation team
+      responses:
+        '204':
+          description: successful operation
+        '404':
+          description: abuse not found
     delete:
+      tags:
+        - Abuses
       summary: Delete an abuse
       security:
         - OAuth2:
             - admin
             - moderator
-      tags:
-        - Video Abuses
+      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
+              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/idOrUUID'
         - $ref: '#/components/parameters/abuseId'
+        - $ref: '#/components/parameters/abuseMessageId'
+      responses:
+        '204':
+          description: successful operation
 
   '/videos/{id}/blacklist':
     post:
@@ -1381,13 +1771,31 @@ paths:
     get:
       tags:
         - Video Blocks
-      summary: List blocked videos
+      summary: List video blocks
       security:
         - OAuth2:
             - admin
             - moderator
       parameters:
-        - $ref: '#/components/parameters/start'
+        - 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:
@@ -1396,14 +1804,20 @@ paths:
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoBlacklist'
+                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:
@@ -1416,6 +1830,7 @@ paths:
                 properties:
                   total:
                     type: integer
+                    example: 1
                   data:
                     type: array
                     items:
@@ -1424,7 +1839,7 @@ paths:
     put:
       summary: Add or replace a video caption
       tags:
-        - Video Caption
+        - Video Captions
       parameters:
         - $ref: '#/components/parameters/idOrUUID'
         - $ref: '#/components/parameters/captionLanguage'
@@ -1449,7 +1864,7 @@ paths:
     delete:
       summary: Delete a video caption
       tags:
-        - Video Caption
+        - Video Captions
       parameters:
         - $ref: '#/components/parameters/idOrUUID'
         - $ref: '#/components/parameters/captionLanguage'
@@ -1473,9 +1888,15 @@ paths:
           content:
             application/json:
               schema:
-                type: array
-                items:
-                  $ref: '#/components/schemas/VideoChannel'
+                type: object
+                properties:
+                  total:
+                    type: integer
+                    example: 1
+                  data:
+                    type: array
+                    items:
+                      $ref: '#/components/schemas/VideoChannel'
     post:
       summary: Create a video channel
       security:
@@ -1572,6 +1993,9 @@ paths:
                 type: array
                 items:
                   type: string
+              examples:
+                nightly:
+                  externalValue: https://peertube2.cpy.re/api/v1/video-playlists/privacies
 
   /video-playlists:
     get:
@@ -1588,9 +2012,15 @@ 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.'
@@ -1636,6 +2066,9 @@ paths:
                   type: integer
               required:
                 - displayName
+            encoding:
+              thumbnailfile:
+                contentType: image/jpeg
 
   /video-playlists/{id}:
     get:
@@ -1684,6 +2117,9 @@ paths:
                 videoChannelId:
                   description: Video channel in which the playlist will be published
                   type: integer
+            encoding:
+              thumbnailfile:
+                contentType: image/jpeg
     delete:
       summary: Delete a video playlist
       security:
@@ -1869,6 +2305,14 @@ 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
@@ -1940,6 +2384,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/CommentThreadPostResponse'
+        '404':
+          description: video does not exist
       requestBody:
         content:
           application/json:
@@ -1984,6 +2430,8 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/CommentThreadPostResponse'
+        '404':
+          description: thread or video does not exist
       requestBody:
         content:
           application/json:
@@ -2008,6 +2456,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
@@ -2020,12 +2474,24 @@ paths:
       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/tagsOneOf'
         - $ref: '#/components/parameters/tagsAllOf'
@@ -2038,55 +2504,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: integer
         - name: durationMax
           in: query
-          required: true
           description: Get videos that have this maximum duration
           schema:
             type: integer
+      callbacks:
+        'searchTarget === search-index':
+          $ref: '#/components/callbacks/searchIndex'
       responses:
         '200':
           description: successful operation
@@ -2094,16 +2548,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
@@ -2113,6 +2565,13 @@ 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
@@ -2122,6 +2581,8 @@ paths:
                 type: array
                 items:
                   $ref: '#/components/schemas/VideoChannel'
+        '500':
+          description: search index unavailable
   /blocklist/accounts:
     get:
       tags:
@@ -2152,6 +2613,7 @@ paths:
               properties:
                 accountName:
                   type: string
+                  example: chocobozzz@example.org
                   description: account to block, in the form `username@domain`
               required:
                 - accountName
@@ -2208,11 +2670,12 @@ paths:
             schema:
               type: object
               properties:
-                accountName:
+                host:
                   type: string
+                  format: hostname
                   description: server domain to block
               required:
-                - accountName
+                - host
       responses:
         '200':
           description: successful operation
@@ -2233,28 +2696,137 @@ paths:
           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:
+                  type: integer
+              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
       servers:
-        - url: 'https://peertube.cpy.re'
-          description: Live Test Server (live data - stable version)
         - url: 'https://peertube2.cpy.re'
-          description: Live Test Server (live data - latest nighlty version)
+          description: Live Test Server (live data - latest nightly version)
         - url: 'https://peertube3.cpy.re'
           description: Live Test Server (live data - latest RC version)
+        - url: 'https://peertube.cpy.re'
+          description: Live Test Server (live data - stable version)
       parameters:
         - name: format
           in: path
           required: true
-          description: 'format expected (we focus on making `rss` the most featureful ; it serves Media RSS)'
+          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:
@@ -2270,6 +2842,26 @@ paths:
           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
@@ -2294,6 +2886,13 @@ paths:
             application/json:
               schema:
                 type: object
+        '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}':
@@ -2302,17 +2901,17 @@ paths:
         - Feeds
       summary: List videos
       servers:
-        - url: 'https://peertube.cpy.re'
-          description: Live Test Server (live data - stable version)
         - url: 'https://peertube2.cpy.re'
-          description: Live Test Server (live data - latest nighlty version)
+          description: Live Test Server (live data - latest nightly version)
         - url: 'https://peertube3.cpy.re'
           description: Live Test Server (live data - latest RC version)
+        - url: 'https://peertube.cpy.re'
+          description: Live Test Server (live data - stable version)
       parameters:
         - name: format
           in: path
           required: true
-          description: 'format expected (we focus on making `rss` the most featureful ; it serves Media RSS)'
+          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:
@@ -2343,6 +2942,9 @@ paths:
           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
@@ -2355,6 +2957,9 @@ paths:
             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'
@@ -2367,69 +2972,314 @@ paths:
             application/json:
               schema:
                 type: object
+        '404':
+          description: video channel or account not found
         '406':
           description: accept header unsupported
-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 used to paginate results
-      schema:
-        type: integer
-    count:
-      name: count
-      in: query
-      required: false
-      description: "Number of items to return"
-      schema:
-        type: integer
-        maximum: 100
-        minimum: 1
-    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
+  /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
+        - name
         - -duration
         - -createdAt
         - -publishedAt
@@ -2444,7 +3294,7 @@ components:
       schema:
         type: string
         enum:
-        - -name
+        - name
         - -duration
         - -createdAt
         - -publishedAt
@@ -2470,13 +3320,27 @@ components:
         type: string
         enum:
         - -id
-        - -name
+        - 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
@@ -2499,15 +3363,23 @@ 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@example.org` for
-        example)
+      description: The name of the account
       schema:
         type: string
+        example: chocobozzz | chocobozzz@example.org
     id:
       name: id
       in: path
@@ -2515,13 +3387,21 @@ components:
       description: The user id
       schema:
         type: integer
+        minimum: 0
+        example: 42
     idOrUUID:
       name: id
       in: path
       required: true
       description: The object id or uuid
       schema:
-        type: string
+        oneOf:
+          - type: integer
+            minimum: 0
+            example: 42
+          - type: string
+            format: uuid
+            example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
     playlistElementId:
       name: playlistElementId
       in: path
@@ -2533,7 +3413,14 @@ components:
       name: abuseId
       in: path
       required: true
-      description: Video abuse id
+      description: Abuse id
+      schema:
+        type: integer
+    abuseMessageId:
+      name: abuseMessageId
+      in: path
+      required: true
+      description: Abuse message id
       schema:
         type: integer
     captionLanguage:
@@ -2547,16 +3434,18 @@ components:
       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
@@ -2575,7 +3464,7 @@ components:
       name: categoryOneOf
       in: query
       required: false
-      description: category id of the video (see /videos/categories)
+      description: category id of the video (see [/videos/categories](#tag/Video/paths/~1videos~1categories/get))
       schema:
         oneOf:
         - type: integer
@@ -2614,7 +3503,7 @@ 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](#tag/Video/paths/~1videos~1languages/get)). Use `_unknown` to filter on videos that don't have a video language
       schema:
         oneOf:
         - type: string
@@ -2627,7 +3516,7 @@ components:
       name: licenceOneOf
       in: query
       required: false
-      description: licence id of the video (see /videos/licences)
+      description: licence id of the video (see [/videos/licences](#tag/Video/paths/~1videos~1licences/get))
       schema:
         oneOf:
         - type: integer
@@ -2679,6 +3568,15 @@ 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
   securitySchemes:
     OAuth2:
       description: >
@@ -2772,6 +3670,7 @@ components:
         - 1
         - 2
       description: 'The user role (Admin = `0`, Moderator = `1`, User = `2`)'
+      example: 2
 
     VideoStateConstant:
       properties:
@@ -2785,20 +3684,20 @@ components:
         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
@@ -2811,14 +3710,17 @@ components:
         - serverRules
         - thumbnails
         - captions
+      example: [spamOrMisleading]
 
     VideoResolutionConstant:
       properties:
         id:
           type: integer
           description: 'Video resolution (240, 360, 720 ...)'
+          example: 240
         label:
           type: string
+          example: 240p
     VideoScheduledUpdate:
       properties:
         privacy:
@@ -2839,8 +3741,10 @@ components:
           type: string
         url:
           type: string
+          format: url
         host:
           type: string
+          format: hostname
         avatar:
           nullable: true
           allOf:
@@ -2855,8 +3759,10 @@ components:
           type: string
         url:
           type: string
+          format: url
         host:
           type: string
+          format: hostname
         avatar:
           nullable: true
           allOf:
@@ -2884,16 +3790,21 @@ components:
           description: 'Video file size in bytes'
         torrentUrl:
           type: string
+          format: url
         torrentDownloadUrl:
           type: string
+          format: url
         fileUrl:
           type: string
+          format: url
         fileDownloadUrl:
           type: string
+          format: url
         fps:
           type: number
         metadataUrl:
           type: string
+          format: url
     VideoStreamingPlaylists:
       properties:
         id:
@@ -2905,8 +3816,10 @@ components:
           description: 'Playlist type (HLS = `1`)'
         playlistUrl:
           type: string
+          format: url
         segmentsSha256Url:
           type: string
+          format: url
         files:
           type: array
           items:
@@ -2918,20 +3831,38 @@ components:
             properties:
               baseUrl:
                 type: string
+                format: url
+    VideoInfo:
+      properties:
+        id:
+          type: integer
+        uuid:
+          type: string
+          format: uuid
+          example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
+        name:
+          type: string
     Video:
       properties:
         id:
           type: integer
+          example: 8
         uuid:
           type: string
+          format: uuid
+          example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
         createdAt:
           type: string
+          format: date-time
         publishedAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         originallyPublishedAt:
           type: string
+          format: date-time
         category:
           $ref: '#/components/schemas/VideoConstantNumber'
         licence:
@@ -2944,22 +3875,30 @@ components:
           type: string
         duration:
           type: integer
+          example: 1419
         isLocal:
           type: boolean
         name:
           type: string
+          example: What is PeerTube?
         thumbnailPath:
           type: string
+          example: /static/thumbnails/a65bc12f-9383-462e-81ae-8207e8b434ee.jpg
         previewPath:
           type: string
+          example: /static/previews/a65bc12f-9383-462e-81ae-8207e8b434ee.jpg
         embedPath:
           type: string
+          example: /videos/embed/a65bc12f-9383-462e-81ae-8207e8b434ee
         views:
           type: integer
+          example: 1337
         likes:
           type: integer
+          example: 42
         dislikes:
           type: integer
+          example: 7
         nsfw:
           type: boolean
         waitTranscoding:
@@ -2996,6 +3935,8 @@ components:
               type: string
             support:
               type: string
+              description: A text tell the audience how to support the video creator
+              example: Please support my work on <insert crowdfunding plateform>! <3
             channel:
               $ref: '#/components/schemas/VideoChannel'
             account:
@@ -3004,6 +3945,7 @@ components:
               type: array
               items:
                 type: string
+              example: [flowers, gardening]
             files:
               type: array
               items:
@@ -3016,10 +3958,60 @@ components:
               type: array
               items:
                 type: string
+                format: url
             streamingPlaylists:
               type: array
               items:
                 $ref: '#/components/schemas/VideoStreamingPlaylists'
+    FileRedundancyInformation:
+      properties:
+        id:
+          type: integer
+        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:
+          type: integer
+        name:
+          type: string
+        url:
+          type: string
+          format: url
+        uuid:
+          type: string
+          format: uuid
+          example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
+        redundancies:
+          type: object
+          properties:
+            files:
+              type: array
+              items:
+                $ref: '#/components/schemas/FileRedundancyInformation'
+            streamingPlaylists:
+              type: array
+              items:
+                $ref: '#/components/schemas/FileRedundancyInformation'
     VideoImportStateConstant:
       properties:
         id:
@@ -3031,45 +4023,51 @@ components:
           description: 'The video import state (Pending = `1`, Success = `2`, Failed = `3`)'
         label:
           type: string
+          example: Pending
     VideoImport:
       properties:
         id:
           type: integer
+          example: 2
         targetUrl:
           type: string
+          format: url
+          example: https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d
         magnetUri:
           type: string
+          format: uri
+          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
         torrentName:
           type: string
         state:
-          type: object
-          properties:
-            id:
-              $ref: '#/components/schemas/VideoImportStateConstant'
-            label:
-              type: string
+          $ref: '#/components/schemas/VideoImportStateConstant'
         error:
           type: string
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         video:
           $ref: '#/components/schemas/Video'
-    VideoAbuse:
+    Abuse:
       properties:
         id:
           type: integer
+          example: 7
         reason:
           type: string
+          example: The video is a spam
         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
         video:
           type: object
           properties:
@@ -3079,8 +4077,24 @@ components:
               type: string
             uuid:
               type: string
+              format: uuid
+              example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
         createdAt:
           type: string
+          format: date-time
+    AbuseMessage:
+      properties:
+        id:
+          type: integer
+        message:
+          type: string
+        byModerator:
+          type: boolean
+        createdAt:
+          type: string
+          format: date-time
+        account:
+          $ref: '#/components/schemas/AccountSummary'
     VideoBlacklist:
       properties:
         id:
@@ -3089,12 +4103,16 @@ components:
           type: integer
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         name:
           type: string
         uuid:
           type: string
+          format: uuid
+          example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
         description:
           type: string
         duration:
@@ -3122,18 +4140,24 @@ components:
               type: integer
             uuid:
               type: string
+              format: uuid
+              example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
     VideoPlaylist:
       properties:
         id:
           type: integer
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         description:
           type: string
         uuid:
           type: string
+          format: uuid
+          example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
         displayName:
           type: string
         isLocal:
@@ -3156,6 +4180,7 @@ components:
           type: integer
         url:
           type: string
+          format: url
         text:
           type: string
         threadId:
@@ -3166,8 +4191,10 @@ components:
           type: integer
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
         totalRepliesFromVideoAuthor:
           type: integer
         totalReplies:
@@ -3194,101 +4221,70 @@ components:
           type: string
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
-    Actor:
+          format: date-time
+    ActorInfo:
       properties:
         id:
           type: integer
-        url:
-          type: string
+          example: 11
         name:
           type: string
-        host:
-          type: string
-        followingCount:
-          type: integer
-        followersCount:
-          type: integer
-        createdAt:
+        displayName:
           type: string
-        updatedAt:
+        host:
           type: string
+          format: hostname
         avatar:
-          $ref: '#/components/schemas/Avatar'
-    Account:
-      allOf:
-        - $ref: '#/components/schemas/Actor'
-        - properties:
-            userId:
-              type: string
-            displayName:
-              type: string
-            description:
+          nullable: true
+          type: object
+          properties:
+            path:
               type: string
-    User:
+    Actor:
       properties:
         id:
           type: integer
-        username:
-          type: string
-        email:
-          type: string
-        theme:
-          type: string
-          description: 'Theme enabled by this user'
-        emailVerified:
-          type: boolean
-          description: 'Has the user confirmed their email address?'
-        nsfwPolicy:
-          $ref: '#/components/schemas/NSFWPolicy'
-        webtorrentEnabled:
-          type: boolean
-        autoPlayVideo:
-          type: boolean
-          description: 'Automatically start playing the video on the watch page'
-        role:
-          $ref: '#/components/schemas/UserRole'
-        roleLabel:
+          example: 11
+        url:
           type: string
-          enum:
-            - User
-            - Moderator
-            - Administrator
-        videoQuota:
-          type: integer
-        videoQuotaDaily:
-          type: integer
-        videosCount:
-          type: integer
-        videoAbusesCount:
-          type: integer
-        videoAbusesAcceptedCount:
-          type: integer
-        videoAbusesCreatedCount:
-          type: integer
-        videoCommentsCount:
-          type: integer
-        noInstanceConfigWarningModal:
-          type: boolean
-        noWelcomeModal:
-          type: boolean
-        blocked:
-          type: boolean
-        blockedReason:
+          format: url
+        name:
+          type: string
+        host:
           type: string
+          format: hostname
+        followingCount:
+          type: integer
+        followersCount:
+          type: integer
         createdAt:
           type: string
-        account:
-          $ref: '#/components/schemas/Account'
-        videoChannels:
-          type: array
-          items:
-            $ref: '#/components/schemas/VideoChannel'
+          format: date-time
+        updatedAt:
+          type: string
+          format: date-time
+        avatar:
+          $ref: '#/components/schemas/Avatar'
+    Account:
+      allOf:
+        - $ref: '#/components/schemas/Actor'
+        - properties:
+            userId:
+              type: string
+              example: 2
+            displayName:
+              type: string
+            description:
+              type: string
     UserWatchingVideo:
       properties:
         currentTime:
           type: integer
+          description: timestamp within the video, in seconds
+          example: 5
     ServerConfig:
       properties:
         instance:
@@ -3485,6 +4481,7 @@ components:
                   properties:
                     indexUrl:
                       type: string
+                      format: url
     ServerConfigAbout:
       properties:
         instance:
@@ -3566,6 +4563,7 @@ components:
           properties:
             email:
               type: string
+              format: email
         contactForm:
           type: object
           properties:
@@ -3656,6 +4654,7 @@ components:
           $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:
@@ -3663,38 +4662,83 @@ components:
             - accepted
         createdAt:
           type: string
+          format: date-time
         updatedAt:
           type: string
+          format: date-time
+
+    PredefinedAbuseReasons:
+      description: Reason categories that help triage reports
+      type: array
+      items:
+        type: string
+        enum:
+        - violentOrAbusive
+        - hatefulOrAbusive
+        - spamOrMisleading
+        - privacy
+        - rights
+        - serverRules
+        - thumbnails
+        - captions
+
     Job:
       properties:
         id:
           type: integer
+          minimum: 0
+          example: 42
         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: integer
-        uuid:
-          type: string
+        user:
+          type: object
+          properties:
+            id:
+              type: integer
+              example: 8
+            account:
+              type: object
+              properties:
+                id:
+                  type: integer
+                  example: 37
     VideoUploadResponse:
       properties:
         video:
@@ -3702,14 +4746,19 @@ components:
           properties:
             id:
               type: integer
+              example: 8
             uuid:
               type: string
+              format: uuid
+              example: 9c9de5e8-0a1e-484a-b099-e80766180a6d
     CommentThreadResponse:
       properties:
         total:
           type: integer
+          example: 1
         data:
           type: array
+          maxItems: 100
           items:
             $ref: '#/components/schemas/VideoComment'
     CommentThreadPostResponse:
@@ -3720,31 +4769,103 @@ components:
       properties:
         total:
           type: integer
+          example: 1
         data:
           type: array
+          maxItems: 100
           items:
             $ref: '#/components/schemas/Video'
+    User:
+      properties:
+        id:
+          type: integer
+          readOnly: true
+        username:
+          type: string
+          description: The user username
+          minLength: 1
+          maxLength: 50
+        email:
+          type: string
+          format: email
+          description: The user email
+        theme:
+          type: string
+          description: Theme enabled by this user
+        emailVerified:
+          type: boolean
+          description: Has the user confirmed their email address?
+        nsfwPolicy:
+          $ref: '#/components/schemas/NSFWPolicy'
+        webtorrentEnabled:
+          type: boolean
+          description: Enable P2P in the player
+        autoPlayVideo:
+          type: boolean
+          description: Automatically start playing the video on the watch page
+        role:
+          $ref: '#/components/schemas/UserRole'
+        roleLabel:
+          type: string
+          enum:
+            - User
+            - Moderator
+            - Administrator
+        videoQuota:
+          type: integer
+          description: The user video quota
+        videoQuotaDaily:
+          type: integer
+          description: The user daily video quota
+        videosCount:
+          type: integer
+        abusesCount:
+          type: integer
+        abusesAcceptedCount:
+          type: integer
+        abusesCreatedCount:
+          type: integer
+        videoCommentsCount:
+          type: integer
+        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'
     AddUser:
       properties:
         username:
           type: string
-          description: 'The user username'
+          description: The user username
           minLength: 1
           maxLength: 50
         password:
           type: string
-          description: 'The user password. If the smtp server is configured, you can leave empty and an email will be sent'
+          format: password
+          description: The user password. If the smtp server is configured, you can leave empty and an email will be sent
           minLength: 6
           maxLength: 255
         email:
           type: string
-          description: 'The user email. MUST be in the format of an email address.'
+          format: email
+          description: The user email
         videoQuota:
-          type: string
-          description: 'The user video quota'
+          type: integer
+          description: The user video quota
         videoQuotaDaily:
-          type: string
-          description: 'The user daily video quota'
+          type: integer
+          description: The user daily video quota
         role:
           $ref: '#/components/schemas/UserRole'
       required:
@@ -3758,16 +4879,17 @@ components:
       properties:
         id:
           type: string
-          description: 'The user id'
+          description: The user id
         email:
           type: string
-          description: 'The updated email of the user'
+          format: email
+          description: The updated email of the user
         videoQuota:
-          type: string
-          description: 'The updated video quota of the user'
+          type: integer
+          description: The updated video quota of the user
         videoQuotaDaily:
-          type: string
-          description: 'The updated daily video quota of the user'
+          type: integer
+          description: The updated daily video quota of the user
         role:
           $ref: '#/components/schemas/UserRole'
       required:
@@ -3780,16 +4902,24 @@ components:
       properties:
         password:
           type: string
-          description: 'Your new password'
+          format: password
+          description: Your new password
+          minLength: 6
+          maxLength: 255
         email:
           type: string
-          description: 'Your new email'
+          format: email
+          description: Your new email
         displayNSFW:
           type: string
-          description: 'Your new displayNSFW'
+          description: Your new displayNSFW
+          enum:
+            - 'true'
+            - 'false'
+            - both
         autoPlayVideo:
-          type: string
-          description: 'Your new autoPlayVideo'
+          type: boolean
+          description: Your new autoPlayVideo
       required:
         - password
         - email
@@ -3799,10 +4929,10 @@ components:
       properties:
         id:
           type: string
-          description: 'Id of the video'
+          description: Id of the video
         rating:
           type: number
-          description: 'Rating of the video'
+          description: Rating of the video
       required:
         - id
         - rating
@@ -3820,26 +4950,37 @@ components:
       properties:
         username:
           type: string
-          description: 'The username of the user'
+          description: The username of the user
+          minLength: 1
+          maxLength: 50
+          pattern: '/^[a-z0-9._]{1,50}$/'
         password:
           type: string
-          description: 'The password of the user'
+          format: password
+          description: The password of the user
+          minLength: 6
+          maxLength: 255
         email:
           type: string
-          description: 'The email of the user'
+          format: email
+          description: The email of the user
         displayName:
           type: string
-          description: 'The user display name'
+          description: The user display name
+          minLength: 1
+          maxLength: 120
         channel:
           type: object
           properties:
             name:
               type: string
-              description: 'The name for the default channel'
+              description: The name for the default channel
+              pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/'
             displayName:
               type: string
-              description: 'The display name for the default channel'
-
+              description: The display name for the default channel
+              minLength: 1
+              maxLength: 120
       required:
         - username
         - password
@@ -3855,6 +4996,7 @@ components:
         support:
           type: string
           description: 'A text shown by default on all videos of this channel, to tell the audience how to support it'
+          example: Please support my work on <insert crowdfunding plateform>! <3
       required:
         - name
         - displayName
@@ -3867,6 +5009,7 @@ components:
         support:
           type: string
           description: 'A text shown by default on all videos of this channel, to tell the audience how to support it'
+          example: Please support my work on <insert crowdfunding plateform>! <3
         bulkVideosSupportUpdate:
           type: boolean
           description: 'Update the support field for all videos of this channel'
@@ -3893,6 +5036,7 @@ components:
       properties:
         url:
           type: string
+          format: url
           xml:
             attribute: true
         fileSize:
@@ -3931,6 +5075,7 @@ components:
         properties:
           link:
             type: string
+            format: url
           guid:
             type: string
           pubDate:
@@ -3952,6 +5097,7 @@ components:
         properties:
           link:
             type: string
+            format: url
             description: video watch page URL
           guid:
             type: string
@@ -3988,6 +5134,7 @@ components:
             properties:
               url:
                 type: string
+                format: url
                 description: video embed path, relative to the canonical URL domain (MRSS)
                 xml:
                   attribute: true
@@ -3996,6 +5143,7 @@ components:
             properties:
               url:
                 type: string
+                format: url
                 description: video watch path, relative to the canonical URL domain (MRSS)
                 xml:
                   attribute: true
@@ -4004,6 +5152,7 @@ components:
             properties:
               url:
                 type: string
+                format: url
                 xml:
                   attribute: true
               height:
@@ -4031,6 +5180,7 @@ components:
             properties:
               url:
                 type: string
+                format: url
                 xml:
                   attribute: true
               type:
@@ -4049,4 +5199,227 @@ components:
             items:
               anyOf:
                 - $ref: '#/components/schemas/MRSSPeerLink'
-                - $ref: '#/components/schemas/MRSSGroupContent'
\ No newline at end of file
+                - $ref: '#/components/schemas/MRSSGroupContent'
+    NotificationSettingValue:
+      type: integer
+      description: >
+        Notification type
+
+        - `0` NONE
+
+        - `1` WEB
+
+        - `2` EMAIL
+      enum:
+        - 0
+        - 1
+        - 3
+    Notification:
+      properties:
+        id:
+          type: integer
+        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:
+              type: integer
+            video:
+              nullable: true
+              $ref: '#/components/schemas/VideoInfo'
+            torrentName:
+              type: string
+              nullable: true
+            magnetUri:
+              type: string
+              format: uri
+              nullable: true
+            targetUri:
+              type: string
+              format: uri
+              nullable: true
+        comment:
+          nullable: true
+          type: object
+          properties:
+            id:
+              type: integer
+            threadId:
+              type: integer
+            video:
+              $ref: '#/components/schemas/VideoInfo'
+            account:
+              $ref: '#/components/schemas/ActorInfo'
+        videoAbuse:
+          nullable: true
+          type: object
+          properties:
+            id:
+              type: integer
+            video:
+              allOf:
+                - $ref: '#/components/schemas/VideoInfo'
+        videoBlacklist:
+          nullable: true
+          type: object
+          properties:
+            id:
+              type: integer
+            video:
+              allOf:
+                - $ref: '#/components/schemas/VideoInfo'
+        account:
+          nullable: true
+          allOf:
+            - $ref: '#/components/schemas/ActorInfo'
+        actorFollow:
+          type: object
+          nullable: true
+          properties:
+            id:
+              type: integer
+            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
+        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'
+  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'