# Undocumented endpoints:
#  /api/v1/settings
#  /api/v1/activity
#  /api/v1/playlist-tracks
#  /api/v1/search
#  /api/v1/radios
#  /api/v1/history

openapi: "3.0.2"
info:
  description: |
    Interactive documentation for [Funkwhale](https://funkwhale.audio) API.

    The API is **not** freezed yet, but we will document breaking changes in our changelog,
    and try to avoid those as much as possible.

    Usage
    -----

    Click on an endpoint name to inspect its properties, parameters and responses.

    Use the "Try it out" button to send a real world payload to the endpoint and inspect
    the corresponding response.

    Authentication
    --------------

    To authenticate, use OAuth. You can register your own app using the `/api/v1/oauth/apps/` endpoint. Proceed to the standard OAuth flow afterwards:

    - Our authorize URL is at `/authorize`
    - Our token acquisition and refresh URL is at `/api/v1/oauth/token`
    - The list of supported scopes is available by clicking the `Authorize` button in the Swagger UI documentation
    - Use `urn:ietf:wg:oauth:2.0:oob` as your redirect URI if you want the user to get a copy-pastable authorization code
    - At the moment, endpoints that deal with admin or moderator-level content are not accessible via OAuth, only through the Web UI

    You can use our demo server at `https://demo.funkwhale.audio` for testing purposes.

    Rate limiting
    -------------

    Depending on server configuration, pods running Funkwhale 0.20 and higher may rate-limit incoming
    requests to prevent abuse and improve the stability of service. Requests that are dropped because of rate-limiting
    receive a 429 HTTP response.

    The limits themselves vary depending on:

    - The client: anonymous requests are subject to lower limits than authenticated requests
    - The operation being performed: Write and delete operations, as performed with DELETE, POST, PUT and PATCH HTTP methods are subject to lower limits

    Those conditions are used to determine the scope of the request, which in turns determine the limit that is applied.
    For instance, authenticated POST requests are bound to the `authenticated-create` scope, with a default limit of
    1000 requests/hour, but anonymous POST requests are bound to the `anonymous-create` scope, with a lower limit of 1000 requests/day.

    A full list of scopes with their corresponding description, and the current usage data for the client performing the request
    is available via the `/api/v1/rate-limit` endpoint.

    Additionally, we include HTTP headers on all API response to ensure API clients can understand:

    - what scope was bound to a given request
    - what is the corresponding limit
    - how much similar requests can be sent before being limited
    - and how much time they should wait if they have been limited

    <table>
      <caption>Rate limiting headers</caption>
      <thead>
        <th>Header</th>
        <th>Example value</th>
        <th>Description value</th>
      </thead>
      <tbody>
        <tr>
          <td><code>X-RateLimit-Limit</code></td>
          <td>50</td>
          <td>The number of allowed requests whithin a given period</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Duration</code></td>
          <td>3600</td>
          <td>The time window, in seconds, during which those requests are accounted for.</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Scope</code></td>
          <td>login</td>
          <td>The name of the scope as computed for the request</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Remaining</code></td>
          <td>42</td>
          <td>How many requests can be sent with the same scope before the limit applies</td>
        </tr>
        <tr>
          <td><code>Retry-After</code> (if <code>X-RateLimit-Remaining</code> is 0)</td>
          <td>3543</td>
          <td>How many seconds to wait before a retry</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-Reset</code></td>
          <td>1568126089</td>
          <td>A timestamp indicating when <code>X-RateLimit-Remaining</code> will return to its higher possible value</td>
        </tr>
        <tr>
          <td><code>X-RateLimit-ResetSeconds</code></td>
          <td>3599</td>
          <td>How many seconds to wait before <code>X-RateLimit-Remaining</code> returns to its higher possible value</td>
        </tr>
      </tbody>
    </table>


    Resources
    ---------

    For more targeted guides regarding API usage, and especially authentication, please
    refer to [https://docs.funkwhale.audio/api.html](https://docs.funkwhale.audio/api.html)

  version: "1.0.0"
  title: "Funkwhale API"

servers:
  - url: https://demo.funkwhale.audio
    description: Demo server
  - url: https://open.audio
    description: Real server with real content
  - url: https://{domain}
    description: Custom server
    variables:
      domain:
        default: yourdomain
        description: Your Funkwhale Domain
      protocol:
        enum:
          - 'http'
          - 'https'
        default: 'https'

components:
  securitySchemes:
    oauth2:
      type: oauth2
      description: This API uses OAuth 2 with the Authorization Code flow. You can register an app using the /oauth/apps/ endpoint.
      flows:
        authorizationCode:
          # Swagger doesn't support relative URLs yet (cf https://github.com/swagger-api/swagger-ui/pull/5244)
          authorizationUrl: /authorize
          tokenUrl: /api/v1/oauth/token/
          refreshUrl: /api/v1/oauth/token/
          scopes:
            "read": "Read-only access to all user data"
            "write": "Write-only access on all user data"
            "read:edits": "Read-only access to edits"
            "write:edits": "Write-only access to edits"
            "read:favorites": "Read-only access to favorites"
            "write:favorites": "Write-only access to favorits"
            "read:filters": "Read-only to to content filters"
            "write:filters": "Write-only access to content-filters"
            "read:follows": "Read-only to follows"
            "write:follows": "Write-only access to follows"
            "read:libraries": "Read-only access to library and uploads"
            "write:libraries": "Write-only access to libraries"
            "read:listenings": "Read-only access to listening history"
            "write:listenings": "Write-only access to listening history"
            "read:notifications": "Read-only access to notifications"
            "write:notifications": "Write-only access to notifications"
            "read:playlists": "Read-only access to playlists"
            "write:playlists": "Write-only access to playlists"
            "read:profile": "Read-only access to profile data"
            "write:profile": "Write-only access to profile data"
            "read:radios": "Read-only access to radios"
            "write:radios": "Write-only access to radios"
            "read:reports": "Read-only access to reports"
            "write:reports": "Write-only access to reports"
            "read:security": "Read-only access security settings"
            "write:security": "write-only access security settings"
    jwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "You can get a token by using the /token endpoint"

security:
  - jwt: []
  - oauth2: []

tags:
  - name: Auth and security
    description: Login, logout, rate-limit and authorization endpoints
  - name: Library and metadata
    description: Information and metadata about musical and audio entities (albums, tracks, artists, etc.)
  - name: Uploads and audio content
    description: Manipulation and uploading of audio files
    externalDocs:
      url: https://docs.funkwhale.audio/users/managing.html
  - name: Channels and subscriptions
    description: Channel management and subscription
    externalDocs:
      url: https://docs.funkwhale.audio/users/upload.html#using-a-channel
  - name: Content curation
    description: Favorites, playlists, radios
  - name: Other
    description: Other endpoints that don't fit in the categories above

paths:
  /api/v1/oauth/apps/:
    post:
      tags:
        - "Auth and security"
      summary:
        Register an OAuth application
      security: []
      responses:
        201:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/OAuthApplication"
                  - $ref: "./api/definitions.yml#/OAuthApplicationCreation"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                name:
                  type: "string"
                  example: "My Awesome Funkwhale Client"
                  summary: "A human readable name for your app"
                redirect_uris:
                  type: "string"
                  example: "https://myapp/oauth2/funkwhale"
                  summary: "A list of redirect uris, separated by spaces"
                scopes:
                  type: "string"
                  summary: "A list of scopes requested by your app, separated by spaces"
                  example: "read write:playlists write:favorites"
  /api/v1/oauth/token/:
    post:
      tags:
        - "Auth and security"
      summary:
        Request an OAuth bearer token in exchange of an authorization_code or a refresh_token
      security: []
      responses:
        200:

  /api/v1/auth/registration/:
    post:
      summary: Create an account
      description: |
        Register a new account on this instance. An invitation code will be required
        if sign up is disabled.
      tags:
        - "Auth and security"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                username:
                  type: "string"
                  example: "alice"
                email:
                  type: "string"
                  format: "email"
                invitation:
                  type: "string"
                  example: "INVITECODE"
                  required: false
                  description: An invitation code, required if signups are closed on the instance.
                password1:
                  type: "string"
                  example: "passw0rd"
                password2:
                  type: "string"
                  description: Must be identical to password1
                  example: "passw0rd"
      responses:
        201:
          $ref: "#/responses/201"
  /api/v1/auth/password/reset/:
    post:
      summary: Request a password reset
      description: |
        Request a password reset. An email with reset instructions will be sent to the provided email,
        if it's associated with a user account.
      tags:
        - "Auth and security"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                email:
                  type: "string"
                  format: "email"
      responses:
        200:
          $ref: "#/responses/200"
  /api/v1/users/users/me/:
    get:
      summary: Retrive profile information
      description: |
        Retrieve profile informations of the current user
      tags:
        - "Auth and security"

      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Me"

  /api/v1/rate-limit/:
    get:
      summary: Retrive rate-limit information and current usage status
      tags:
        - "Auth and security"

      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/RateLimitStatus"

  /api/v1/artists/:
    get:
      summary: List artists
      tags:
        - "Library and metadata"
      security:
        - oauth2:
          - "read:libraries"
      parameters:

        - $ref: "./api/parameters.yml#/Search"
        - allOf:
            - $ref: "./api/parameters.yml#/Ordering"
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - id
                  - name
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Artist"
  /api/v1/artists/{id}/:
    get:
      summary: Retrieve a single artist
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"
      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Artist"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"
  /api/v1/artists/{id}/libraries/:
    get:
      summary: List available user libraries containing work from this artist
      security:
        - oauth2:
          - "read:libraries"
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"

      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/LibraryPage"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/albums/:
    get:
      summary: List albums
      tags:
        - "Library and metadata"

      security:
        - oauth2:
          - "read:libraries"
      parameters:

        - $ref: "./api/parameters.yml#/Search"
        - name: "artist"
          in: "query"
          default: null
          description: "Only include albums by the requested artist"
          schema:
            required: false
            type: "integer"
            format: "int64"
        - allOf:
            - $ref: "./api/parameters.yml#/Ordering"
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - release_date
                  - title
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Album"
  /api/v1/albums/{id}/:
    get:
      summary: Retrieve a single album
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"

      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Album"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/albums/{id}/libraries/:
    get:
      summary: List available user libraries containing tracks from this album
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"

      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/LibraryPage"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/tracks/:
    get:
      summary: List tracks
      tags:
        - "Library and metadata"

      security:
        - oauth2:
          - "read:libraries"
      parameters:

        - $ref: "./api/parameters.yml#/Search"
        - name: "artist"
          in: "query"
          default: null
          description: "Only include tracks by the requested artist"
          schema:
            required: false
            type: "integer"
            format: "int64"
        - name: "favorites"
          in: "query"
          default: null
          description: "filter/exclude tracks favorited by the current user"
          schema:
            required: false
            type: "boolean"
        - name: "album"
          in: "query"
          default: null
          description: "Only include tracks from the requested album"
          schema:
            required: false
            type: "integer"
            format: "int64"
        - name: "license"
          in: "query"
          description: "Only include tracks with the given license"
          default: null
          schema:
            example: "cc-by-sa-4.0"
            required: false
            type: "string"
        - allOf:
            - $ref: "./api/parameters.yml#/Ordering"
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - release_date
                  - title
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Track"
  /api/v1/tracks/{id}/:
    get:
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/Refresh"
      summary: Retrieve a single track

      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Track"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/tracks/{id}/libraries/:
    get:
      summary: List available user libraries containing given track
      parameters:
        - $ref: "./api/parameters.yml#/ObjectId"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/LibraryPage"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"
  /api/v1/listen/{uuid}/:
    get:
      summary: Download the audio file matching the given track uuid
      description: |
        Given a track uuid (and not ID), return the first found audio file
        accessible by the user making the request.

        In case of a remote upload, this endpoint will fetch the audio file from the remote
        and cache it before sending the response.

      parameters:
        - name: uuid
          in: path
          required: true
          description: Track uuid
          schema:
            type: "string"
            format: "uuid"
        - name: to
          in: query
          required: false
          description: |
            If specified, the endpoint will return a transcoded version of the original
            audio file.

            Since transcoding happens on the fly, it can significantly increase response time,
            and it's recommended to request transcoding only for files that are not playable
            by the client.

            This endpoint support bytess-range requests.
          schema:
            $ref: "./api/properties.yml#/transcode_options"
        - name: upload
          in: query
          required: false
          summary: An upload uuid
          description: |
            If specified, will return the audio for the given upload uuid.

            This is useful for tracks that have multiple uploads available.

          schema:
            type: string
            format: uuid
        - name: token
          in: query
          required: false
          description: |
            A listen token as returned by /users/me

            This offers an alternative authentication method for situations where HTTP headers
            can't be modified to include a Bearer token.
          schema:
            type: string

      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            '*/*':
              description: "Audio file, as binary data"
              schema:
                type: string
                format: binary
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/licenses/:
    get:
      summary: List licenses
      security:
        - oauth2:
          - "read:libraries"
      tags:
        - "Library and metadata"
      parameters:
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/License"

  /api/v1/licenses/{code}/:
    get:
      summary: Retrieve a single license
      security:
        - oauth2:
          - "read:libraries"
      parameters:
        - name: code
          in: path
          description: License code
          required: true
          schema:
            type: string
            example: cc0-1.0

      tags:
        - "Library and metadata"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/License"
        404:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/ResourceNotFound"

  /api/v1/libraries/:
    get:
      summary: List owned libraries
      tags:
        - "Uploads and audio content"
      parameters:
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/Scope"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/OwnedLibrary"
    post:
      tags:
        - "Uploads and audio content"
      description:
        Create a new library
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/OwnedLibraryCreate"

  /api/v1/libraries/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve a library
      tags:
        - "Uploads and audio content"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/OwnedLibrary"
    post:
      summary: Update a library
      tags:
        - "Uploads and audio content"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/OwnedLibraryCreate"
      responses:
        201:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/OwnedLibrary"
    delete:
      summary: Delete a library and all associated uploads
      description: |
        This will delete the library, all associated uploads, follows, and broadcast
        the event on the federation.
      tags:
        - "Uploads and audio content"
      responses:
        204:
          $ref: "#/responses/204"

  /api/v1/channels/:
    get:
      summary: List channels
      tags:
        - "Channels and subscriptions"
      parameters:
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/Tags"
        - $ref: "./api/parameters.yml#/Subscribed"
        - $ref: "./api/parameters.yml#/External"
        - $ref: "./api/parameters.yml#/ChannelOrdering"

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Channel"
    post:
      summary: Create a new channel
      tags:
        - "Channels and subscriptions"
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/ChannelCreate"

  /api/v1/channels/metadata-choices:
    summary: List metadata (locales, itunes categories) for creating and editing channels.
    tags:
      - "Channels and subscriptions"
    get:
      summary: List channels metadata options
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  language:
                    type: "array"
                    items:
                      type: object
                      properties:
                        value:
                          type: string
                          description: ID of the locale in ISO 639 format
                          example: "en"
                        language:
                          type: string
                          example: "English"
                  itunes_category:
                    type: "array"
                    items:
                      type: object
                      properties:
                        value:
                          type: string
                          description: ID of the category
                          example: "Business"
                        label:
                          type: string
                          description: Readable label of the category
                          example: "Business"
                        children:
                          type: array
                          description: Some categories have subcategories
                          items:
                            type: string
                            example: "Entrepreneurship"

  /api/v1/channels/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve a channel
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Channel"
    post:
      summary: Update a channel
      tags:
        - "Channels and subscriptions"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/ChannelUpdate"
      responses:
        201:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Channel"
    delete:
      summary: Delete a channel and all associated uploads
      description: |
        This will delete the channel, all associated uploads, follows, and broadcast
        the event on the federation.
      tags:
        - "Channels and subscriptions"
      responses:
        204:
          $ref: "#/responses/204"

  /api/v1/channels/rss-suscribe/:
    post:
      summary: Subscribe to a third-party podcast via its RSS feed

      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                url:
                  type: "string"
                  description: URL of the RSS feed

      tags:
        - "Channels and subscriptions"
      responses:
        201:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Subscription"

  /api/v1/channels/{uuid}/rss/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Get the RSS feed of a podcast channel. Only available for channel hosted on the pod where the API is queried.
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/rss+xml:

  /api/v1/channels/{uuid}/subscribe/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    post:
      summary: Subscribe to the given channel
      tags:
        - "Channels and subscriptions"
      responses:
        201:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Subscription"

  /api/v1/channels/{uuid}/unsubscribe/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    post:
      summary: Unsubscribe from the given channel
      tags:
        - "Channels and subscriptions"
      responses:
        204:

  /api/v1/uploads/:
    get:
      summary: List owned uploads
      tags:
        - "Uploads and audio content"
      parameters:

        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/OwnedUpload"
    post:
      tags:
        - "Uploads and audio content"
      description:
        Upload a new file in a library. The event will be broadcasted on federation,
        according to the library visibility and followers.
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                library:
                  type: string
                  format: uuid
                  description: "The library in which the audio should be stored"
                import_reference:
                  type: string
                  example: "Import launched via API client on 04/19"
                source:
                  type: string
                  example: "upload://filename.mp3"
                audio_file:
                  type: string
                  format: binary
                import_status:
                  type: string
                  description: "Setting import_status to draft will prevent processing, but allow further modifications to audio and metadata. Once ready, use the PATCH method to set import_status to pending. Default to `pending` if unspecified."
                  default: "pending"
                  enum:
                  - "draft"
                  - "pending"
                import_metadata:
                  required: false
                  $ref: "./api/definitions.yml#/ImportMetadata"


  /api/v1/subscriptions/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve a subscription
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Subscription"

  /api/v1/subscriptions/:
    get:
      summary: List subscriptions
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Subscription"

  /api/v1/subscriptions/all/:
    get:
      summary: Retrieve all subscriptions in a lightweight format, without pagination
      tags:
        - "Channels and subscriptions"
      responses:
        200:
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  results:
                    type: "array"
                    items:
                      $ref: "./api/definitions.yml#/SubscriptionsAll"

  /api/v1/uploads/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve an upload
      tags:
        - "Uploads and audio content"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/OwnedUpload"
    patch:
      summary: Update a draft upload
      description: |
        This will update a draft upload, before it is processed.

        All fields supported for `POST /api/v1/uploads` can be updated here.

        Setting `import_status` to `pending` will trigger processing, and make future
        modifications impossible.

      tags:
        - "Uploads and audio content"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/OwnedUpload"
    delete:
      summary: Delete an upload
      description: |
        This will delete the upload from the server and broadcast the event
        on the federation.
      tags:
        - "Uploads and audio content"
      responses:
        204:
          $ref: "#/responses/204"

  /api/v1/uploads/{uuid}/audio-file-metadata:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve the tags embedded in the audio file
      tags:
        - "Uploads and audio content"
      responses:
        200:
          content:
            application/json:
              schema:
                type: "object"
                properties: []

  /api/v1/favorites/tracks/:
    get:
      tags:
        - "Content curation"
      parameters:
        - $ref: "./api/parameters.yml#/Search"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
        - $ref: "./api/parameters.yml#/Scope"

      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/TrackFavorite"
    post:
      summary: Mark the given track as favorite
      tags:
        - "Content curation"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                track:
                  type: "integer"
                  format: "int64"
                  example: 98
      responses:
        201:
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  id:
                    type: "integer"
                    format: "int64"
                    example: 876
                  track:
                    type: "integer"
                    format: "int64"
                    example: 98
                  creation_date:
                    $ref: "./api/properties.yml#/creation_date"
  /api/v1/favorites/tracks/remove/:
    post:
      summary: Remove the given track from favorites
      tags:
        - "Content curation"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                track:
                  type: "integer"
                  format: "int64"
                  example: 98
      responses:
        204:
          $ref: "#/responses/204"

  /api/v1/attachments/:
    post:
      tags:
        - "Other"
      description:
        Upload a new file as an attachment that can be later associated with other objects.
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary

  /api/v1/attachments/{uuid}/:
    parameters:
      - name: uuid
        in: path
        required: true
        schema:
          type: "string"
          format: "uuid"
    get:
      summary: Retrieve an attachment
      tags:
        - "Other"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Attachment"
    delete:
      summary: Delete an attachment
      tags:
        - "Other"
      responses:
        204:
          $ref: "#/responses/204"
  /api/v1/playlists/:
    get:
      summary: List playlists
      tags:
        - "Content curation"
      parameters:
        - $ref: "./api/parameters.yml#/Search"
        - allOf:
            - $ref: "./api/parameters.yml#/Ordering"
            - default: "-creation_date"
              schema:
                required: false
                type: "string"
                example: "creation_date"
                enum:
                  - creation_date
                  - modification_date
                  - id
                  - name
        - in: query
          name: artist
          description: Restrict to playlists containing tracks from the given artist
          schema:
            type: "integer"
            format: "int64"
        - in: query
          name: album
          description: Restrict to playlists containing tracks from the given album
          schema:
            type: "integer"
            format: "int64"
        - in: query
          name: track
          description: Restrict to playlists containing the given track
          schema:
            type: "integer"
            format: "int64"
        - $ref: "./api/parameters.yml#/Playable"
        - $ref: "./api/parameters.yml#/PageNumber"
        - $ref: "./api/parameters.yml#/PageSize"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/Playlist"
    post:
      tags:
        - "Content curation"
      description: Create a new playlist
      responses:
        201:
          $ref: "#/responses/201"
        400:
          $ref: "#/responses/400"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/PlaylistCreate"
  /api/v1/playlists/{id}/:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: "integer"
          format: "int64"
    get:
      summary: Retrieve a playlist
      tags:
        - "Content curation"
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Playlist"
    post:
      summary: Update a playlist
      tags:
        - "Content curation"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "./api/definitions.yml#/PlaylistCreate"
      responses:
        201:
          content:
            application/json:
              schema:
                $ref: "./api/definitions.yml#/Playlist"
    delete:
      description: Delete the playlist
      tags:
        - "Content curation"
      responses:
        204:
          $ref: "#/responses/204"
  /api/v1/playlists/{id}/tracks:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: "integer"
          format: "int64"
    get:
      description: Retrieve all tracks in the playlist
      tags:
        - "Content curation"
      responses:
        200:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/PlaylistTrack"
  /api/v1/playlists/{id}/add:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: "integer"
          format: "int64"
    post:
      tags:
        - "Content curation"
      summary: Append one or more tracks to a playlist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tracks:
                  type: array
                  description: An array of track IDs
                  items:
                    type: "integer"
                    format: "int64"
                    example: 13
                allow_duplicates:
                  type: boolean
                  default: false
                  description: |
                    Wether to raise an error when the same track is added
                    multiple time in the playlist
      responses:
        201:
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "./api/definitions.yml#/ResultPage"
                  - type: "object"
                    properties:
                      results:
                        type: "array"
                        items:
                          $ref: "./api/definitions.yml#/PlaylistTrack"
  /api/v1/playlists/{id}/clear:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: "integer"
          format: "int64"
    delete:
      description: Remove all tracks in the playlist
      tags:
        - "Content curation"
      responses:
        204:
responses:
  200:
    description: Success
  201:
    description: Successfully created
  204:
    description: Successfully deleted
  400:
    description: Bad request
