Skip to content

Retry play as transcode

POST
/api/v1/plays/{id}/fallback
curl --request POST \
--url https://example.com/api/v1/plays/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/fallback \
--header 'Content-Type: application/json' \
--cookie kivo_session=<kivo_session> \
--data '{ "positionMs": 1, "code": "mediaDecodeError", "detail": "example" }'

Ends the failed play and starts a new one at positionMs with the same version and tracks, transcoding everything: nothing played directly or copied, and a selected subtitle burned in rather than drawn by the client. A video transcode that was on an accelerator is on the CPU. Each track’s reason is fallback unless it already had one. The client plays the returned play, and asks once per play. When the failed play already transcoded everything on the CPU, it ends and there’s nothing else to try: 409 with code noFallback. The new play can be refused as a start is.

id
required

A UUIDv7.

string format: uuid
Media typeapplication/json
object
positionMs
required
integer
code
required

What failed.

string
Allowed values: mediaDecodeError mediaSourceError networkError unsupported
detail

The player’s own error text, for the server log.

string
<= 1000 characters

The new play and where to fetch its media.

Media typeapplication/json

A play that started, and where to fetch its media. Media URLs are relative to the API root (/api/v1/) and carry the play’s ID, which is a credential: treat them like a token.

tracks says how every choice shows. A choice without a delivery starts a new play at the current position with that track. Any other shows as its delivery says, and a subtitle shown so is reported in the heartbeat (PlayUpdate.subtitleTrackId), as is an audio track chosen inside the file. Players show the play as Direct Play when the video’s delivery is file, Direct Stream when it’s stream without transcode, and Transcode with transcode.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
versionId
required

A UUIDv7.

string format: uuid
startMs
required

Where playback starts on the version’s timeline. Seek here once metadata has loaded (Safari ignores an earlier seek).

integer
durationMs
required
integer
local
required

Whether the client is on a local network.

boolean
bitrateBps

The stream’s bitrate, a video transcode’s target or else the source’s, when known.

integer format: int64
limitBps

The bitrate cap the server sets on the play whatever quality the client picks, when one applies. A quality above it can’t be chosen.

integer format: int64
delivery
required

How a play’s media is fetched: file is the original, each part’s url with range requests; stream is the HLS playlist at url.

string
Allowed values: file stream
url
required

For file, the first part; for stream, the multivariant playlist.

string
tracks
required

Every track of the version, and the subtitle choice off.

Array<object>

One choice of a play: a track of its version, or the subtitle choice off, and how it shows.

object
trackId
required

A track’s id, or off.

string
<= 36 characters
type
required

A track’s type.

string
Allowed values: video audio subtitle
selected

True for the tracks the play shows; absent otherwise.

boolean
delivery

Absent when choosing it starts a new play.

string
Allowed values: file stream external burn none
codec

The codec it’s delivered as, such as hevc, aac or webvtt.

string
hdr

The video’s HDR as delivered; absent for SDR.

string
Allowed values: hdr10 hdr10plus hlg dolbyVision
transcode

What a transcoded track becomes.

object
width
integer
height
integer
bitrateBps
integer format: int64
channels
integer
encoder

Video only; what encodes it, the accelerator’s name as GET /api/v1/accelerators gives it, such as Intel Quick Sync (QSV), or CPU.

string
reason

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.

string
Allowed values: containerUnsupported videoCodecUnsupported videoCodecTagUnsupported videoProfileUnsupported videoLevelUnsupported videoBitDepthUnsupported videoResolutionUnsupported videoFrameRateUnsupported videoBitrateUnsupported videoRefFramesUnsupported videoInterlacedUnsupported videoAnamorphicUnsupported videoHdrUnsupported audioCodecUnsupported audioChannelsUnsupported audioSampleRateUnsupported audioBitDepthUnsupported audioProfileUnsupported subtitleCodecUnsupported trackSelectionUnsupported streamCodecUnsupported directPlayDisabled burnSubtitlesEnabled clientQualityLimit remoteQualityLimit bandwidthLimit dialogueBoost keyframeIndexMissing subtitlePreparing fallback downloadQuality
mismatch

The capability that failed: its field (such as maxLevel, codec or containers), what the client declared, and what the track has.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
index

For file, the track’s stream index, to select it in the player.

integer
url

For external, the file, relative to the API root.

string
fonts

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.

Array<string>
parts
required

The version’s parts in order; positions are on their joined timeline.

Array<object>
object
durationMs
required
integer
url

For file delivery, the original.

string
previews
object
ready
required
boolean
url

The manifest, when ready.

string
chapters
required
Array<object>
object
startMs
required
integer
endMs
required
integer
title
string
markers

The version’s markers on its timeline, in order.

Array<object>

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
kind
required

What a marker skips. A later server may add kinds; skip a marker of a kind you don’t know.

string
Allowed values: intro recap credits
startMs
required
integer
endMs
required
integer
source
required

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.

string
Allowed values: chapter fingerprint manual
final

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.

boolean
quality

The quality the play applies: the request’s settings.quality, or its settings.remoteQuality when the server counts the client as remote. Absent means auto.

object
mode
required

A quality pick: auto chosen from limits and measured bandwidth, original with no cap, limit capped at maxBitrateBps.

string
Allowed values: auto original limit
maxBitrateBps

For limit, from the fixed ladder.

integer format: int64
bandwidthBps

For auto, the client’s last measured download rate from this server; the play stays below about 80% of it.

integer format: int64
dialogueBoost

The play’s dialogue boost. Absent when the play can’t boost its dialogue: one without video or audio, or on a client without HLS. Switching it starts a new play at the same position.

object
enabled
required

Whether the play boosts its dialogue.

boolean
cost

What the boost changes besides the dialogue, the same whether it’s on or off. Absent when nothing.

string
Allowed values: audioAsAac videoTranscode

Example

{
"delivery": "file",
"tracks": [
{
"type": "video",
"delivery": "file",
"hdr": "hdr10",
"reason": "containerUnsupported"
}
],
"markers": [
{
"kind": "intro",
"source": "chapter"
}
],
"quality": {
"mode": "auto"
},
"dialogueBoost": {
"cost": "audioAsAac"
}
}

The request is malformed or a field is invalid (code invalidRequest).

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}

No valid session or API key (code unauthenticated), or a failed sign-in (code invalidCredentials).

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}

No such resource, or the caller may not see it (code notFound).

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}

The resource’s state doesn’t allow this; the code says why.

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}

An admin stopped the play (code playEnded), with their message when they gave one.

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}

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).

Media typeapplication/problem+json

An RFC 9457 problem document. code is stable and is what clients translate.

object
type
required

A URI naming the problem type; about:blank when only code matters.

string
title
required

A short English summary, for logs.

string
status
required
integer
detail

English detail for logs and developers; never internal error text.

string
instance
string
code
required

A problem’s stable code, which clients translate. A client that doesn’t know a code goes by the response’s status.

string
Allowed values: invalidRequest unauthenticated invalidCredentials wrongPassword forbidden crossOrigin denied notFound expired notReady rangeNotSatisfiable conflict alreadySetUp nameTaken lastAdmin ownUser fileStillPresent kindMismatch notStoppable streamLimit notPlayable noFallback playEnded throttled rateLimited providerUnavailable notConfigured quotaUsed transcodeBusy transcodeFailed internal
requestId
required

The request ID, also in the X-Request-Id header and the server log.

string
reason

For transcodeBusy and notPlayable, why. For transcodeBusy: transcodeLimit or storageFull. For notPlayable: noTracks, fileUnplayable, subtitleUnplayable, transcodeFailed, keyframeIndexMissing or downloadsNotAllowed.

string
Allowed values: noTracks fileUnplayable subtitleUnplayable keyframeIndexMissing transcodeFailed transcodeLimit storageFull downloadsNotAllowed sourceUnreadable subtitlesUnavailable planUnreadable
mismatch

For fileUnplayable, the capability the file failed.

object
field
required
string
declared

The declared value, lists joined by commas; absent when the client declared none.

string
actual
required
string
retryAfterSeconds

For throttled and rateLimited, the Retry-After header’s value.

integer
errors

For invalidRequest, what’s wrong with which field.

Array<object>
object
field
required

A JSON pointer into the body, or a parameter name.

string
code
required

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.

string
Allowed values: required invalid tooShort tooLong tooLarge unsupported outOfRange unknownEpisodeGroup notABook
plays

For streamLimit, the user’s plays, to show what is playing where.

Array<object>

One of the user’s plays, for the stream limit.

object
id
required

A UUIDv7.

string format: uuid
workId
required

A UUIDv7.

string format: uuid
title
required
string
clientName

The name of the session or API key it was started by.

string
startedAt
required
string format: date-time
message

For playEnded, the admin’s words to the viewer, when they gave any.

string
resetsAt

For quotaUsed, when the quota resets, when the provider said.

string format: date-time

Example

{
"code": "invalidRequest",
"reason": "noTracks",
"errors": [
{
"code": "required"
}
]
}