Skip to main content

Python SDK

Install and use the official videas-sdk Python client to call the Videas External API from your backend, with zero dependencies.

videas-sdk is the official Python client for the Videas External API. It wraps every endpoint in a small, resource-grouped client so you don’t have to build URLs, set headers or parse responses by hand. It uses only the Python standard library — no third-party dependency — and works on Python 3.9+.

Installation

pip install videas-sdk
# or: uv add videas-sdk

Quick start

Create a client with your organization’s API key, then call any resource:

from videas_sdk import VideasClient

client = VideasClient(api_key="sk_your_key_here")

# List the "ready" videos in your organization
page = client.videos.list(status="ready", limit=50)
print(page["count"], "videos")
for video in page["results"]:
    print(video["uid"], video["name"])

You create an API key from Settings → API keys — see Creating an API key. The key both identifies the organization the client acts on and defines the scopes it may use.

Authentication

The key you pass to VideasClient is sent as a Bearer token on every request. Each client is bound to one key, so you can create several clients with different keys in the same process.

Client options: timeouts & retries

Besides api_key, VideasClient also accepts:

  • timeout — per-request timeout in seconds (None, the default, means no timeout). Applies to every request, including the upload transfer.
  • retries — retry idempotent (GET/HEAD) requests this many extra times on connection errors or 429/503, with a short back-off. Mutating calls (create/update/delete/upload) are never retried.
client = VideasClient(
    api_key="sk_your_key_here",
    timeout=10,   # seconds
    retries=2,
)

Working with videos

Every method returns the parsed JSON body (a dict), or raises on error.

# Get one video
video = client.videos.get("vid_123")

# Update editorial fields (partial — pass only what changes)
client.videos.update("vid_123", name="Onboarding — v2", tags=["onboarding"])

# Delete (moves it to the trash)
client.videos.delete("vid_123")

# Player metadata + a signed playback token
player = client.videos.get_player("vid_123")

videos.list() accepts the same filters as the REST endpoint: search, status, tag, created_after, created_before, ordering, plus limit (1–100) and offset.

Other resources

# Assets — every media type (video, audio, image, document)
client.assets.list(limit=20)
client.assets.get("ast_123")

# Folders inside a workspace
client.folders.list("ws_123")
client.folders.create("ws_123", name="Courses")
client.folders.update("ws_123", "fld_1", name="Archived courses")
client.folders.delete("ws_123", "fld_1")

# Workspaces and their embed-domain settings
client.workspaces.list()
client.workspaces.get_embed_settings("ws_123")
client.workspaces.add_embed_domain("ws_123", domain="example.com")

URL fields are absolute. Response fields like thumbnail_url come back as fully-qualified URLs, resolved against the Videas API base URL — use them directly, no host to prefix.

Resolving playback URLs

Playback is a two-step flow: get a signed token from the player endpoint, then exchange it for the actual stream URLs. The resolve_playback helper does both in one call:

info = client.videos.resolve_playback("vid_123")
print(info["hls_url"])  # signed, time-limited HLS URL

assets.resolve_playback(uid) does the same for any asset type. Prefer these helpers; if you need the token itself, run the two steps by hand:

player = client.videos.get_player("vid_123")
info = client.playback.resolve(
    asset_id="vid_123",
    playback_token=player["playback_token"],
)

Uploading a file

upload.upload_file() handles the whole resumable (TUS) flow: it creates the session and transfers the bytes, then returns the created asset metadata (including asset_uid, available immediately).

with open("intro.mp4", "rb") as fh:
    data = fh.read()

created = client.upload.upload_file(
    workspace_uid="ws_123",
    filename="intro.mp4",
    data=data,
    content_type="video/mp4",
    asset_name="Onboarding intro",       # optional
    parent_folder_uid="fld_1",           # optional — defaults to the workspace root
)
print("New asset:", created["asset_uid"])

Large files & progress

The byte transfer is chunked automatically — 32 MiB per request by default, safely under the server’s 50 MiB per-chunk limit — so multi-gigabyte videos upload with no extra work. Tune the chunk size and follow progress:

client.upload.upload_file(
    workspace_uid="ws_123",
    filename="lecture.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)}%"),
)

Need to drive the transfer yourself? upload.create_session(headers=...) exposes the low-level session-creation call.

Error handling

Any non-2xx response raises VideasAPIError, which carries the HTTP status, the machine-readable code and the parsed error body:

from videas_sdk import VideasAPIError

try:
    client.videos.get("does-not-exist")
except VideasAPIError as err:
    print(err.status)  # 404
    print(err.code)    # "NOT_FOUND"
    print(err)         # human-readable message

See the REST API guide for the full list of status codes.

Current limitations

  • No cross-call resume yet. upload.upload_file() uploads in chunks, 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 against upload.create_session() — see Upload with the REST API.

Next steps