diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e26f05cdc..8ce89be48 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -250,9 +250,9 @@ test_api:
# - if: $CI_COMMIT_REF_PROTECTED == "true"
# when: always
-build_docs:
+build_openapi_schema:
stage: build
- image: $CI_REGISTRY/funkwhale/backend-test-docker:3.10
+ image: $CI_REGISTRY/funkwhale/backend-test-docker:3.11
services:
- postgres:15-alpine
- redis:7-alpine
@@ -281,6 +281,44 @@ build_docs:
paths:
- docs/schema.yml
+build_documentation:
+ stage: build
+ image: python:3.11
+ needs:
+ - build_openapi_schema
+ dependencies:
+ - build_openapi_schema
+ variables:
+ BUILD_PATH: "../public"
+ GIT_STRATEGY: clone
+ GIT_DEPTH: 0
+ before_script:
+ - cd docs
+ - apt-get update
+ - apt-get install -y graphviz
+ - pip install poetry
+ - poetry install
+ - git branch stable --track origin/stable || true
+ - git branch develop --track origin/develop || true
+ script:
+ - ./build_docs.sh
+ cache:
+ key: "$CI_PROJECT_ID__sphinx"
+ paths:
+ - "$PIP_CACHE_DIR"
+ artifacts:
+ expire_in: 2 weeks
+ paths:
+ - public
+ rules:
+ - if: $CI_COMMIT_BRANCH == "stable" || $CI_COMMIT_BRANCH == "develop"
+ when: always
+ - changes:
+ - docs/**/*
+ when: always
+ tags:
+ - docker
+
build_front:
stage: build
image: node:18-alpine
@@ -308,39 +346,28 @@ build_front:
tags:
- docker
-build_documentation:
+build_api:
stage: build
- image: python:3.11
+ image: bash
variables:
- BUILD_PATH: "../public"
- before_script:
- - cd docs
- - apt-get update
- - apt-get install -y graphviz git
- - pip install poetry
- - poetry install
- - git switch develop && git pull
- - git switch stable && git pull
- - git switch $CI_COMMIT_BRANCH && git pull
+ # Keep the git files attributes during job setup
+ GIT_STRATEGY: clone
+ GIT_DEPTH: "5"
+ FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: "true"
script:
- - ./build_docs.sh
- cache:
- key: "$CI_PROJECT_ID__sphinx"
- paths:
- - "$PIP_CACHE_DIR"
+ - rm -rf api/tests
+ - >
+ if [ "$CI_COMMIT_REF_NAME" == "develop" ] || [ "$CI_COMMIT_REF_NAME" == "stable" ]; then
+ ./scripts/set-api-build-metadata.sh $CI_COMMIT_SHORT_SHA;
+ fi
artifacts:
- expire_in: 2 weeks
+ name: api_${CI_COMMIT_REF_NAME}
paths:
- - public
- rules:
- - if: $CI_COMMIT_BRANCH == "stable"
- when: always
- - if: $CI_COMMIT_BRANCH == "develop"
- changes:
- - docs/**/*
- when: always
- tags:
- - docker
+ - api
+ only:
+ - tags@funkwhale/funkwhale
+ - stable@funkwhale/funkwhale
+ - develop@funkwhale/funkwhale
deploy_documentation:
stage: publish
@@ -362,6 +389,9 @@ deploy_documentation:
.docker_publish:
stage: publish
image: egon0/docker-with-buildx-and-git:bash
+ variables:
+ IMAGE_NAME: funkwhale/$COMPONENT
+ FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: "true"
tags:
- multiarch
services:
@@ -372,13 +402,10 @@ deploy_documentation:
key: docker_public_${CI_COMMIT_REF_NAME}
paths:
- ~/.cargo
- script:
docker_publish_stable_release:
# Publish a docker image for releases
extends: .docker_publish
- variables:
- IMAGE_NAME: funkwhale/$COMPONENT
rules:
- if: $CI_COMMIT_TAG && $CI_COMMIT_REF_NAME =~ /^[0-9]+(.[0-9]+){1,2}$/
script:
@@ -425,27 +452,3 @@ docker_publish_non-release:
parallel:
matrix:
- COMPONENT: ["api", "front"]
-
-build_api:
- # Simply publish a zip containing api/ directory
- stage: publish
- image: bash
- variables:
- # Keep the git files attributes during job setup
- GIT_STRATEGY: clone
- GIT_DEPTH: "5"
- FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: "true"
- script:
- - rm -rf api/tests
- - >
- if [ "$CI_COMMIT_REF_NAME" == "develop" ] || [ "$CI_COMMIT_REF_NAME" == "stable" ]; then
- ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8);
- fi
- artifacts:
- name: api_${CI_COMMIT_REF_NAME}
- paths:
- - api
- only:
- - tags@funkwhale/funkwhale
- - stable@funkwhale/funkwhale
- - develop@funkwhale/funkwhale
diff --git a/docs/api/definitions.yml b/docs/api/definitions.yml
deleted file mode 100644
index afd510dd6..000000000
--- a/docs/api/definitions.yml
+++ /dev/null
@@ -1,951 +0,0 @@
-OAuthApplication:
- type: "object"
- properties:
- client_id:
- type: "string"
- example: "VKIZWv7FwBq56UMfUtbCSIgSxzUTv1b6nMyOkJvP"
- created:
- type: "string"
- format: "date-time"
- updated:
- type: "string"
- format: "date-time"
- scopes:
- type: "string"
- description: "Coma-separated list of scopes requested by the app"
-
-OAuthApplicationCreation:
- type: "object"
- properties:
- client_secret:
- type: "string"
- example: "qnKDX8zjIfC0BG4tUreKlqk3tNtuCfJdGsaEt5MIWrTv0YLLhGI6SGqCjs9kn12gyXtIg4FWfZqWMEckJmolCi7a6qew4LawPWMfnLDii4mQlY1eQG4BJbwPANOrDiTZ"
- redirect_uris:
- type: "string"
- format: "uri"
- description: "Coma-separated list of redirect uris allowed for the app"
-
-ResultPage:
- type: "object"
- properties:
- count:
- type: "integer"
- format: "int64"
- example: 42
- description: "The total number of results (all pages included)"
- next:
- type: "string"
- format: "uri"
- description: "Link to the next page of results"
- previous:
- type: "string"
- format: "uri"
- description: "Link to the previous page of results"
-
-Attachment:
- type: "object"
- properties:
- uuid:
- type: string
- format: uuid
- size:
- type: "integer"
- format: "int64"
- example: 2787000
- description: "Size of the file, in bytes"
- mimetype:
- $ref: "./properties.yml#/image_mimetype"
- creation_date:
- type: "string"
- format: "date-time"
- urls:
- type: "object"
- properties:
- original:
- type: "string"
- description: "URL to the original image"
- example: "https://mydomain/media/attachments/ec2c53aeaac6.jpg"
- medium_square_crop:
- type: "string"
- description: "URL to a medium, squared thumbnail of the image"
- example: "https://mydomain/media/__sized__/attachments/ec2c53aeaac6-crop-c0-5__0-5-200x200-70.jpg"
-
-Actor:
- type: object
- description: "A federation/ ActivityPub actor"
- properties:
- fid:
- type: string
- format: uri
- description: "The actor Federation ID (unique across federation)"
- uuid:
- type: string
- format: uuid
- description: "Local ID of the library"
- creation_date:
- type: "string"
- format: "date-time"
- preferred_username:
- type: "string"
- example: "alice"
- name:
- type: string
- example: "Alice Unicorn"
- last_fetch_date:
- type: "string"
- format: "date-time"
- description: "Last time the actor profile was fetched on its origin server"
- domain:
- type: "string"
- format: "hostname"
- example: "open.audio"
- type:
- type: "string"
- example: "Person"
- enum:
- - Person
- - Application
- - Group
- - Organization
- manually_approves_followers:
- type: "boolean"
- full_username:
- type: string
- example: "alice@open.audio"
-
-BaseArtist:
- type: "object"
- required:
- - id
- - fid
- - name
- - creation_date
- - is_local
- properties:
- mbid:
- $ref: "./properties.yml#/mbid"
- id:
- type: "integer"
- format: "int64"
- example: 42
- fid:
- type: string
- format: uri
- description: "The artist Federation ID (unique across federation)"
- name:
- type: "string"
- example: "System of a Down"
- creation_date:
- type: "string"
- format: "date-time"
- is_local:
- type: "boolean"
- description: "Indicates if the object was initially created locally or on another server"
-
-Artist:
- type: "object"
- allOf:
- - $ref: "#/BaseArtist"
- - type: "object"
- properties:
- tracks_count:
- type: "integer"
- format: "int64"
- example: 42
- albums:
- type: "array"
- items:
- $ref: "#/ArtistAlbum"
-
-BaseAlbum:
- type: "object"
- required:
- - id
- - fid
- - artist
- - title
- - creation_date
- - is_playable
- - is_local
- properties:
- mbid:
- $ref: "./properties.yml#/mbid"
- id:
- type: "integer"
- format: "int64"
- example: 16
- fid:
- type: string
- format: uri
- description: "The album Federation ID (unique across federation)"
- artist:
- type: "integer"
- format: "int64"
- example: 42
- title:
- type: "string"
- example: "Toxicity"
- creation_date:
- type: "string"
- format: "date-time"
- release_date:
- type: "string"
- format: "date"
- example: "2001-01-01"
- is_playable:
- type: "boolean"
- cover:
- $ref: "#/Attachment"
- is_local:
- type: "boolean"
- description: "Indicates if the object was initially created locally or on another server"
-
-Album:
- type: "object"
- allOf:
- - $ref: "#/BaseAlbum"
- - type: "object"
- properties:
- tracks_count:
- type: "integer"
- format: "int64"
-
-ArtistAlbum:
- type: "object"
- allOf:
- - $ref: "#/BaseAlbum"
- - type: "object"
- properties:
- tracks_count:
- type: "integer"
- format: "int64"
- example: 16
-
-ChannelMetadata:
- type: "object"
- properties:
- itunes_category:
- type: string
- example: Comedy
- description: Itunes category (see `/api/v1/channels/metadata-choices`) for allowed values
- itunes_subcategory:
- type: string
- example: Improv
- description: Itunes subcategory (see `/api/v1/channels/metadata-choices`) for allowed values
- language:
- type: string
- example: en
- description: Language of the content, in ISO 639 format (see `/api/v1/channels/metadata-choices`) for allowed values
- owner_name:
- type: string
- example: "Alice"
- description: Used to make the channel compatible with other platforms (iTunes, Spotify, etc.)
- owner_email:
- type: string
- example: "alice@example.com"
- description: Used to make the channel compatible with other platforms (iTunes, Spotify, etc.)
-
-ChannelCreate:
- type: "object"
- properties:
- name:
- type: "string"
- example: "A short, public name for the channel"
- maxLength: 255
- username:
- type: "string"
- example: "aliceandbob"
- description: "The username to associate with the channel, for use over federation. This cannot be changed afterwards."
- description:
- $ref: "./properties.yml#/description"
- tags:
- $ref: "./properties.yml#/tags"
- content_category:
- $ref: "./properties.yml#/content_category"
- cover:
- type: string
- format: uuid
- metadata:
- $ref: "#/ChannelMetadata"
-ChannelUpdate:
- type: "object"
- properties:
- name:
- type: "string"
- example: "A short, public name for the channel"
- maxLength: 255
- description:
- $ref: "./properties.yml#/description"
- tags:
- $ref: "./properties.yml#/tags"
- cover:
- type: string
- format: uuid
- metadata:
- $ref: "#/ChannelMetadata"
-
-Channel:
- type: "object"
- properties:
- uuid:
- type: "string"
- format: "uuid"
- creation_date:
- $ref: "./properties.yml#/creation_date"
- artist:
- $ref: "#/BaseArtist"
- attributed_to:
- $ref: "#/Actor"
- description: User account owning the channel
- actor:
- $ref: "#/Actor"
- description: Actor representing the channel over federation
-
-Subscription:
- type: "object"
- properties:
- approved:
- type: "string"
- fid:
- $ref: "./properties.yml#/fid"
- uuid:
- type: "string"
- format: "uuid"
- creation_date:
- $ref: "./properties.yml#/creation_date"
- channel:
- $ref: "#/Channel"
-
-SubscriptionsAll:
- type: "object"
- properties:
- uuid:
- type: "string"
- format: "uuid"
- channel:
- type: "string"
- format: "uuid"
-
-Library:
- type: "object"
- properties:
- fid:
- type: string
- format: uri
- description: "The library Federation ID (unique across federation)"
- uuid:
- type: string
- format: uuid
- description: "Local ID of the library"
- name:
- type: string
- example: "My awesome library"
- description:
- type: string
- nullable: true
- example: "This library contains all the stuff I love!"
- uploads_count:
- type: "integer"
- format: "int64"
- example: 687
- privacy_level:
- type: string
- example: "me"
- enum:
- - "me"
- - "instance"
- - "everyone"
- actor:
- $ref: "#/Actor"
-LibraryPage:
- allOf:
- - $ref: "#/ResultPage"
- - type: "object"
- properties:
- results:
- type: "array"
- items:
- $ref: "#/Library"
-
-License:
- type: "object"
- properties:
- id:
- type: string
- format: uri
- example: http://creativecommons.org/publicdomain/zero/1.0/
- description: "The license ID"
- url:
- type: string
- format: uri
- example: http://creativecommons.org/publicdomain/zero/1.0/
- description: "The license url (can be different than the ID)"
- code:
- type: string
- description: "A unique code to identify the license"
- example: cc0-1.0
- redistribute:
- type: boolean
- example: true
- description: "Does the license allow free redistribution?"
- derivative:
- type: boolean
- example: true
- description: "Does the license allow the creation of derivative work?"
- commercial:
- type: boolean
- example: true
- description: "Does the license allow commercial use?"
- attribution:
- type: boolean
- example: false
- description: "Does the license requires crediting the author?"
- copyleft:
- type: boolean
- example: false
- description: "Does the license enforce a similar license of derivative work?"
-
-BaseTrack:
- type: "object"
- required:
- - id
- - fid
- - artist
- - album
- - title
- - listen_url
- - copyright
- - license
- - is_local
- properties:
- mbid:
- $ref: "./properties.yml#/mbid"
- id:
- type: "integer"
- format: "int64"
- example: 66
- fid:
- type: string
- format: uri
- description: "The track Federation ID (unique across federation)"
- artist:
- type: "integer"
- format: "int64"
- example: 42
- album:
- type: "integer"
- format: "int64"
- example: 16
- title:
- type: "string"
- example: "Chop Suey!"
- position:
- description: "Position of the track in the album"
- type: "number"
- minimum: 1
- example: 1
- disc_number:
- type: "number"
- minimum: 1
- example: 1
- listen_url:
- type: "string"
- format: "uri"
- description: "URL to stream the track"
- copyright:
- type: "string"
- example: "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0: http://creativecommons.org/licenses/by-nc-nd/4.0/"
- description: "Copyright information as extracted from upload tags"
- license:
- type: "string"
- description: "Identifier of the license that is linked to the track"
- example: "cc-by-nc-nd-4.0"
- is_local:
- type: "boolean"
- description: "Indicates if the object was initially created locally or on another server"
-
-AlbumTrack:
- type: "object"
- allOf:
- - $ref: "#/BaseTrack"
- - type: "object"
- properties:
- artist:
- $ref: "#/BaseArtist"
- uploads:
- type: "array"
- description: "List of uploads associated with this track"
- items:
- $ref: "#/Upload"
-
-ListeningCreate:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 66
- creation_date:
- $ref: "./properties.yml#/creation_date"
- track:
- type: "integer"
- format: "int64"
- example: 94
-
-Listening:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 66
- creation_date:
- $ref: "./properties.yml#/creation_date"
- track:
- $ref: "#/Track"
- actor:
- $ref: "#/Actor"
-
-Track:
- type: "object"
- allOf:
- - $ref: "#/BaseTrack"
- - type: "object"
- properties:
- album:
- $ref: "#/Album"
- artist:
- $ref: "#/BaseArtist"
- uploads:
- type: "array"
- description: "List of uploads associated with this track"
- items:
- $ref: "#/Upload"
-Upload:
- type: "object"
- properties:
- uuid:
- type: string
- format: uuid
- size:
- type: "integer"
- format: "int64"
- example: 278987000
- description: "Size of the file, in bytes"
- duration:
- type: "integer"
- format: "int64"
- example: 184
- description: "Duration of the audio, in seconds"
- bitrate:
- type: "integer"
- format: "int64"
- example: 128000
- description: "Bitrate of the file, in bytes/s"
- mimetype:
- $ref: "./properties.yml#/audio_mimetype"
- extension:
- type: string
- example: "ogg"
- description: "File extension of the upload"
- filename:
- type: "string"
- example: "Myfile.mp3"
- listen_url:
- type: "string"
- format: "uri"
- description: "URL to stream the upload"
- is_local:
- type: "boolean"
- description: "Indicates if the object was initially created locally or on another server"
-
-OwnedLibraryCreate:
- type: "object"
- required:
- - name
- - privacy_level
- properties:
- name:
- type: "string"
- example: "My new library"
- description:
- type: "string"
- example: "Lots of interesting content"
- privacy_level:
- $ref: "./properties.yml#/privacy_level"
-
-OwnedLibrary:
- type: "object"
- properties:
- uuid:
- type: string
- format: uuid
- fid:
- $ref: "./properties.yml#/fid"
- name:
- type: "string"
- example: "My Creative Commons library"
- description:
- type: "string"
- example: "All content is under CC-BY"
- creation_date:
- $ref: "./properties.yml#/creation_date"
- privacy_level:
- $ref: "./properties.yml#/privacy_level"
- uploads_count:
- type: "integer"
- format: "int64"
- example: 34
- size:
- type: "integer"
- format: "int64"
- example: 678917000
- description: "Total size of uploads in the library, in bytes"
-
-OwnedUpload:
- type: "object"
- allOf:
- - $ref: "#/Upload"
- - type: "object"
- properties:
- import_status:
- $ref: "./properties.yml#/import_status"
- track:
- $ref: "#/Track"
- library:
- $ref: "#/OwnedLibrary"
- source:
- type: "string"
- example: "upload://myfile.mp3"
- import_reference:
- type: "string"
- example: "Import launched via web UI on 03/18"
- import_metadata:
- $ref: "#/ImportMetadata"
-
-Playlist:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 42
- name:
- type: "string"
- description: Name of the playlist
- example: "Move your body"
- duration:
- type: "integer"
- format: "int64"
- description: Duration of the playlist, in seconds
- example: 3600
- tracks_count:
- type: "integer"
- format: "int64"
- description: Number of tracks in the playlist
- example: 76
- privacy_level:
- $ref: "./properties.yml#/privacy_level"
- actor:
- $ref: "#/Actor"
- description: Actor owning the playlist
- creation_date:
- $ref: "./properties.yml#/creation_date"
- modification_date:
- $ref: "./properties.yml#/modification_date"
-
-PlaylistCreate:
- type: "object"
- properties:
- name:
- type: "string"
- description: Name of the playlist
- example: "Move your body"
- privacy_level:
- $ref: "./properties.yml#/privacy_level"
-
-PlaylistTrack:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 42
- index:
- type: "integer"
- format: "int64"
- example: 16
- description: Position of the track in the playlist
- creation_date:
- $ref: "./properties.yml#/creation_date"
- track:
- $ref: "#/Track"
-
-ImportMetadata:
- type: "object"
- required:
- - title
- - position
- description: "Import metadata to override values from ID3/embedded audio tags"
- properties:
- title:
- type: "string"
- example: "My Track"
- mbid:
- $ref: "./properties.yml#/mbid"
- copyright:
- type: "string"
- example: "Alice, 2018"
- description: "Copyright information"
- license:
- type: "string"
- example: "cc-by-sa-4.0"
- description: A license code, as returned by /api/v1/licenses
- tags:
- $ref: "./properties.yml#/tags"
- position:
- description: "Position of the track in the album or channel"
- type: "number"
- minimum: 1
- example: 1
-
-TrackFavorite:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 876
- track:
- $ref: "#/Track"
- user:
- $ref: "#/User"
- creation_date:
- $ref: "./properties.yml#/creation_date"
-User:
- type: "object"
- properties:
- id:
- type: "integer"
- format: "int64"
- example: 23
- username:
- type: "string"
- example: "alice"
- name:
- type: "string"
- example: "Alice Kingsley"
- avatar:
- $ref: "#/Attachment"
-
-Me:
- type: "object"
- allOf:
- - $ref: "#/User"
- - type: "object"
- properties:
- full_username:
- type: "string"
- description: Full username, for use on federation
- example: "alice@yourdomain.com"
- email:
- type: "string"
- format: "email"
- description: E-mail address associated with the account
- example: "alice@email.provider"
- is_staff:
- type: "boolean"
- example: false
- is_superuser:
- type: "boolean"
- example: false
- date_joined:
- type: "string"
- format: "date-time"
- privacy_level:
- $ref: "./properties.yml#/privacy_level"
- description: Default privacy-level associated with the user account
- quota_status:
- $ref: "#/QuotaStatus"
- permissions:
- $ref: "#/Permissions"
- tokens:
- type: object
- properties:
- listen:
- type: string
- description: |
- A token that can be passed in the querystring, when playing
- a file from the /api/v1/listen endpoint. Example:
- /api/v1/listen/uuid/?token=foo
-
- This is especially useful in situations where authentication
- via request headers isn't possible.
-
- The token expires after 3 days by default.
-
-QuotaStatus:
- type: "object"
- properties:
- max:
- type: "integer"
- format: "int64"
- description: Storage space allocated to this user, in MB
- example: 5000
- remaining:
- type: "integer"
- format: "int64"
- description: Remaining storage space for this user, in MB
- example: 4600
- current:
- type: "integer"
- format: "int64"
- description: Storage space used by this user, in MB
- example: 400
- skipped:
- type: "integer"
- format: "int64"
- description: Storage space occupied by uploads with "skipped" import status, in MB
- example: 30
- finished:
- type: "integer"
- format: "int64"
- description: Storage space occupied by uploads with "finished" import status, in MB
- example: 350
- pending:
- type: "integer"
- format: "int64"
- description: Storage space occupied by uploads with "pending" import status, in MB
- example: 15
- draft:
- type: "integer"
- format: "int64"
- description: Storage space occupied by uploads with "draft" import status, in MB
- example: 8
- errored:
- type: "integer"
- format: "int64"
- description: Storage space occupied by uploads with "errored" import status, in MB
- example: 5
-Permissions:
- type: "object"
- properties:
- library:
- type: "boolean"
- example: false
- description: A boolean indicating if the user can manage the instance library
- moderation:
- type: "boolean"
- example: false
- description: A boolean indicating if the user has moderation permission
- settings:
- type: "boolean"
- example: false
- description: A boolean indicating if the user can manage instance settings and users
-
-RadioSessionCreate:
- type: "object"
- properties:
- radio_type:
- type: "string"
- description: |
- The type of radio to start. Depending of the type, the `related_object_id` field
- will need to be set to a non null value:
-
- - tag: tag `name`
- - artist: artist `id`
- - library: library `uuid`
-
- enum:
- - random
- - favorites
- - tag
- - similar
- - artist
- - less-listened
- - actor-content
- - library
-
- related_object_id:
- type: string
- default: null
- description: |
- Value may be an integer depending of the `radio_type`.
- Please refer to the `radio_type` documentation.
-
-RateLimitStatus:
- type: "object"
- properties:
- enabled:
- type: "boolean"
- example: true
- description: A boolean indicating if rate-limiting is enabled on the server
- ident:
- type: "object"
- description: Client-related data
- properties:
- type:
- type: string
- example: "anonymous"
- enum:
- - "authenticated"
- - "anonymous"
- id:
- type: string
- example: "92.143.42"
- description: An address IP or user ID identifying the client
- scopes:
- type: "array"
- items:
- type: "object"
- description: Rate-limit scope configuration and usage
- properties:
- id:
- type: string
- example: "password-reset"
- description:
- type: string
- example: "Password reset request"
- rate:
- type: string
- example: "30/day"
- limit:
- type: "integer"
- format: "int64"
- example: 30
- duration:
- type: "integer"
- format: "int64"
- example: 86400
- remaining:
- type: "integer"
- format: "int64"
- example: 28
- description: How many requests can be sent with the same scope before the limit applies
- reset:
- type: "integer"
- format: "int64"
- example: 1568126189
- description: A timestamp indicating when remaining
will return to its higher possible value
- reset_seconds:
- type: "integer"
- format: "int64"
- example: 86267
- description: How many seconds to wait before remaining
returns to its higher possible value
- available:
- type: "integer"
- format: "int64"
- example: 1568126089
- description: A timestamp indicating when the client can retry
- available_seconds:
- type: "integer"
- format: "int64"
- example: 54
- description: How many seconds to wait before a retry
-
-ResourceNotFound:
- type: "object"
- properties:
- detail:
- type: "string"
- example: "Not found."
diff --git a/docs/api/parameters.yml b/docs/api/parameters.yml
deleted file mode 100644
index 9fceed7d7..000000000
--- a/docs/api/parameters.yml
+++ /dev/null
@@ -1,212 +0,0 @@
-ChannelOrdering:
- $ref: "#/Ordering"
- required: false
- schema:
- type: "string"
- default: "creation_date"
- example: "creation_date"
- enum:
- - creation_date
- - artist__modification_date
-
-PlaylistOrdering:
- $ref: "#/Ordering"
- required: false
- schema:
- type: "string"
- default: "creation_date"
- example: "creation_date"
- enum:
- - creation_date
- - modification_date
- - id
- - name
-
-ArtistOrdering:
- $ref: "#/Ordering"
- required: false
- schema:
- type: "string"
- default: "creation_date"
- example: "creation_date"
- enum:
- - creation_date
- - id
- - name
- - random
-
-AlbumOrdering:
- $ref: "#/Ordering"
- required: false
- schema:
- type: "string"
- default: "creation_date"
- example: "creation_date"
- enum:
- - creation_date
- - release_date
- - title
- - random
-
-TrackOrdering:
- $ref: "#/Ordering"
- required: false
- schema:
- type: "string"
- default: "creation_date"
- example: "creation_date"
- enum:
- - creation_date
- - release_date
- - title
- - random
-
-External:
- name: "external"
- in: "query"
- required: false
- description: "Filter/exclude channels created from a third-party, non-Funkwhale RSS feed"
- schema:
- default: null
- type: "boolean"
-
-Library:
- name: library
- in: query
- description: Restrict to results contained in the given library
- schema:
- type: string
- format: uuid
-
-ObjectId:
- name: id
- in: path
- description: Object ID
- required: true
- schema:
- type: integer
- format: int64
-Ordering:
- name: "ordering"
- in: "query"
- description: "Ordering for the results, prefix with - for DESC ordering"
-
-PageNumber:
- in: query
- name: page
- schema:
- type: "integer"
- format: "int64"
- example: 1
- default: 1
- minimum: 1
-PageSize:
- in: query
- name: page_size
- schema:
- type: "integer"
- format: "int64"
- example: 16
- default: 25
- minimum: 1
- maximum: 25
-Playable:
- name: "playable"
- in: "query"
- required: false
- description: "Filter/exclude resources with playable tracks"
- schema:
- default: null
- type: "boolean"
-HasAlbums:
- name: "has_albums"
- in: "query"
- required: false
- description: "Filter/exclude artists with no associated albums"
- schema:
- default: null
- type: "boolean"
-Refresh:
- name: "refresh"
- in: "query"
- required: false
- description: "Trigger an ActivityPub fetch to refresh local data"
- schema:
- default: false
- type: "boolean"
-
-Related:
- name: related
- in: query
- description: Restrict to results similar to the given object (based on tags)
- schema:
- type: integer
- format: int64
-
-Scope:
- name: "scope"
- in: "query"
- required: false
- description: |
- Limit the results to a given user or pod:
- - Use `all` (or do not specify the property to disable scope filtering)
- - Use `me` to retrieve content relative to the current user
- - Use `subscribed` to retrieve content in libraries you follow
- - Use `actor:alice@example.com` to retrieve content relative to the account `alice@example.com
- - Use `domain:example.com` to retrieve content relative to the domain `example.com
-
- You can specify multiple coma separated scopes, e.g `scope=me,subscribed` to retrieve content matching either scopes.
-
- schema:
- default: "all"
- type: "string"
- enum:
- - "me"
- - "all"
- - "subscribed"
- - "actor:alice@example.com"
- - "domain:example.com"
-
-ContentCategory:
- name: "content_category"
- in: "query"
- description: |
- Limits the results to those whose artist content type matches the query.
-
- required: false
- schema:
- type: "string"
- enum:
- - "podcast"
- - "music"
-
-Search:
- name: "q"
- in: "query"
- required: false
- description: "Limit the results to the corresponding search query"
- schema:
- default: "all"
- type: "string"
- example: "Bonobo"
-
-Subscribed:
- name: "subscribed"
- in: "query"
- description: "Limit or exclude results with a matching subsription from the current user"
- required: false
- schema:
- type: boolean
-
-Tags:
- name: "tag"
- in: "query"
- description: "Limit the results to the corresponding tags. May be used multiple times, to retrieve objects matching al provided tags"
- required: false
- schema:
- type: array
- items:
- type: string
- example:
- - rock
- - metal
diff --git a/docs/api/properties.yml b/docs/api/properties.yml
deleted file mode 100644
index efaf0d403..000000000
--- a/docs/api/properties.yml
+++ /dev/null
@@ -1,99 +0,0 @@
-description:
- type: object
- description: Text content associated with another resource, like and artist or channel.
- properties:
- text:
- type: string
- example: "This is **me**"
- description: "The raw user input"
- content_type:
- type: string
- enum:
- - text/markdown
- - text/plain
- - text/html
- description: "The raw user input"
- html:
- type: string
- description: "HTML output based on user input"
- readOnly: true
-
-mbid:
- type: "string"
- format: "uuid"
- description: "A musicbrainz ID"
-creation_date:
- type: "string"
- format: "date-time"
- description: "Creation date of the resource"
-
-modification_date:
- type: "string"
- format: "date-time"
- description: "Last modification date of th resource"
-privacy_level:
- type: string
- example: "me"
- description: |
- * `me`: private
- * `instance`: accessible by local users
- * `everyone`: public (including over federation)
- enum:
- - "me"
- - "instance"
- - "everyone"
-fid:
- type: "string"
- format: "uri"
- description: "Federation ID"
- example: "https://my.instance/federation/music/libraries/3fa85f64-5717-4562-b3fc-2c963f66afa6"
-audio_mimetype:
- type: string
- example: "audio/ogg"
- enum:
- - "audio/ogg"
- - "audio/mpeg"
- - "audio/x-flac"
- - "audio/flac"
-image_mimetype:
- type: string
- example: "image/png"
- enum:
- - "image/png"
- - "image/jpeg"
-import_status:
- type: string
- example: "finished"
- enum:
- - "draft"
- - "pending"
- - "finished"
- - "errored"
- - "skipped"
- description: |
- * `draft`: waiting for further modifications from the owner
- * `pending`: waiting to be processed by the server
- * `finished`: successfully processed by the server
- * `errored`: couldn't be processed by the server (e.g because of a tagging issue)
- * `skipped`: processed by the server but skipped, because considered as a duplicate of an existing upload
-
-transcode_options:
- type: string
- enum:
- - "ogg"
- - "mp3"
-
-tags:
- type: array
- description: A list of hashtags associated with a resource
- items:
- type: string
- example: "Rock"
-
-content_category:
- type: "string"
- description: Used to what kind of content is published in a channel
- enum:
- - music
- - podcast
- - other
diff --git a/docs/build_swagger.sh b/docs/build_swagger.sh
index 6902a4549..1dc8419e8 100755
--- a/docs/build_swagger.sh
+++ b/docs/build_swagger.sh
@@ -1,14 +1,18 @@
#!/usr/bin/env bash
-
set -eux
-SWAGGER_VERSION="4.1.3"
+SWAGGER_VERSION="4.15.5"
TARGET_PATH=${TARGET_PATH-"swagger"}
-rm -rf "$TARGET_PATH" /tmp/swagger-ui
-git clone --branch="v$SWAGGER_VERSION" --depth=1 "https://github.com/swagger-api/swagger-ui.git" /tmp/swagger-ui
+rm -rf "$TARGET_PATH"
+tmpdir="$(mktemp -d)"
+trap 'rm -rf "$tmpdir"' EXIT
-mv /tmp/swagger-ui/dist "$TARGET_PATH"
+pushd "$tmpdir"
+wget "https://github.com/swagger-api/swagger-ui/archive/refs/tags/v$SWAGGER_VERSION.tar.gz" -O swagger-ui.tgz
+tar -xzf swagger-ui.tgz
+popd
+mv "$tmpdir/"*/dist "$TARGET_PATH"
cp schema.yml "$TARGET_PATH"
-cp -r api "$TARGET_PATH/api"
-sed -i "s,https://petstore.swagger.io/v2/swagger.json,schema.yml,g" "$TARGET_PATH/index.html"
+
+sed -i "s#https://petstore.swagger.io/v2/swagger.json#schema.yml#g" "$TARGET_PATH/swagger-initializer.js"
diff --git a/docs/swagger.yml b/docs/swagger.yml
deleted file mode 100644
index decf97951..000000000
--- a/docs/swagger.yml
+++ /dev/null
@@ -1,1781 +0,0 @@
-openapi: "3.0.3"
-info:
- description: |
- API explorer for the [Funkwhale](https://funkwhale.audio) API.
-
- Backward compatibility between minor versions (1.X to 1.Y) is guaranteed for all the
- endpoints documented here.
-
- ## 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.
-
- ## OAuth Authentication
-
- Funkwhale uses the OAuth [authorization grant flow](https://tools.ietf.org/html/rfc6749#section-4.1) for external apps. This flow is
- a secure way to authenticate apps that requires a user's explicit consent to perform actions. You can use our demo server at
- for testing purposes.
-
- To authenticate with the Funkwhale API:
-
- 1. Create an application by sending a `POST` request to `api/v1/oauth/apps`. Include your scopes and redirect URI (use `urn:ietf:wg:oauth:2.0:oob`
- to get an authorization code you can copy)
- 2. Send an [authorization request](https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2) to the `/authorize` endpoint to receive an authorization code
- 3. [Request an access token](https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3) from `/api/v1/oauth/token`
- 4. Use your access token to authenticate your calls with the following format: `Authorization: Bearer `
- 5. Refresh your access token by sending a refresh request to `/api/v1/oauth/token`
-
- For more detailed instructions, see [our API authentication documentation](https://docs.funkwhale.audio/developers/authentication.html).
-
- ## Application token authentication
-
- If you have an account on your target pod, you can create an application at `/settings/applications/new`. Once you authorize the application you
- can retrieve an access token. Use your access token to authenticate your calls with the following format: `Authorization: Bearer `
-
- ## Rate limiting
-
- Funkwhale supports rate-limiting as of version 0.2.0. Pod admins can choose to rate limit specific endpoints to prevent abuse and improve the stability of the service.
- If the server drops a request due to rate-limiting, it returns a `429` status code.
-
- Each API call returns HTTP headers to pass the following information:
-
- - What was the scope of the request (`X-RateLimit-Scope`)
- - What is the rate-limit associated with the request scope (`X-RateLimit-Limit`)
- - How many more requests in the scope can be made within the rate-limit timeframe (`X-RateLimit-Remaining`)
- - How much time does the client need to wait to send another request (`Retry-After`)
-
- For more information, check our [rate limit documentation](https://docs.funkwhale.audio/admin/configuration.html#api-configuration)
-
- ## Resources
-
- For more information about API usage, refer to [our API documentation](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:
- responses:
- 200:
- description: Success
- 201:
- description: Successfully created
- 204:
- description: Successfully deleted
- 400:
- description: Bad request
- 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:
- 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: User activity
- description: Listenings
- - 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:
- description: ""
- 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"
- description: "A human readable name for your app"
- redirect_uris:
- type: "string"
- example: "https://myapp/oauth2/funkwhale"
- description: "A list of redirect uris, separated by spaces"
- scopes:
- type: "string"
- description: "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:
- $ref: "#/components/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"
- required:
- - username
- - email
- - password1
- - password2
- properties:
- username:
- type: "string"
- example: "alice"
- email:
- type: "string"
- format: "email"
- invitation:
- type: "string"
- example: "INVITECODE"
- 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: "#/components/responses/201"
- /api/v1/auth/password/reset/:
- post:
- summary: Request a password reset
- description: |
- Request a password reset. An e-mail with reset instructions will be sent to the provided e-mail address,
- 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: "#/components/responses/200"
- /api/v1/users/me/:
- get:
- summary: Retrieve profile information
- description: |
- Retrieve profile information of the current user
- tags:
- - "Auth and security"
-
- responses:
- 200:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Me"
- delete:
- summary: Delete the user account performing the request
- tags:
- - "Auth and security"
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: "object"
- properties:
- confirm:
- type: "boolean"
- description: "Must be set to true, to avoid accidental deletion"
- password:
- type: "string"
- description: "The current password of the account"
- responses:
- 200:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Me"
- /api/v1/users/users/change-email/:
- post:
- summary: Update the e-mail address associated with a user account
- tags:
- - "Auth and security"
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: "object"
- properties:
- email:
- type: "string"
- format: "email"
- password:
- type: "string"
- description: "The current password of the account"
- responses:
- 200:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Me"
-
- /api/v1/rate-limit/:
- get:
- summary: Retrieve rate-limit information and current usage status
- tags:
- - "Auth and security"
-
- responses:
- 200:
- description: ""
- 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"
- - $ref: "./api/parameters.yml#/ArtistOrdering"
- - $ref: "./api/parameters.yml#/Playable"
- - $ref: "./api/parameters.yml#/HasAlbums"
- - $ref: "./api/parameters.yml#/Library"
- - $ref: "./api/parameters.yml#/PageNumber"
- - $ref: "./api/parameters.yml#/PageSize"
- - $ref: "./api/parameters.yml#/Related"
- - $ref: "./api/parameters.yml#/Scope"
- - $ref: "./api/parameters.yml#/ContentCategory"
- responses:
- 200:
- description: ""
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Artist"
- 404:
- description: "Not Found"
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/LibraryPage"
- 404:
- description: "Not Found"
- 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"
- required: false
- description: "Only include albums by the requested artist"
- schema:
- nullable: true
- type: "integer"
- format: "int64"
- - $ref: "./api/parameters.yml#/AlbumOrdering"
- - $ref: "./api/parameters.yml#/Library"
- - $ref: "./api/parameters.yml#/Playable"
- - $ref: "./api/parameters.yml#/PageNumber"
- - $ref: "./api/parameters.yml#/PageSize"
- - $ref: "./api/parameters.yml#/Related"
- - $ref: "./api/parameters.yml#/Scope"
- - $ref: "./api/parameters.yml#/ContentCategory"
-
- responses:
- 200:
- description: ""
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Album"
- 404:
- description: "Not Found"
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/LibraryPage"
- 404:
- description: "Not Found"
- 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"
- required: false
- description: "Only include tracks by the requested artist"
- schema:
- nullable: true
- type: "integer"
- format: "int64"
- - name: "favorites"
- in: "query"
- required: false
- description: "filter/exclude tracks favorited by the current user"
- schema:
- nullable: true
- type: "boolean"
- - name: "album"
- in: "query"
- required: false
- description: "Only include tracks from the requested album"
- schema:
- nullable: true
- type: "integer"
- format: "int64"
- - name: "license"
- in: "query"
- description: "Only include tracks with the given license"
- required: false
- schema:
- example: "cc-by-sa-4.0"
- nullable: true
- type: "string"
- - $ref: "./api/parameters.yml#/TrackOrdering"
- - $ref: "./api/parameters.yml#/Library"
- - $ref: "./api/parameters.yml#/Playable"
- - $ref: "./api/parameters.yml#/PageNumber"
- - $ref: "./api/parameters.yml#/PageSize"
- - $ref: "./api/parameters.yml#/Related"
- - $ref: "./api/parameters.yml#/Scope"
-
- responses:
- 200:
- description: ""
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Track"
- 404:
- description: "Not Found"
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/LibraryPage"
- 404:
- description: "Not Found"
- 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
- description: |
- An upload uuid
-
- 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:
- description: ""
- content:
- "*/*":
- schema:
- description: "Audio file, as binary data"
- type: string
- format: binary
- 404:
- description: "Not Found"
- 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:
- description: ""
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/License"
- 404:
- description: "Not Found"
- 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:
- description: ""
- 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: "#/components/responses/201"
- 400:
- $ref: "#/components/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:
- description: ""
- 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:
- description: ""
- 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: "#/components/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:
- description: ""
- 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: "#/components/responses/201"
- 400:
- $ref: "#/components/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.
- description: "Channels and subscriptions"
- get:
- summary: List channels metadata options
- tags:
- - "Channels and subscriptions"
- responses:
- 200:
- description: ""
- 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:
- description: ""
- 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:
- description: ""
- 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: "#/components/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:
- description: ""
- 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:
- description: ""
- 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:
- description: ""
- 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:
- $ref: "#/components/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:
- description: ""
- 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: "#/components/responses/201"
- 400:
- $ref: "#/components/responses/400"
- requestBody:
- required: true
- content:
- multipart/form-data:
- schema:
- type: object
- required:
- - library
- - import_reference
- - source
- - audio_file
- - import_status
- 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:
- $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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Subscription"
-
- /api/v1/subscriptions/:
- get:
- summary: List subscriptions
- tags:
- - "Channels and subscriptions"
- responses:
- 200:
- description: ""
- 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:
- description: ""
- 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:
- description: ""
- 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:
- description: ""
- 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: "#/components/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:
- description: ""
- 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:
- description: ""
- 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:
- description: ""
- 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: "#/components/responses/204"
-
- #################
- # User activity #
- #################
-
- /api/v1/history/listenings:
- get:
- tags:
- - "User activity"
- parameters:
- - $ref: "./api/parameters.yml#/Search"
- - $ref: "./api/parameters.yml#/PageNumber"
- - $ref: "./api/parameters.yml#/PageSize"
- - $ref: "./api/parameters.yml#/Scope"
-
- responses:
- 200:
- description: ""
- content:
- application/json:
- schema:
- allOf:
- - $ref: "./api/definitions.yml#/ResultPage"
- - type: "object"
- properties:
- results:
- type: "array"
- items:
- $ref: "./api/definitions.yml#/Listening"
- post:
- summary: Record a track in your history
- tags:
- - "User activity"
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: "object"
- properties:
- track:
- type: "integer"
- format: "int64"
- example: 98
- responses:
- 201:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/ListeningCreate"
-
- ##########
- # Others #
- ##########
-
- /api/v1/search:
- get:
- tags:
- - "Other"
- description: Search artists, tracks, albums and other resources
- parameters:
- - $ref: "./api/parameters.yml#/Search"
- responses:
- 200:
- $ref: "#/components/responses/200"
- 400:
- $ref: "#/components/responses/400"
-
- /api/v1/instance/settings:
- get:
- tags:
- - "Other"
- description: Retrieve pod-level configuration such as description or max playlist size
- responses:
- 200:
- description: ""
- content:
- application/json:
- schema:
- type: "array"
- description: "List of settings with their id, label and values"
- items:
- type: object
- properties:
- name:
- type: "string"
- description: "Name of the setting"
- example: "max_channels"
- section:
- type: "string"
- description: "Group of the setting"
- example: "audio"
- identifier:
- type: "string"
- description: "Unique identifier of the setting"
- example: "audio__max_channels"
- default:
- description: Default value of the setting
- value:
- description: Current value of the setting
- verbose_name:
- type: "string"
- description: Human-readable label of the setting
- help_text:
- type: "string"
- description: Human-readable description of the setting
- field:
- type: "object"
- properties:
- input_type:
- type: string
- description: "Input type of the setting"
-
- /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: "#/components/responses/201"
- 400:
- $ref: "#/components/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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Attachment"
- delete:
- summary: Delete an attachment
- tags:
- - "Other"
- responses:
- 204:
- $ref: "#/components/responses/204"
-
- /api/v1/playlists/:
- get:
- summary: List playlists
- tags:
- - "Content curation"
- parameters:
- - $ref: "./api/parameters.yml#/Search"
- - $ref: "./api/parameters.yml#/PlaylistOrdering"
- - 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:
- description: ""
- 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: "#/components/responses/201"
- 400:
- $ref: "#/components/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:
- description: ""
- 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:
- description: ""
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Playlist"
- delete:
- description: Delete the playlist
- tags:
- - "Content curation"
- responses:
- 204:
- $ref: "#/components/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:
- description: ""
- 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: |
- Whether to raise an error when the same track is added
- multiple time in the playlist
- responses:
- 201:
- description: ""
- 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}/move:
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: "integer"
- format: "int64"
- post:
- tags:
- - "Content curation"
- summary: Move a track to another index within its playlist
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- properties:
- from:
- type: "integer"
- format: "int64"
- description: Current index of the track
- to:
- type: "integer"
- format: "int64"
- description: New index of the track
-
- responses:
- 204:
- $ref: "#/components/responses/204"
- /api/v1/playlists/{id}/remove:
- parameters:
- - name: id
- in: path
- required: true
- schema:
- type: "integer"
- format: "int64"
- post:
- tags:
- - "Content curation"
- summary: Remove a track from its playlist
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- properties:
- index:
- type: "integer"
- format: "int64"
- description: Index of the track to remove
-
- responses:
- 204:
- $ref: "#/components/responses/204"
- /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:
- $ref: "#/components/responses/204"
- /api/v1/radios/sessions:
- post:
- tags:
- - "Content curation"
- description: Start a new radio session
- responses:
- 201:
- $ref: "#/components/responses/201"
- 400:
- $ref: "#/components/responses/400"
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/RadioSessionCreate"
- /api/v1/radios/tracks:
- post:
- tags:
- - "Content curation"
- description: Get a new track for a radio session
- responses:
- 201:
- $ref: "#/components/responses/201"
- 400:
- $ref: "#/components/responses/400"
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: "./api/definitions.yml#/Track"