Skip to main content

Upload with the SDK

Upload files (including large videos) to Videas with the official SDKs — one call handles the resumable session, chunking and progress.

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.

Next steps