Videos
The video object
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier for the object. |
| project_id | string | |
| folder_id | string | |
| version | number | |
| title | string | |
| description | string | |
| status | enum | Available values: pending, uploading, pre-processing, processing, aborted, done, error |
| progress | number | Video processing progress |
| duration | number | Video duration in seconds |
| assets | []Asset | |
| has_audio | bool | Whether the video has any audio. |
| audio_tracks | []AudioTrack | Downloadable audio tracks (id, language, label, file_size, filetype, original_name, download_link). Omitted when the video has no audio tracks. |
| chapters | Chapters | |
| privacy_type | enum | Available values: anywhere, nowhere, custom |
| privacy_domains | []string | Whitelist domains |
| poster | Poster | |
| additional_materials | []AdditionalMaterial | |
| additional_materials_enabled | bool | |
| annotation_text_enabled | bool | |
| annotation_video_enabled | bool | |
| created_at | datetime | |
| updated_at | datetime | |
| play_link | string | Link to player |
| embed_link | string | Embed player link |
| subtitles | Subtitles | |
| subtitles_enabled | boolean | Show/Hide subtitles in player |
| hls_link | string | Link to HLS manifest |
Concat video
https://api.kinescope.io/v1/videos/:video_id/concatConcatenates the source video with one or more other videos into a single new video. The original video is left unchanged and a new video is created with the combined content.
{
"prepend": [
{
"video_id": "<UUID>"
}
],
"append": [
{
"video_id": "<UUID>"
}
],
"replace": false
}Copy video
https://api.kinescope.io/v1/videos/:video_id/copyCreates a full copy of the video, optionally moving the copy into a different project or folder.
{
"parent_id": "<UUID>"
}Cut video
https://api.kinescope.io/v1/videos/:video_id/cutTrims the video to a given time range. The result is written back to the same video ID; the original bytes are replaced.
Create new trim/crop video.
| Field | Type | Description |
|---|---|---|
| project_id | string | not required |
| folder_id | string | not required |
| title | string | not required |
| description | string | not required |
| crop | crop_object | w, h — width, height; x, y — left top corner |
| trim | []trim_object | start — start time; length — length of video |
{
"crop": {
"w": 300,
"h": 200,
"x": 100,
"y": 80,
"quality": "360p"
},
"trim": [
{
"start": 6,
"length": 2
},
{
"start": 1,
"length": 2
}
]
}Videos list
https://api.kinescope.io/v1/videosReturns a list of videos. Results are paginated and can be filtered via query parameters.
{
"meta": {
"pagination": {
"page": 1,
"per_page": 1,
"total": 10
},
"order": {
"created_at": "desc",
"title": "asc"
}
},
"data": [
{
"id": "vKSxQyZScoQfP29oothREi",
"project_id": "mNFQz2wYTBhLkPBCo9oS8m",
"folder_id": null,
"version": 0,
"title": "sample_video",
"description": "",
"status": "uploading",
"progress": 100,
"duration": 0,
"assets": [],
"chapters": {
"items": [],
"enabled": false,
"show_on_load": false
},
"privacy_type": "anywhere",
"privacy_domains": [],
"poster": null,
"additional_materials": null,
"additional_materials_enabled": false,
"play_link": "https://kinescope.io/199511994",
"embed_link": "https://kinescope.io/embed/199511994",
"created_at": "2020-08-31T09:03:00.106436Z",
"updated_at": null,
"subtitles": [],
"subtitles_enabled": false,
"hls_link": "https://kinescope.io/199511994/master.m3u8"
}
]
}Get video
https://api.kinescope.io/v1/videos/:video_idRetrieves the details of a single video by its unique ID.
{
"data": {
"id": "<UUID>",
"project_id": "<UUID>",
"folder_id": null,
"player_id": "<UUID>",
"version": 1,
"title": " Encrypted, saved (2024.09.08 13:35)",
"subtitle": "",
"description": "",
"status": "done",
"progress": 0,
"duration": 66.00001,
"assets": [
{
"id": "<UUID>",
"video_id": "<UUID>",
"original_name": "original.ts",
"file_size": 4862244,
"md5": "a05d6c66884dc7f8c5136b6c9d95fef7",
"filetype": "ts",
"quality": "original",
"resolution": "1920x1080",
"created_at": "2024-09-08T10:35:17.087638Z",
"url": "https://kinescopecdn.net/<UUID>/videos/<UUID>/assets/<UUID>/original.mp4?expires=<EXPIRES>&sign=<SIGNATURE>",
"download_link": "https://s3.kinescope.io/<UUID>/videos/<UUID>/mp4/original.ts?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<CREDENTIAL>"
},
{
"id": "<UUID>",
"video_id": "<UUID>",
"original_name": "1080p.mp4",
"file_size": 4292636,
"filetype": "mp4",
"quality": "1080p",
"resolution": "1920x1080",
"created_at": "2024-09-08T10:35:30.549646Z",
"download_link": ""
},
{
"id": "<UUID>",
"video_id": "<UUID>",
"original_name": "720p.mp4",
"file_size": 3217594,
"filetype": "mp4",
"quality": "720p",
"resolution": "1280x720",
"created_at": "2024-09-08T10:35:30.549646Z",
"download_link": ""
},
{
"id": "<UUID>",
"video_id": "<UUID>",
"original_name": "480p.mp4",
"file_size": 2031032,
"filetype": "mp4",
"quality": "480p",
"resolution": "852x480",
"created_at": "2024-09-08T10:35:30.549646Z",
"download_link": ""
},
{
"id": "<UUID>",
"video_id": "<UUID>",
"original_name": "360p.mp4",
"file_size": 1451443,
"filetype": "mp4",
"quality": "360p",
"resolution": "640x360",
"created_at": "2024-09-08T10:35:30.549646Z",
"download_link": ""
}
],
"has_audio": true,
"audio_tracks": [
{
"id": "<UUID>",
"language": "en",
"label": "English",
"file_size": 4292636,
"filetype": "mp4",
"original_name": "audio_en.mp4",
"download_link": "https://s3.kinescope.io/<UUID>/videos/<UUID>/audio/<UUID>.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<CREDENTIAL>"
},
{
"id": "<UUID>",
"language": "ru",
"label": "Русский",
"file_size": 4185220,
"filetype": "mp4",
"original_name": "audio_ru.mp4",
"download_link": "https://s3.kinescope.io/<UUID>/videos/<UUID>/audio/<UUID>.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<CREDENTIAL>"
}
],
"chapters": {
"items": [],
"enabled": false
},
"privacy_type": "anywhere",
"privacy_domains": [],
"privacy_email_domains": [],
"privacy_share": {},
"tags": [],
"poster": {
"id": "<UUID>",
"type": "image",
"media_id": "<UUID>",
"status": "done",
"active": true,
"original": "https://kinescopecdn.net/<UUID>/posters/<UUID>/<UUID>.jpg",
"md": "https://kinescopecdn.net/<UUID>/posters/<UUID>/md/<UUID>.jpg",
"sm": "https://kinescopecdn.net/<UUID>/posters/<UUID>/sm/<UUID>.jpg",
"xs": "https://kinescopecdn.net/<UUID>/posters/<UUID>/xs/<UUID>.jpg",
"from_time": 0,
"to_time": 0
},
"additional_materials": [],
"additional_materials_enabled": false,
"annotation_text_enabled": false,
"annotation_video_enabled": false,
"play_link": "https://kinescope.io/vN1xLXadcCk94aCuZHR5i2",
"embed_link": "https://kinescope.io/embed/vN1xLXadcCk94aCuZHR5i2",
"created_at": "2024-09-08T10:35:11.674333Z",
"updated_at": "2026-03-05T14:04:37.150678Z",
"subtitles": [],
"subtitles_enabled": false,
"hls_link": "https://kinescope.io/vN1xLXadcCk94aCuZHR5i2/master.m3u8",
"chat_preview": false,
"chat_inside_player": "",
"chat_expand_on_load": false,
"meta": {
"event_id": "<UUID>",
"stream_id": "<UUID>"
}
}
}{
"error": {
"code": 400404,
"message": "not found"
}
}Move video to another project and folder
https://api.kinescope.io/v1/videos/:video_id/moveMoves the video into a different project and/or folder. The video ID stays the same.
{
"project_id": "3kAyiWTAZQKKZxg1GfjKvS",
"folder_id": "2MxB8wx35jHQjhCPczBamu"
}Update chapters
https://api.kinescope.io/v1/videos/:video_id/chaptersReplaces the chapter markers of the video with the provided list. Pass an empty array to clear all chapters.
{
"items": [
{
"time": 10000,
"title": "Chapter at 10sec"
}
],
"enabled": true
}{
"data": {
"items": [
{
"time": 10000,
"title": "Chapter at 10sec"
}
],
"enabled": true
}
}Update video
https://api.kinescope.io/v1/videos/:video_idUpdates the specified video. Only fields provided in the request body are changed; others are left unchanged.
This request update only passed fields.
Fields which can update: title, description, privacy_type, privacy_domains, additional_materials_enabled
{
"title": "New title",
"description": "New description",
"privacy_type": "custom",
"privacy_domains": [
"example.com"
],
"additional_materials_enabled": false,
"tags": [
"tag 1",
"tag 2",
"tag 3"
]
}{
"data": {
"id": "iuFPEzdC2Jtf8aCcvMJQ8h",
"workspace_id": "s8vL2Zr3CxCj1A8HmxoGhp",
"project_id": "hfHfAgq4g2nxxtg8DQ3Twi",
"folder_id": null,
"storage_id": "mucjva43n3sLsw5YRwsZYS",
"short_id": 199511990,
"version": 0,
"title": "New title",
"description": "New description",
"status": "done",
"progress": 0,
"duration": 179.305,
"assets": [
{
"id": "i7r58w3Lt3bPoPyX27tprT",
"video_id": "iuFPEzdC2Jtf8aCcvMJQ8h",
"original_name": "original.mp4",
"file_size": 5603249,
"filetype": "QuickTime / MOV",
"quality": "original",
"resolution": "320x240",
"created_at": "2020-08-30T16:10:08.091561Z",
"updated_at": null,
"deleted_at": null
},
{
"id": "kdwSHkB2e1AH8veDLuCnUP",
"video_id": "iuFPEzdC2Jtf8aCcvMJQ8h",
"original_name": "360p.mp4",
"file_size": 4196287,
"filetype": "QuickTime / MOV",
"quality": "360p",
"resolution": "320x240",
"created_at": "2020-08-30T16:10:14.087606Z",
"updated_at": null,
"deleted_at": null
}
],
"chapters": {
"items": [],
"enabled": false,
"show_on_load": false
},
"privacy_type": "custom",
"privacy_domains": [
"example.com"
],
"poster": {
"id": "eHqAqKuMi4JTsAoMvf5GRs",
"video_id": "iuFPEzdC2Jtf8aCcvMJQ8h",
"storage_id": "mucjva43n3sLsw5YRwsZYS"
},
"additional_materials": [],
"additional_materials_enabled": false,
"created_at": "2020-08-30T16:10:05.702154Z",
"updated_at": null,
"deleted_at": null
}
}Delete video
https://api.kinescope.io/v1/videos/:video_idPermanently deletes the video. This action cannot be undone.
{
"data": {
"success": true
}
}Videos
Create upload session
https://uploader.kinescope.io/v2/initCreates an upload session and returns the address the file is sent to. Use it when the file is large, the network is unreliable, or the upload happens in a browser you do not want to hand the API token to: the address itself authorises the upload.
The returned endpoint is geo-routed — https://eu-ams-uploader-1.kinescope.io/v2/upload/… — so send the file exactly there, do not rebuild the URL from the base host.
| Parameter | Type | Description |
|---|---|---|
type | enum | Required. video, attachment or replace. |
parent_id | uuid | Required for type: video. Project or folder the video lands in. Get it from GET /v1/projects or GET /v1/projects/:project_id/folders. |
title | string | Required for type: video. Video title. |
video_id | uuid | Required for type: attachment. The video the material is attached to. |
filesize | integer | Required for tus. File size in bytes. Drives the progress indicator. |
filename | string | File name. Informational. |
subtitle | string | Video subtitle. |
description | string | Video description. |
client_ip | string | End-client IP address. Picks the closest upload server. |
preview | object | Creates a preview clip available at https://kinescope.io/{video_id}/preview. Fields: start and length in seconds, quality — 360p, 480p, 720p or 1080p. |
The parameter set for type: replace is not described in the guide and requires confirmation.
{
"type": "video",
"parent_id": "e51e55a1-7615-493e-9055-10ac9cc44ccd",
"title": "Product demo",
"filename": "demo.mp4",
"filesize": 48622440
}{
"data": {
"id": "7127f2d7-0e96-40d0-9a03-2e987c096466",
"endpoint": "https://eu-ams-uploader-1.kinescope.io/v2/upload/0966958f-638b-4aab-bf4a-7f9860a57a93"
}
}Step 2: send the file to the returned address
The address from data.endpoint accepts both a plain POST with the file in the body and the tus protocol. The access token is not sent on this step — the address itself is the permission.
curl -X POST \
'https://eu-ams-uploader-1.kinescope.io/v2/upload/0966958f-638b-4aab-bf4a-7f9860a57a93' \
--data-binary '@demo.mp4'For resumable uploads use a tus client library: it sends HEAD to read the current Upload-Offset and continues with PATCH from that byte, receiving 204 No Content with the new offset after every chunk. A plain POST has no resume — after a drop the upload starts from zero.
How long the returned address stays valid is not documented and requires confirmation. The threshold above which tus becomes mandatory is not documented either.
Upload video
https://uploader.kinescope.io/v2/videoUploads a video in a single request. Metadata goes in headers, the file goes in the body — or, with the X-Video-URL header, the body stays empty and Kinescope downloads the file itself.
Use it for small files on a stable connection and for imports from your own storage. For large files use POST /v2/init and tus: this endpoint has no resume, and a dropped connection means starting over.
| Parameter | Type | Description |
|---|---|---|
X-Parent-ID | uuid | Required. Project or folder the video lands in. |
X-Video-Title | string | Required. Video title. |
X-Video-URL | string | Required for URL upload. Direct link to the file, or a YouTube address of the form https://www.youtube.com/watch?v=… or https://youtu.be/…. With this header the request body stays empty. |
X-Video-Description | string | Video description. |
X-File-Name | string | File name. |
X-Replace-Video-ID | uuid | Video to replace. Whether the identifier, metadata and links survive the replacement is not documented and requires confirmation. |
X-Video-Trim | json | Trim on upload, values in seconds: {"start": 1, "length": 2}. Without length the video is trimmed from start to the end. |
Content-Type | string | Type of the data in the body, for example video/mp4. |
X-Poster-URL appears in the previous version of this page but not in the developer guide: its support requires confirmation.
The body format is described as multipart in the previous version of this page, while the guide passes the file as a raw body. Maximum file size for this endpoint is not published. Both require confirmation.
{
"data": {
"id": "8d1c4b7e-2f39-4a06-b5c8-71e0a9d3f462",
"project_id": "3f2a9c14-7b6d-4e58-9a21-0c5e8d47b193",
"title": "Product demo",
"status": "uploading",
"progress": 0,
"play_link": "https://kinescope.io/bK3mQx7ZtNvRs2WdYpLc9F"
}
}After the upload
A finished upload does not mean a ready video. Poll GET /v1/videos/{video_id} by the identifier returned at the first step, no more than once every 5 seconds, or subscribe to the media.update.status webhook. Terminal statuses are done, error and aborted; progress is not a readiness signal.
If the file behind X-Video-URL is unreachable, the video ends up in status: error and the reason arrives in the webhook payload.
Repeating a POST after a timeout creates a second video: Idempotency-Key is not supported. Before retrying, look the video up with GET /v1/videos filtered by project and title, or replace the failed attempt through X-Replace-Video-ID.