Videos & ingest
The entry point to the whole pipeline: create a video record, then get bytes in by whatever path fits — direct presigned upload, S3-style multipart, resumable TUS, or a server-side pull from a URL.
Create a video
Everything starts here. Create the record, then choose an ingest path below — or pass source_url and skip uploading entirely.
/v1/videos videos:write Create the vid_… record before any bytes exist. Returns a one-time upload_token (for resumable TUS). All fields are optional: playback_policy = signed (default) | public; quality_preset = low | standard | high | av1; max_height caps the ladder; encrypt:true turns on AES-128 HLS; access_rules gates by country/referrer.
curl -X POST https://api.ollanode.com/v1/videos \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Q3 All-Hands",
"playback_policy": "signed",
"quality_preset": "high",
"max_height": 1080,
"encrypt": true,
"access_rules": { "allowed_countries": ["US","IN"] }
}' { "id": "vid_7Qk3...", "status": "created",
"playback_policy": "signed", "encrypted": true,
"quality_preset": "high", "max_height": 1080,
"upload_token": "<shown once — TUS metadata>", "chapters": [],
"created_at": "..." } - Pre-register a video and hand the client an upload target.
- Gate a video to specific countries at create time.
/v1/videos videos:write Pull-from-URL: set source_url and the platform fetches the file itself (SSRF-vetted, size-capped) and starts processing — no separate upload step. Returns immediately; the fetch runs in the background.
curl -X POST https://api.ollanode.com/v1/videos \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Imported clip","source_url":"https://cdn.example.com/master.mp4"}' - One-call import of an existing remote MP4.
- Migrate a back-catalogue by pointing at your current origin.
Lifecycle: list, get, update, delete
Standard tenant-scoped CRUD — every call is scoped to your project.
/v1/videos videos:read List videos (paginated; filter with ?library_id=). Ready videos include a short-lived presigned poster_url.
curl "https://api.ollanode.com/v1/videos?limit=20&offset=0" \
-H "Authorization: Bearer $OLLANODE_API_KEY" /v1/videos/{id} videos:read Fetch a single video with its full metadata, chapters, and access rules.
/v1/videos/{id} videos:write Update title, playback_policy, metadata, library_id (empty string detaches), or access_rules.
/v1/videos/{id} videos:delete Soft-delete the video and async-purge its storage. Agent keys get 202 {approval_id} (approval-gated).
Poll status
/v1/videos/{id}/status videos:read Cheap poll: current lifecycle state (created → upload_pending → uploaded → processing → ready | errored) plus live transcode progress (0–100). Poll this after upload instead of the full GET.
curl https://api.ollanode.com/v1/videos/vid_7Qk3.../status \
-H "Authorization: Bearer $OLLANODE_API_KEY" { "id":"vid_7Qk3...", "status":"processing", "error_reason":null, "progress":63 } Ingest A — direct presigned upload
Best for small/medium files: mint a presigned PUT, upload the whole file straight to object storage, then finalize. Bytes never pass through the API.
# 1) mint a presigned PUT URL
curl -X POST https://api.ollanode.com/v1/videos/vid_7Qk3.../upload-url \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content_type":"video/mp4"}'
# -> { "url":"https://...presigned PUT...", "source_key":"...", "expires_in":3600 }
# 2) upload the whole file to that URL
curl -X PUT --upload-file ./movie.mp4 -H "Content-Type: video/mp4" "<url>"
# 3) finalize -> starts the pipeline
curl -X POST https://api.ollanode.com/v1/videos/vid_7Qk3.../upload-complete \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" -d '{"size_bytes":52428800}' Ingest B — multipart (large files)
S3-style multipart for large or chunked uploads: begin → presign each part → complete. The complete call finalizes the object and starts the pipeline itself.
# 1) begin
curl -X POST https://api.ollanode.com/v1/videos/vid_7Qk3.../multipart \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" -d '{"content_type":"video/mp4"}'
# -> { "upload_id":"...", "source_key":"..." }
# 2) presign + PUT each part (capture the ETag from each response)
curl -X POST https://api.ollanode.com/v1/videos/vid_7Qk3.../multipart/<upload_id>/parts/1 \
-H "Authorization: Bearer $OLLANODE_API_KEY"
# -> { "url":"https://...presigned PUT for part 1..." }
# 3) complete -> starts the pipeline (no upload-complete needed)
curl -X POST https://api.ollanode.com/v1/videos/vid_7Qk3.../multipart/<upload_id>/complete \
-H "Authorization: Bearer $OLLANODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"parts":[{"part_number":1,"etag":"<etag-1>"},{"part_number":2,"etag":"<etag-2>"}]}' Ingest C — resumable (TUS)
For browser uploads that must survive flaky networks or page reloads, use the TUS protocol against tusd at /files/ (not a gateway route). Send TUS metadata videoId=<vid_…> and uploadToken=<token from create>. tusd stores the object and calls a secret-gated completion hook that binds the upload to the video via that one-time token — a wrong or absent uploadToken is silently ignored, which is what keeps uploads tenant-isolated.
tus-js-client) pointed at https://<your-host>/files/. Next: Processing & AI covers what happens after the bytes land.