API overview

The Tellers API lets you integrate video creation, assets, and workflows into your applications. Use it to manage sources, trigger exports, and build custom pipelines.

What you can do

  • Manage sources and files — List and organize files in your sources.
  • Work with assets — Upload, complete multipart uploads, and manage media assets.
  • Control exports — Trigger server-side export and rendering jobs and monitor their status.
  • Authenticate — Use API keys or OAuth to secure your requests.

Creating your API token

To use the API or the CLI, you need an API key. Create one from the app:

  1. Go to app.tellers.ai.
  2. Click your user menu (top right).
  3. Open API keys.
  4. Click Create new and copy your key.

Credits

You need credits on your account before using the API or CLI. All actions made through the API or CLI using your API token consume credits based on the requests (uploads, exports, etc.). Purchase credits on app.tellers.ai. New users who sign in with Google SSO receive a small amount of free credits to get started.

Getting started

Use the API reference for full endpoint details, request/response schemas, and try-it-out. All endpoints are documented in OpenAPI 3.1 format.

Examples

Generate a video from a prompt

The simplest way to create a video: send a prompt and stream the result. No file upload needed — the agent uses stock footage and resources available to it. The GET /create endpoint returns a Server-Sent Events stream; listen for tellers.json_result events.

import json, urllib.parse
import requests
import sseclient  # pip install sseclient-py requests

API_KEY = "sk_..."
BASE    = "https://api.tellers.ai"

prompt = (
    "Make me a video showing 10 seconds shots of nature "
    "with a peaceful music. Use stock footage."
)

url      = f"{BASE}/create?prompt={urllib.parse.quote(prompt)}"
response = requests.get(url, headers={"x-api-key": API_KEY}, stream=True)
response.raise_for_status()

for event in sseclient.SSEClient(response).events():
    if event.event == "tellers.json_result":
        data = json.loads(event.data)
        print(data)
        if data.get("status") == "done":
            break

Upload a file

Uploading a file is a two-step process: first request a presigned upload URL, then PUT your file directly to it.

import os, uuid, time
import requests  # pip install requests

API_KEY = "sk_..."
BASE    = "https://api.tellers.ai"
headers = {"x-api-key": API_KEY}

# Step 1 — request a presigned upload URL
file_path = "footage/interview.mp4"
file_size = os.path.getsize(file_path)

resp = requests.post(
    f"{BASE}/users/assets/upload_urls",
    headers=headers,
    json=[{
        "upload_id":      str(uuid.uuid4()),
        "content_length": file_size,
        "file_type":      "video",
        "source_file": {
            "sourceName":       "local",
            "sourceUrl":        None,
            "sourceIconUrl":    None,
            "authors":          [],
            "creationDatetime": None,
            "additionDatetime": int(time.time()),
            "inAppPath":        ["footage"],
            "title":            "interview.mp4",
            "description":      None,
            "keywords":         [],
        },
    }],
)
resp.raise_for_status()
upload   = resp.json()[0]
asset_id = upload["asset_id"]

# Step 2 — PUT the file directly to the presigned URL (no auth header needed)
with open(file_path, "rb") as f:
    requests.put(upload["presigned_put_url"], data=f).raise_for_status()

print(f"Uploaded as asset {asset_id}")

Generate a video with an uploaded file

Once your file is uploaded, reference it in your prompt by its asset ID (returned by POST /users/assets/upload_urls) or by its filename. Using the asset ID is more reliable — filenames may not be unique.

import json, urllib.parse
import requests
import sseclient  # pip install sseclient-py requests

API_KEY = "sk_..."
BASE    = "https://api.tellers.ai"

# After uploading (see "Upload a file" above), reference the asset
# by its ID (preferred) or by its filename in your prompt.
asset_id = "asset_abc123"  # returned by /users/assets/upload_urls

prompt = (
    f"Using asset ID {asset_id} (interview.mp4): "
    "add a title card at the start that says 'Product Demo', "
    "then cut to the best 60 seconds."
)

url      = f"{BASE}/create?prompt={urllib.parse.quote(prompt)}"
response = requests.get(url, headers={"x-api-key": API_KEY}, stream=True)
response.raise_for_status()

for event in sseclient.SSEClient(response).events():
    if event.event == "tellers.json_result":
        data = json.loads(event.data)
        print(data)
        if data.get("status") == "done":
            break

CLI

We provide a command-line interface for common operations. Use it for scripts, CI/CD, or local workflows.

For the complete list of endpoints and parameters, see the API reference.