# API - Authenticated endpoints All endpoints under namespace `/api/v1/auth` require authentication. Authentication can be in one of two forms: - A `Cookie: ` header (for logged in users) - An `Authentication: Bearer ` (recommended) A new token can be generated from `/authorize_token` with the given parameters: ``` scopes: Comma-separated list of scopes callback_url: URL to redirect to with generated token expire: Int64 how long a given token should be valid (in seconds) ``` Each `scope` has the following format: ``` METHOD1;METHOD2...:ENDPOINT(*)? ``` Where `METHOD` can be one of `GET`, `POST`, `PUT`, `DELETE`, `PATCH`. An `ENDPOINT` can be any of the documented endpoints below. Examples: - `POST:playlists*`: authorizes `POST` methods to _any_ endpoint under `/api/v1/auth/playlists` (`/api/v1/auth/playlists`, `/api/v1/playlists/:id/videos`, etc.) - `:playlists/*`: authorizes _any_ method to endpoints under `/api/v1/auth/playlists/` (`/api/v1/auth/playlists/:id`, `/api/v1/playlists/:id/videos`, etc.) - `GET:playlists/IVPAAAAAAA`: authorizes `GET` only to playlist `IVPAAAAAAA`. - `:preferences`: authorizes _any_ method to `/api/v1/auth/preferences` - `GET;POST:preferences`: authorizes `GET` or `POST` to `/api/v1/auth/preferences` When a `callback_url` is specified, after a user has authorized a token with the desired `scopes`, a GET request will be made to the `callback_url` with the token URL-escaped and appended as `token=TOKEN`. ##### GET `/api/v1/auth/feed` Get subscription feed for the authenticated user. Parameters: ``` max_results: Int32 page: Int32 ``` > Schema: ```javascript { "notifications": [ { "type": "shortVideo", "title": String, "videoId": String, "videoThumbnails": [ { "quality": String, "url": String, "width": Int64, "height": Int64 } ], "lengthSeconds": Int64, "author": String, "authorId": String, "authorUrl": String, "published": Int64, "publishedText": String, "viewCount": Int64 } ], "videos": [ { "type": "shortVideo", "title": String, "videoId": String, "videoThumbnails": [ { "quality": String, "url": String, "width": Int64, "height": Int64 } ], "lengthSeconds": Int64, "author": String, "authorId": String, "authorUrl": String, "published": Int64, "publishedText": String, "viewCount": Int64 } ] } ``` ##### GET `/api/v1/auth/notifications` Parameters: ``` topics: Array(String) (comma separated: e.g. "UCID1,UCID2) limit of 1000 topics since: Int64, timestamp ``` Provides an [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) for receiving changes from each `topic` in `topics`. Currently the only supported topic-type is `ucid`, which will return an updated video object whenever the given channel uploads a video. Important to note is that an event will also be sent when a channel _changes_ an already uploaded video, for example changing description or title. Each event is a JSON object with the same schema as `/api/v1/videos`. The `fields` API can be used, which will be applied to each object. A `debug` topic can also provided which will return a (psuedo-)randomly selected video every minute. `since` will return all videos uploaded since `TIMESTAMP`, with a limit of the 15 most recent videos from each topic. More details in [#469](https://github.com/iv-org/invidious/issues/469). ##### POST `/api/v1/auth/notifications` Same as above `GET` endpoint, however `topics` is moved into post body as `Content-Type: application/x-www-form-urlencoded`. ##### GET `/api/v1/auth/playlists` Get list of playlists for the given user. > Schema: ```javascript [ { "type": "invidiousPlaylist", "title": String, "playlistId": String, "author": String, "authorId": null, "authorUrl": null, "authorThumbnails": [], "description": String, "descriptionHtml": String, "videoCount": Int32, "viewCount": 0, "updated": Int64, "isListed": Boolean, "videos": [ { "title": String, "videoId": String, "author": String, "authorId": String, "authorUrl": String, "videoThumbnails": [ { "quality": String, "url": String, "width": Int32, "height": Int32 } ], "index": Int32, "indexId": String, "lengthSeconds": Int32 } ] } ] ``` ##### POST `/api/v1/auth/playlists` `Content-Type: application/json` Create new playlist. Example request body: ```javascript { "title": String, "privacy": "private" } ``` `privacy` can be any of: `public`, `unlisted`, `private` If successful, returns 201, a link to the created resource as a `Location` header, and the following response: ```javascript { "title": String, "playlistId": String } ``` ##### GET `/api/v1/auth/playlists/:id` Returns same result as unauthenticated `/api/v1/playlists/:id`. Important to note is that if the requested playlist is marked as `private`, it will return an error if the request is not authenticated as the playlist's author. ##### PATCH `/api/v1/auth/playlists/:id` `Content-Type: application/json` Modify a playlist's `description`, `title`, `description`, or `privacy`. Example request body: ```javascript { "title": String, "description": String, "privacy": "private" } ``` `privacy` can be any of: `public`, `unlisted`, `private` Will return 204 on success. ##### DELETE `/api/v1/auth/playlists/:id` Delete a given playlist `:id`. Will return 204 on success. ##### POST `/api/v1/auth/playlists/:id/videos` `Content-Type: application/json` Add a video to the given playlist `:id`. Example request body: ```javascript { "videoId": String } ``` Returns a 201 on success with the following schema: ```javascript { "title": String, "videoId": String, "author": String, "authorId": String, "authorUrl": String, "videoThumbnails": [ { "quality": String, "url": String, "width": Int32, "height": Int32 } ] } ``` ##### DELETE `/api/v1/auth/playlists/:id/videos/:index` Delete a video from the given playlist `:id` with `indexId` `:index`. Will return 204 on success. ##### GET `/api/v1/auth/preferences` Get preferences for authenticated user. > Schema: ```javascript { "annotations": false, "annotations_subscribed": false, "autoplay": false, "captions": [ "", "", "" ], "comments": [ "youtube", "" ], "continue": false, "continue_autoplay": true, "dark_mode": "light", "latest_only": false, "listen": false, "local": false, "locale": "en-US", "max_results": 40, "notifications_only": false, "player_style": "invidious", "quality": "hd720", "default_home": "Popular", "feed_menu": [ "Trending", "Playlists" ], "related_videos": true, "sort": "published", "speed": 1.0, "thin_mode": false, "unseen_only": false, "video_loop": false, "volume": 100 } ``` ##### POST `/api/v1/auth/preferences` `Content-Type: application/json` Patch user preferences. Example body: ```javascript { "speed": 2.0, "volume": 10 } ``` ##### GET `/api/v1/auth/subscriptions` Get user's subscriptions. > Schema: ```javascript [ { "author": String, "authorId": String } ] ``` ##### POST `/api/v1/auth/subscriptions/:ucid` `Content-Type: application/json` Add a given `ucid` to a user's subscriptions. Will return 204 on success. ##### DELETE `/api/v1/auth/subscriptions/:ucid` Removes a given `ucid` from a user's subscriptions. Will return 204 on success. ##### GET `/api/v1/auth/tokens` Get a list of tokens for the authenticated user. > Schema: ```javascript [ { "session": String, "issued": Int64 } ] ``` ##### POST `/api/v1/auth/tokens/register` `Content-Type: application/json` Create a new token for the authenticated user. Example request body: ```javascript { "scopes": Array(String), // Each scope has same format as each scope in `/authorize_token` "callbackUrl": String?, "expire": Int64 } ``` Returns a 200 on success with the newly created token as the response body. Example response: ```javascript { "session":"v1:YUwKEL1XwHQzp7-AAAAAAAAAAAAAAAAAA=", "scopes":["GET:notifications"], "signature":"jNYdAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAXGb__2Gv-w=" } ``` ##### POST `/api/v1/auth/tokens/unregister` `Content-Type: application/json` Revoke a token for the authenticated user. Example request: ```javascript { "session": "v1:YUwKEL1XwHQzp7-AAAAAAAAAAAAAAAAAA=" } ``` Returns 204 on success.