mirror of
https://github.com/iv-org/documentation.git
synced 2025-05-02 06:46:22 -04:00
Update channels api docs (#326)
* Add a page specifying common object types * Add a page for the /api/v1/channels endpoint * Remove obselete definitions from api.md * Add/update links in index.md and mkdocs.yml * Impove MkDocs config to support code highlight & copy button * Use native JS types for better syntax highlighting
This commit is contained in:
parent
4a66173585
commit
dca939835c
6 changed files with 250 additions and 199 deletions
420
docs/api/authenticated-endpoints.md
Normal file
420
docs/api/authenticated-endpoints.md
Normal file
|
@ -0,0 +1,420 @@
|
|||
# Authenticated Endpoints
|
||||
|
||||
All endpoints under namespace `/api/v1/auth` require authentication.
|
||||
|
||||
Authentication can be in one of two forms:
|
||||
|
||||
- A `Cookie: <SID>` header (for logged in users)
|
||||
- An `Authentication: Bearer <TOKEN>` (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.
|
124
docs/api/channels_endpoint.md
Normal file
124
docs/api/channels_endpoint.md
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Channels endpoint
|
||||
|
||||
Please refer to the [Common object types](./common_types.md) page for more
|
||||
details on the various JSON objects used below.
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id`
|
||||
|
||||
> Response:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"author": String,
|
||||
"authorId": String,
|
||||
"authorUrl": String,
|
||||
"authorBanners": [
|
||||
// One or more ImageObject
|
||||
],
|
||||
"authorThumbnails": [
|
||||
// One or more ImageObject
|
||||
],
|
||||
|
||||
"subCount": Number, // Integer
|
||||
"totalViews": Number, // Integer
|
||||
"joined": Number, // Unix timestamp
|
||||
|
||||
"autoGenerated": Boolean,
|
||||
"isFamilyFriendly": Boolean,
|
||||
|
||||
"description": String,
|
||||
"descriptionHtml": String,
|
||||
"allowedRegions": [String],
|
||||
|
||||
"latestVideos": [
|
||||
// One or more VideoObject
|
||||
],
|
||||
"relatedChannels": [
|
||||
// One or more ChannelObject
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/channels`
|
||||
|
||||
> URL parameters:
|
||||
|
||||
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
|
||||
|
||||
> Response:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"relatedChannels": [
|
||||
// One or more ChannelObject
|
||||
],
|
||||
"continuation": String
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/latest`
|
||||
|
||||
This is the same as requesting `/api/v1/channels/:id/videos` without URL parameters.
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/playlists`
|
||||
|
||||
> URL parameters:
|
||||
|
||||
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
|
||||
* `sort_by`: Sort order filter. Accepted values: `oldest`, `newest`, `last`. Defaults to `last`.
|
||||
|
||||
> Response:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"playlists": [
|
||||
// One or more PlaylistOject
|
||||
],
|
||||
"continuation": continuation
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/shorts`
|
||||
|
||||
> URL parameters:
|
||||
|
||||
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
|
||||
|
||||
> Response:
|
||||
|
||||
See: GET `/api/v1/channels/:id/videos`
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/streams`
|
||||
|
||||
> URL parameters:
|
||||
|
||||
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
|
||||
|
||||
> Response:
|
||||
|
||||
See: GET `/api/v1/channels/:id/videos`
|
||||
|
||||
|
||||
##### GET `/api/v1/channels/:id/videos`
|
||||
|
||||
> URL parameters:
|
||||
|
||||
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
|
||||
* `sort_by`: Sort order filter. Accepted values: `newest`, `popular` or `oldest` (Broken as of 10/2022). Default to `newest`.
|
||||
|
||||
> Response:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"videos": [
|
||||
// One or more VideoObject
|
||||
],
|
||||
"continuation": String
|
||||
}
|
||||
```
|
114
docs/api/common_types.md
Normal file
114
docs/api/common_types.md
Normal file
|
@ -0,0 +1,114 @@
|
|||
# Object types used across the API
|
||||
|
||||
|
||||
### ImageObject
|
||||
|
||||
```javascript
|
||||
{
|
||||
"url": String,
|
||||
"width": Number, // Integer
|
||||
"height": Number // Integer
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### ThumbnailObject
|
||||
|
||||
```javascript
|
||||
{
|
||||
"quality": String,
|
||||
"url": String,
|
||||
"width": Number, // Integer
|
||||
"height": Number // Integer
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### VideoObject
|
||||
|
||||
```javascript
|
||||
{
|
||||
"type": "video", // Constant
|
||||
|
||||
"title": String,
|
||||
"videoId": String,
|
||||
|
||||
"author": String,
|
||||
"authorId": String,
|
||||
"authorUrl": String,
|
||||
|
||||
"videoThumbnails": [
|
||||
// One or more ThumbnailObject
|
||||
],
|
||||
|
||||
"description": String,
|
||||
"descriptionHtml": String,
|
||||
|
||||
"viewCount": Number, // Integer
|
||||
"lengthSeconds": Number, // Integer
|
||||
|
||||
"published": Number, // Unix timestamp
|
||||
"publishedText": String,
|
||||
|
||||
// Only available on premiered videos
|
||||
"premiereTimestamp": Number, // Unix timestamp
|
||||
|
||||
"liveNow": Boolean,
|
||||
"premium": Boolean,
|
||||
"isUpcoming": Boolean
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### ChannelObject
|
||||
|
||||
```javascript
|
||||
{
|
||||
"type": "channel", // Constant
|
||||
|
||||
"author": String,
|
||||
"authorId": String,
|
||||
"authorUrl": String,
|
||||
"authorVerified": Boolean,
|
||||
"authorThumbnails": [
|
||||
// One or more ThumbnailObject
|
||||
],
|
||||
|
||||
"autoGenerated": Boolean,
|
||||
"subCount": Number, // Integer
|
||||
"videoCount": Number, // Integer
|
||||
|
||||
"description": String,
|
||||
"descriptionHtml": String,
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### PlaylistOject
|
||||
|
||||
```javascript
|
||||
{
|
||||
"type": "playlist", // Constant
|
||||
|
||||
"title": String,
|
||||
"playlistId": String,
|
||||
"playlistThumbnail": String,
|
||||
|
||||
"author": String,
|
||||
"authorId": String,
|
||||
"authorUrl": String,
|
||||
"authorVerified": Boolean,
|
||||
|
||||
"videoCount": Number, // Integer
|
||||
"videos": [
|
||||
{
|
||||
"title": String,
|
||||
"videoId": String,
|
||||
"lengthSeconds": Number, // Integer
|
||||
"videoThumbnails": [
|
||||
// One or more ThumbnailObject
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue