Uploads Slicer API upload endpoints — create an upload, send the file whole, in parts or via a one-time link, import from a URL, check the status and cancel.
On this page An upload is a video, photo or audio file a montage is built from. First the upload is created (createUpload), then the
file is sent in one of the ways, and after the check the status becomes ready. How to choose a way and handle errors —
in the guide Uploading files .
Start an upload# POST /v1/uploads
Rate limit default Returns the upload and a one-time uploadUrl. Then either PUT the whole file to uploadUrl (no token) or to /v1/uploads/{id}/content, or send 8 MiB parts to /v1/uploads/{id}/parts/{n} and call complete.
Request body CreateUploadRequest Field Type Description fileNamerequired stringFile name with extension: the type is detected by it≤ 255 sizerequired integerFile size, bytes≥ 1 mimeTypestring≤ 128 purposestringsource (default) — montage materialsource · media · music
Request Copy curl -X POST "https://api.slicer.media/v1/uploads" \
-H "Authorization: Bearer $SLICER_TOKEN " \
-H "Content-Type: application/json" \
-d '{"fileName":"interview.mp4","size":104857600}' Copy const response = await fetch ( 'https://api.slicer.media/v1/uploads' , {
method: 'POST' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
"fileName" : "interview.mp4" ,
"size" : 104857600
}),
});
const { ok , data , error } = await response. json (); Copy import os
import requests
response = requests.post(
"https://api.slicer.media/v1/uploads" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " },
json = {
"fileName" : "interview.mp4" ,
"size" : 104857600 ,
},
)
body = response.json() Response Response fields: CreatedUpload (3) Field Type Description uploadrequired UploaduploadUrlrequired string (uri)One-time URL: PUT the whole file without a token (≤ 1 h, write-only) uploadUrlExpiresAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"upload" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : null ,
"durationSec" : null ,
"width" : null ,
"height" : null ,
"hasAudio" : null
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
},
"uploadUrl" : "https://api.slicer.media/v1/…" ,
"uploadUrlExpiresAt" : "2026-10-16T09:30:00Z"
}
}
Upload the whole file by a one-time URL# PUT /v1/upload-links/{secret}
Scopes no token
Rate limit default No token: the secret in the URL is the permission. Write-only, one file, ≤ 1 h. curl -T video.mp4 <uploadUrl>
Path parameters Field Type Description secretrequired string
Request body File bytes (application/octet-stream).
Request Copy curl -X PUT "https://api.slicer.media/v1/upload-links/upl_…" \
-H "Content-Type: application/octet-stream" \
--data-binary @video.mp4 Copy import { readFile } from 'node:fs/promises' ;
const response = await fetch ( 'https://api.slicer.media/v1/upload-links/upl_…' , {
method: 'PUT' ,
headers: {
'Content-Type' : 'application/octet-stream' ,
},
body: await readFile ( 'video.mp4' ),
});
const { ok , data , error } = await response. json (); Copy import requests
with open ( "video.mp4" , "rb" ) as file :
response = requests.put(
"https://api.slicer.media/v1/upload-links/upl_…" ,
headers = { "Content-Type" : "application/octet-stream" },
data = file ,
)
body = response.json() Response Response fields: Upload (18) Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : "video" ,
"durationSec" : 42.5 ,
"width" : 1 ,
"height" : 1 ,
"hasAudio" : true
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
}
}
Upload the whole file# PUT /v1/uploads/{id}/content
Rate limit default Body — the file bytes, Content-Length must equal the declared size. The upload is completed automatically.
Path parameters Field Type Description idrequired string (uuid)
Request body File bytes (application/octet-stream).
Request Copy curl -X PUT "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content" \
-H "Authorization: Bearer $SLICER_TOKEN " \
-H "Content-Type: application/octet-stream" \
--data-binary @video.mp4 Copy import { readFile } from 'node:fs/promises' ;
const response = await fetch ( 'https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content' , {
method: 'PUT' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
'Content-Type' : 'application/octet-stream' ,
},
body: await readFile ( 'video.mp4' ),
});
const { ok , data , error } = await response. json (); Copy import os
import requests
with open ( "video.mp4" , "rb" ) as file :
response = requests.put(
"https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/content" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " , "Content-Type" : "application/octet-stream" },
data = file ,
)
body = response.json() Response Response fields: Upload (18) Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : "video" ,
"durationSec" : 42.5 ,
"width" : 1 ,
"height" : 1 ,
"hasAudio" : true
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
}
}
Upload a part# PUT /v1/uploads/{id}/parts/{n}
Rate limit upload parts Parts are numbered from 1; every part except the last is exactly partSize bytes. Parts may go in parallel and be retried.
Path parameters Field Type Description idrequired string (uuid)nrequired integer≥ 1
Request body File bytes (application/octet-stream).
Request Copy curl -X PUT "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1" \
-H "Authorization: Bearer $SLICER_TOKEN " \
-H "Content-Type: application/octet-stream" \
--data-binary @video.mp4 Copy import { readFile } from 'node:fs/promises' ;
const response = await fetch ( 'https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1' , {
method: 'PUT' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
'Content-Type' : 'application/octet-stream' ,
},
body: await readFile ( 'video.mp4' ),
});
const { ok , data , error } = await response. json (); Copy import os
import requests
with open ( "video.mp4" , "rb" ) as file :
response = requests.put(
"https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/parts/1" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " , "Content-Type" : "application/octet-stream" },
data = file ,
)
body = response.json() Response Response fields: object (2) Field Type Description partrequired integeretagrequired string
Response example Copy {
"ok" : true ,
"data" : {
"part" : 1 ,
"etag" : "string"
}
}
Complete a multipart upload# POST /v1/uploads/{id}/complete
Rate limit default Path parameters Field Type Description idrequired string (uuid)
Request Copy curl -X POST "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete" \
-H "Authorization: Bearer $SLICER_TOKEN " Copy const response = await fetch ( 'https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete' , {
method: 'POST' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
},
});
const { ok , data , error } = await response. json (); Copy import os
import requests
response = requests.post(
"https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20/complete" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " },
)
body = response.json() Response Response fields: Upload (18) Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : "video" ,
"durationSec" : 42.5 ,
"width" : 1 ,
"height" : 1 ,
"hasAudio" : true
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
}
}
Import a file by URL# POST /v1/uploads/import
Rate limit default Downloads a public https file in the background. Poll GET /v1/uploads/{id} or wait for the upload.ready webhook.
Request body ImportUploadRequest Field Type Description urlrequired string (uri)Public https URL of the file≤ 2048 fileNamestringName with extension if the URL has none≤ 255 purposestringsource · media · music
Request Copy curl -X POST "https://api.slicer.media/v1/uploads/import" \
-H "Authorization: Bearer $SLICER_TOKEN " \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/hook"}' Copy const response = await fetch ( 'https://api.slicer.media/v1/uploads/import' , {
method: 'POST' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
"url" : "https://example.com/hook"
}),
});
const { ok , data , error } = await response. json (); Copy import os
import requests
response = requests.post(
"https://api.slicer.media/v1/uploads/import" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " },
json = {
"url" : "https://example.com/hook" ,
},
)
body = response.json() Response Response fields: Upload (18) Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : "video" ,
"durationSec" : 42.5 ,
"width" : 1 ,
"height" : 1 ,
"hasAudio" : true
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
}
}
Upload status# GET /v1/uploads/{id}
Rate limit default Path parameters Field Type Description idrequired string (uuid)
Request Copy curl "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" \
-H "Authorization: Bearer $SLICER_TOKEN " Copy const response = await fetch ( 'https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20' , {
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
},
});
const { ok , data , error } = await response. json (); Copy import os
import requests
response = requests.get(
"https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " },
)
body = response.json() Response Response fields: Upload (18) Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"fileName" : "interview.mp4" ,
"purpose" : "source" ,
"origin" : "client" ,
"sizeBytes" : 104857600 ,
"status" : "uploading" ,
"partSize" : 104857600 ,
"partCount" : 13 ,
"uploadedParts" : [
1
],
"progress" : 0.5 ,
"media" : {
"kind" : "video" ,
"durationSec" : 42.5 ,
"width" : 1 ,
"height" : 1 ,
"hasAudio" : true
},
"error" : "string" ,
"createdAt" : "2026-10-16T09:30:00Z"
}
}
Cancel an upload# DELETE /v1/uploads/{id}
Rate limit default Path parameters Field Type Description idrequired string (uuid)
Request Copy curl -X DELETE "https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" \
-H "Authorization: Bearer $SLICER_TOKEN " Copy const response = await fetch ( 'https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20' , {
method: 'DELETE' ,
headers: {
Authorization: `Bearer ${ process . env . SLICER_TOKEN }` ,
},
});
const { ok , data , error } = await response. json (); Copy import os
import requests
response = requests.delete(
"https://api.slicer.media/v1/uploads/6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
headers = { "Authorization" : f "Bearer { os.environ[ 'SLICER_TOKEN' ] } " },
)
body = response.json() Response Response fields: object (2) Field Type Description idrequired string (uuid)deletedrequired boolean
Response example Copy {
"ok" : true ,
"data" : {
"id" : "6f1c2a4e-8b3d-4c1a-9e2f-3b5d7a9c1e20" ,
"deleted" : true
}
}
Schemas#
Upload
Field Type Description idrequired string (uuid)fileNamerequired stringpurposerequired stringsource · media · musicoriginrequired stringclient · import · serversizeBytesrequired integerstatusrequired stringuploading · processing · ready · failed · abortedpartSizerequired integerPart size for PUT …/parts/{n}, bytes (8 MiB) partCountrequired integeruploadedPartsrequired integer[]progressrequired number | nullImport progress 0–1 while downloading by URL0–1 mediarequired object | nullmedia.kindrequired stringvideo · image · audiomedia.durationSecrequired numbermedia.widthrequired integermedia.heightrequired integermedia.hasAudiorequired booleanerrorrequired string | nullcreatedAtrequired stringISO 8601 date-time, UTC
CreatedUpload
Field Type Description uploadrequired UploaduploadUrlrequired string (uri)One-time URL: PUT the whole file without a token (≤ 1 h, write-only) uploadUrlExpiresAtrequired stringISO 8601 date-time, UTC