Upload artwork
const url = 'https://example.com/api/v1/works/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/artwork';const form = new FormData();form.append('type', 'poster');form.append('file', 'file');
const options = {method: 'POST', headers: {cookie: 'kivo_session=<kivo_session>'}};
options.body = form;
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/v1/works/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/artwork \ --header 'Content-Type: multipart/form-data' \ --cookie kivo_session=<kivo_session> \ --form type=poster \ --form file=@fileThe image is size-checked and re-encoded before it’s stored; SVG is refused. The upload becomes the selected artwork of its type, which refreshes keep.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”A UUIDv7.
Request Bodyrequired
Section titled “Request Bodyrequired”object
An image’s role.
JPEG, PNG or WebP, up to 25 MB and 40 megapixels.
Responses
Section titled “Responses”The uploaded artwork.
object
A UUIDv7.
An image’s role.
Where an image comes from: a metadata provider, the media’s folder, or an admin’s upload.
For provider, which one.
The text’s language (ISO 639-1); absent for textless or unknown.
The original’s width in pixels, when known.
The original’s height in pixels, when known.
Fetch with GET /api/v1/images/{id}?width=….
object
A UUIDv7.
The largest stored width.
Example
{ "type": "poster", "source": "provider", "provider": "tmdb"}The request is malformed or a field is invalid (code invalidRequest).
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" } ]}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" } ]}Signed in, but this needs an admin (code forbidden); a
same-origin request (code crossOrigin); or a device code that was
denied (code denied).
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" } ]}No such resource, or the caller may not see it (code notFound).
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" } ]}