The official SDKs turn the whole resumable upload flow
into a single call: uploadFile (JavaScript) / upload_file (Python). They
create the session, split the file into chunks, transfer them in order, and
report progress — so large videos just work.
The one call
JavaScript / TypeScript (@videas/sdk)
import { createVideasClient } from '@videas/sdk'
const videas = createVideasClient({ apiKey: process.env.VIDEAS_API_KEY! })
const created = await videas.upload.uploadFile({
workspaceUid: 'ws_123',
filename: 'lecture.mp4',
data: bytes, // a Blob/File, ArrayBuffer, or typed array
contentType: 'video/mp4', // optional
})
console.log('New asset:', created.asset_uid)
Python (videas-sdk)
from videas_sdk import VideasClient
client = VideasClient(api_key="sk_your_key_here")
with open("lecture.mp4", "rb") as fh:
created = client.upload.upload_file(
workspace_uid="ws_123",
filename="lecture.mp4",
data=fh.read(),
content_type="video/mp4",
)
print("New asset:", created["asset_uid"])
Optional fields: assetName / asset_name, description, and
parentFolderUid / parent_folder_uid (upload into a folder instead of the
workspace root).
Large files & progress
The transfer is chunked automatically — 32 MiB per request by default, well under the server’s 50 MiB per-chunk limit — so multi-gigabyte files upload without any extra work. Tune the chunk size and follow progress:
await videas.upload.uploadFile({
workspaceUid: 'ws_123',
filename: 'movie.mp4',
data: bytes,
chunkSize: 16 * 1024 * 1024, // optional — default 32 MiB, must stay ≤ 50 MiB
onProgress: (sent, total) => console.log(`${Math.round((sent / total) * 100)}%`),
})
client.upload.upload_file(
workspace_uid="ws_123",
filename="movie.mp4",
data=data,
chunk_size=16 * 1024 * 1024, # optional — default 32 MiB, must stay <= 50 MiB
on_progress=lambda sent, total: print(f"{round(sent / total * 100)}%"),
)
From the browser
uploadFile needs your secret sk_ key, so run it on your server — never
ship the key to a browser. For browser uploads, have your server mint the upload
session and let the browser send the bytes to the returned capability URL (no
key required): see
Resumable uploads with a TUS client.
From a server (Node)
import { readFile } from 'node:fs/promises'
const bytes = await readFile('movie.mp4')
await videas.upload.uploadFile({ workspaceUid: 'ws_123', filename: 'movie.mp4', data: bytes })
Wait until the asset is ready
uploadFile resolves with the created metadata (including asset_uid)
immediately — the video is then processed asynchronously. Poll until it’s
ready before playing or embedding:
let asset = await videas.assets.get(created.asset_uid!)
while (asset.status !== 'ready' && asset.status !== 'error') {
await new Promise((r) => setTimeout(r, 3000))
asset = await videas.assets.get(created.asset_uid!)
}
Error handling
Any failure throws a typed VideasApiError (JS) / VideasAPIError (Python)
carrying the HTTP status, code and body. If you set chunkSize above the
server limit you’ll get a clear “chunk too large” message naming the
50 MiB per-chunk limit — lower
the chunk size (or just omit it and use the default).
Limitations
- No cross-call resume yet. The upload is chunked, but an interrupted call restarts from the first chunk; resuming a partially-uploaded session isn’t exposed yet. For custom resume logic, drive the transfer with a TUS client — see Upload with the REST API.