List downloads
const url = 'https://example.com/api/v1/downloads';const options = {method: 'GET', headers: {cookie: 'kivo_session=<kivo_session>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://example.com/api/v1/downloads \ --cookie kivo_session=<kivo_session>The downloads the server keeps for the caller’s session,
newest first, each as GET /api/v1/downloads/{id} gives it: what
an app takes up again after a relaunch or a server restart. A
download leaves the list when the app deletes it, 7 days after
it’s ready or failed, or when the session ends.
Authorizations
Section titled “Authorizations”Responses
Section titled “Responses”The session’s downloads.
object
A download as the server holds it for its session. Media URLs are
relative to the API root (/api/v1/) and need the user’s
authorization.
object
A UUIDv7.
A UUIDv7.
A UUIDv7.
The quality asked for, original for a book.
Where a download is: queued waiting in line on the server
(queuePosition says where); preparing its subtitles or conversion
being made (progress and remainingMs say how far); ready to
fetch each part’s url, and each subtitle’s; failed (reason says
why, and retry asks again).
While queued, its place in line, 1 when it’s next.
While preparing, how much is converted, from 0 to 1.
While converting, about how long it has left, once that can be told.
When failed, why: transcodeFailed, storageFull,
sourceUnreadable, subtitlesUnavailable or planUnreadable.
What a download fetches: the original file, or a conversion, an
MP4 per part made for the download.
Every track of the version, and the subtitle choice off, as a
play gives them (PlayStarted.tracks), for playing the download
offline. A track inside the downloaded file has delivery file
and its stream index in that file: in a conversion the video, the
audio, then each text track it carries, the chosen one first. A
subtitle delivered external is fetched with the download, at
url, once the download is ready; one that couldn’t be
extracted has no delivery. A choice without a delivery isn’t in
the download.
One choice of a play: a track of its version, or the subtitle choice
off, and how it shows.
object
A track’s id, or off.
A track’s type.
True for the tracks the play shows; absent otherwise.
Absent when choosing it starts a new play.
The codec it’s delivered as, such as hevc, aac or webvtt.
The video’s HDR as delivered; absent for SDR.
What a transcoded track becomes.
object
Video only; what encodes it, the accelerator’s name as GET /api/v1/accelerators gives it, such as Intel Quick Sync (QSV), or CPU.
Why the track isn’t delivered unchanged in the file, or why choosing it starts a new play, when there’s a reason to give.
The capability that failed: its field (such as maxLevel, codec
or containers), what the client declared, and what the track has.
object
The declared value, lists joined by commas; absent when the client declared none.
For file, the track’s stream index, to select it in the player.
For external, the file, relative to the API root.
For an ass subtitle delivered external, the URLs of the
fonts it uses, each once, relative to the API root:
GET /api/v1/fonts/{sha256}, cacheable for good. Load them
before drawing.
Every part’s bytes. Exact when sizeExact; until a conversion
is ready, an estimate from the quality’s cap, which a grainy
title can exceed.
sizeBytes is exact: the download is ready, or the original
goes as it is. Otherwise it’s an estimate.
The version’s parts in order; positions are on their joined timeline.
object
The part’s file, fetched with the user’s authorization and range requests.
The file’s type, as it’s served (video/mp4 for a conversion; for an original, as the version’s files are).
The file’s exact size, once ready.
The file’s strong ETag, once ready, for If-Range.
A converted file’s SHA-256 in lowercase hex, to check it once fetched.
object
The version’s markers on its timeline, in order.
A part of a video’s timeline a player offers to skip. An episode has intro, recap and credits markers, a movie credits only, any other video none. Each kind comes from an admin’s marker, else, for an episode, what the server found in its season’s audio and pictures, else the file’s own chapters (a chapter whose whole name is the marker’s: Intro, Opening Credits, OP; Recap, Previously On; Credits, End Credits, ED, where it belongs and as long as one lasts).
object
What a marker skips. A later server may add kinds; skip a marker of a kind you don’t know.
Where a marker comes from: the file’s chapters, the audio its episode shares with others in its season (and, for credits, its pictures), or an admin. A later server may add sources.
Set on final credits: nothing follows them to the video’s end but, perhaps, a next episode’s preview, so up next may appear at their start.
Once ready or failed, when the server forgets it, unless deleted sooner.
Example
{ "items": [ { "quality": "original", "state": "queued", "reason": "noTracks", "delivery": "file", "tracks": [ { "type": "video", "delivery": "file", "hdr": "hdr10", "reason": "containerUnsupported" } ], "markers": [ { "kind": "intro", "source": "chapter" } ] } ]}No valid session or API key (code unauthenticated), or a failed sign-in (code invalidCredentials).
An RFC 9457 problem document. code is stable and is what clients
translate.
object
A URI naming the problem type; about:blank when only code matters.
A short English summary, for logs.
English detail for logs and developers; never internal error text.
A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.
The request ID, also in the X-Request-Id header and the server log.
For transcodeBusy and notPlayable, why. For transcodeBusy:
transcodeLimit or storageFull. For notPlayable: noTracks,
fileUnplayable, subtitleUnplayable, transcodeFailed,
keyframeIndexMissing or downloadsNotAllowed.
For fileUnplayable, the capability the file failed.
object
The declared value, lists joined by commas; absent when the client declared none.
For throttled and rateLimited, the Retry-After header’s value.
For invalidRequest, what’s wrong with which field.
object
A JSON pointer into the body, or a parameter name.
What’s wrong with a field: tooLarge for a file or list over its
size, unsupported for a file in a format the server doesn’t take,
unknownEpisodeGroup for a group:<ID> ordering TMDb doesn’t list
for the series, and notABook for a work edited with books that
isn’t one.
For streamLimit, the user’s plays, to show what is playing where.
One of the user’s plays, for the stream limit.
object
A UUIDv7.
A UUIDv7.
The name of the session or API key it was started by.
For playEnded, the admin’s words to the viewer, when they gave any.
For quotaUsed, when the quota resets, when the provider said.
Example
{ "code": "invalidRequest", "reason": "noTracks", "errors": [ { "code": "required" } ]}default
Section titled “default”A server-side failure: 500 (code internal, or transcodeFailed
for a play’s media), or 503
for something unavailable (codes providerUnavailable and
transcodeBusy, for now; notConfigured, until an admin configures
it).
An RFC 9457 problem document. code is stable and is what clients
translate.
object
A URI naming the problem type; about:blank when only code matters.
A short English summary, for logs.
English detail for logs and developers; never internal error text.
A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.
The request ID, also in the X-Request-Id header and the server log.
For transcodeBusy and notPlayable, why. For transcodeBusy:
transcodeLimit or storageFull. For notPlayable: noTracks,
fileUnplayable, subtitleUnplayable, transcodeFailed,
keyframeIndexMissing or downloadsNotAllowed.
For fileUnplayable, the capability the file failed.
object
The declared value, lists joined by commas; absent when the client declared none.
For throttled and rateLimited, the Retry-After header’s value.
For invalidRequest, what’s wrong with which field.
object
A JSON pointer into the body, or a parameter name.
What’s wrong with a field: tooLarge for a file or list over its
size, unsupported for a file in a format the server doesn’t take,
unknownEpisodeGroup for a group:<ID> ordering TMDb doesn’t list
for the series, and notABook for a work edited with books that
isn’t one.
For streamLimit, the user’s plays, to show what is playing where.
One of the user’s plays, for the stream limit.
object
A UUIDv7.
A UUIDv7.
The name of the session or API key it was started by.
For playEnded, the admin’s words to the viewer, when they gave any.
For quotaUsed, when the quota resets, when the provider said.
Example
{ "code": "invalidRequest", "reason": "noTracks", "errors": [ { "code": "required" } ]}