File size: 14,494 Bytes
11fcc5a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# cobalt api documentation
methods, acceptable values, headers, responses and everything else related to making and parsing requests from a cobalt api instance.

> [!IMPORTANT]
> hosted api instances (such as `api.cobalt.tools`) use bot protection and are **not** intended to be used in other projects without explicit permission. if you want to use the cobalt api, you should [host your own instance](/docs/run-an-instance.md) or ask an instance owner for access.

- [POST /](#post)
- [POST /session](#post-session)
- [GET /](#get)
- [GET /tunnel](#get-tunnel)

all endpoints (except for `GET /`) are rate limited and return current rate limiting status in `RateLimit-*` headers, according to the ["RateLimit Header Fields for HTTP" spec](https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-02.html#name-header-specifications).

## authentication
an api instance may be configured to require you to authenticate yourself.
if this is the case, you will typically receive an [error response](#error-response)
with a **`api.auth.<method>.missing`** code, which tells you that a particular method
of authentication is required.

authentication is done by passing the `Authorization` header, containing
the authentication scheme and the token:
```
Authorization: <scheme> <token>
```

currently, cobalt supports two ways of authentication. an instance can
choose to configure both, or neither:
- [`Api-Key`](#api-key-authentication)
- [`Bearer`](#bearer-authentication)

### api-key authentication
the api key authentication is the most straightforward. the instance owner
will assign you an api key which you can then use to authenticate like so:
```
Authorization: Api-Key aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
```

if you are an instance owner and wish to configure api key authentication,
see the [instance](run-an-instance.md#api-key-file-format) documentation!

### bearer authentication
the cobalt server may be configured to issue JWT bearers, which are short-lived
tokens intended for use by regular users (e.g. after passing a challenge).
currently, cobalt can issue tokens for successfully solved [turnstile](run-an-instance.md#list-of-all-environment-variables)
challenge, if the instance has turnstile configured. the resulting token is passed like so:
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

## POST `/`
cobalt's main processing endpoint.

> [!IMPORTANT]
> you must include correct `Accept` and `Content-Type` headers with every `POST /` request.

```
Accept: application/json
Content-Type: application/json
```

### request body
body type: `application/json`

not a fan of reading tables of text?
you can read [the api schema](/api/src/processing/schema.js) directly from code instead!

### api schema
all keys except for `url` are optional. value options are separated by `/`.

#### general
| key               | type      | description/value                                               | default    |
|:------------------|:----------|:----------------------------------------------------------------|:-----------|
| `url`             | `string`  | source URL                                                      | *required* |
| `audioBitrate`    | `string`  | `320 / 256 / 128 / 96 / 64 / 8` (kbps)                          | `128`      |
| `audioFormat`     | `string`  | `best / mp3 / ogg / wav / opus`                                 | `mp3`      |
| `downloadMode`    | `string`  | `auto / audio / mute`                                           | `auto`     |
| `filenameStyle`   | `string`  | `classic / pretty / basic / nerdy`                              | `basic`    |
| `videoQuality`    | `string`  | `max / 4320 / 2160 / 1440 / 1080 / 720 / 480 / 360 / 240 / 144` | `1080`     |
| `disableMetadata` | `boolean` | title, artist, and other info will not be added to the file     | `false`    |
| `alwaysProxy`     | `boolean` | always tunnel all files, even when not necessary                | `false`    |
| `localProcessing` | `string`  | `disabled / preferred / forced`                                 | `disabled` |
| `subtitleLang`    | `string`  | any valid ISO 639-1 language code                               | *none*     |

#### service-specific options
| key                     | type      | description/value                                 | default |
|:------------------------|:----------|:--------------------------------------------------|:--------|
| `youtubeVideoCodec`     | `string`  | `h264 / av1 / vp9`                                | `h264`  |
| `youtubeVideoContainer` | `string`  | `auto / mp4 / webm / mkv`                         | `auto`  |
| `youtubeDubLang`        | `string`  | any valid ISO 639-1 language code                 | *none*  |
| `convertGif`            | `boolean` | convert twitter gifs to the actual GIF format     | `true`  |
| `allowH265`             | `boolean` | allow H265/HEVC videos from tiktok/xiaohongshu    | `false` |
| `tiktokFullAudio`       | `boolean` | download the original sound used in a video       | `false` |
| `youtubeBetterAudio`    | `boolean` | prefer higher quality youtube audio if possible   | `false` |
| `youtubeHLS`            | `boolean` | use HLS formats when downloading from youtube     | `false` |

### response
body type: `application/json`

the response will always be a JSON object containing the `status` key, which is one of:
- `tunnel`: cobalt is proxying and/or remuxing/transcoding the file for you.
- `local-processing`: cobalt is proxying the files for you, but you have to remux/transcode them locally.
- `redirect`: cobalt will redirect you to the direct service URL.
- `picker`: there are multiple items to choose from, a picker should be shown.
- `error`: something went wrong, here's an error code.

### tunnel/redirect response
| key          | type     | value                                                      |
|:-------------|:---------|:-----------------------------------------------------------|
| `status`     | `string` | `tunnel / redirect`                                        |
| `url`        | `string` | url for the cobalt tunnel, or redirect to an external link |
| `filename`   | `string` | cobalt-generated filename for the file being downloaded    |

### local processing response
| key          | type       | value                                                         |
|:-------------|:-----------|:--------------------------------------------------------------|
| `status`     | `string`   | `local-processing`                                            |
| `type`       | `string`   | `merge`, `mute`, `audio`, `gif`, or `remux`                   |
| `service`    | `string`   | origin service (`youtube`, `twitter`, `instagram`, etc)       |
| `tunnel`     | `string[]` | array of tunnel URLs                                          |
| `output`     | `object`   | details about the output file ([see below](#output-object))   |
| `audio`      | `object`   | audio-specific details (optional, [see below](#audio-object)) |
| `isHLS`      | `boolean`  | whether the output is in HLS format (optional)                |

#### output object
| key         | type      | value                                                                             |
|:------------|:----------|:----------------------------------------------------------------------------------|
| `type`      | `string`  | mime type of the output file                                                      |
| `filename`  | `string`  | filename of the output file                                                       |
| `metadata`  | `object`  | metadata associated with the file (optional, [see below](#outputmetadata-object)) |
| `subtitles` | `boolean` | whether tunnels include a subtitle file                                           |

#### output.metadata object
all keys in this table are optional.

| key            | type     | description                                |
|:---------------|:---------|:-------------------------------------------|
| `album`        | `string` | album name or collection title             |
| `composer`     | `string` | composer of the track                      |
| `genre`        | `string` | track's genre(s)                           |
| `copyright`    | `string` | copyright information or ownership details |
| `title`        | `string` | title of the track or media file           |
| `artist`       | `string` | artist or creator name                     |
| `album_artist` | `string` | album's artist or creator name             |
| `track`        | `string` | track number or position in album          |
| `date`         | `string` | release date or creation date              |
| `sublanguage`  | `string` | subtitle language code (ISO 639-2)         |

#### audio object
| key         | type      | value                                                      |
|:------------|:----------|:-----------------------------------------------------------|
| `copy`      | `boolean` | defines whether audio codec data is copied                 |
| `format`    | `string`  | output audio format                                        |
| `bitrate`   | `string`  | preferred bitrate of audio format                          |
| `cover`     | `boolean` | whether tunnels include a cover art file (optional)        |
| `cropCover` | `boolean` | whether cover art should be cropped to a square (optional) |

### picker response
| key             | type     | value                                                                                          |
|:----------------|:---------|:-----------------------------------------------------------------------------------------------|
| `status`        | `string` | `picker`                                                                                       |
| `audio`         | `string` | returned when an image slideshow (such as on tiktok) has a general background audio (optional) |
| `audioFilename` | `string` | cobalt-generated filename, returned if `audio` exists (optional)                               |
| `picker`        | `array`  | array of objects containing the individual media                                               |

#### picker object
| key          | type      | value                     |
|:-------------|:----------|:--------------------------|
| `type`       | `string`  | `photo` / `video` / `gif` |
| `url`        | `string`  |                           |
| `thumb`      | `string`  | thumbnail url (optional)  |

### error response
| key          | type     | value                         |
|:-------------|:---------|:------------------------------|
| `status`     | `string` | `error`                       |
| `error`      | `object` | error code & optional context |

#### error object
| key          | type     | value                                                     |
|:-------------|:---------|:----------------------------------------------------------|
| `code`       | `string` | machine-readable error code explaining the failure reason |
| `context`    | `object` | additional error context (optional)                       |

#### error.context object
| key          | type     | value                                                                       |
|:-------------|:---------|:----------------------------------------------------------------------------|
| `service`    | `string` | origin service (optional)                                                   |
| `limit`      | `number` | the maximum downloadable video duration or the rate limit window (optional) |

## POST `/session`
used for generating JWT tokens, if enabled. currently, cobalt only supports
generating tokens when a [turnstile](run-an-instance.md#list-of-all-environment-variables) challenge solution
is submitted by the client.

the turnstile challenge response is submitted via the `cf-turnstile-response` header.

### response body
| key             | type       | description                                            |
|:----------------|:-----------|:-------------------------------------------------------|
| `token`         | `string`   | a `Bearer` token used for later request authentication |
| `exp`           | `number`   | number in seconds indicating the token lifetime        |

on failure, an [error response](#error-response) is returned.

## GET `/`
provides basic instance info.

### response
body type: `application/json`

| key         | type     | description                                              |
|:------------|:---------|:---------------------------------------------------------|
| `cobalt`    | `object` | information about the cobalt instance                    |
| `git`       | `object` | information about the codebase that is currently running |

#### cobalt object
| key                | type       | description                                    |
|:-------------------|:-----------|:-----------------------------------------------|
| `version`          | `string`   | cobalt version                                 |
| `url`              | `string`   | instance url                                   |
| `startTime`        | `string`   | instance start time in unix milliseconds       |
| `turnstileSitekey` | `string`   | site key for a turnstile widget (optional)     |
| `services`         | `string[]` | array of services which this instance supports |

#### git object
| key         | type     | description |
|:------------|:---------|:------------|
| `commit`    | `string` | commit hash |
| `branch`    | `string` | git branch  |
| `remote`    | `string` | git remote  |

## GET `/tunnel`
endpoint for file tunnels (proxy/remux/transcode). the response is a file stream. all errors are reported via
[HTTP status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status).

### returned headers
- `Content-Length`: file size, in bytes. returned when exact final file size is known.
- `Estimated-Content-Length`: estimated file size, in bytes. returned when real `Content-Length` is not known.
a rough estimate which should NOT be used for strict size verification.
can be used to show approximate download progress in UI.

### possible HTTP status codes
- 200: OK
- 401: Unauthorized
- 403: Bad Request
- 404: Not Found
- 429: Too Many Requests (rate limit exceeded, check [RateLimit-* headers](https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-02.html#name-header-specifications))
- 500: Internal Server Error.