What this platform does
A single API-first platform for video (upload, transcode to adaptive HLS, thumbnails, transcripts, signed playback, hosted player) and delivery (multi-tenant CDN pull zones, object storage, edge functions, and edge rules). Everything in the dashboard is available over the REST API at https://api.ollanode.com.
New here? Do the five-step Quickstart, then come back for the concepts and deeper workflows below.
Core concepts
- Project
- Your tenant boundary. Every video, zone, key, and webhook belongs to one project; credentials are project-scoped, so you never see another tenant's data.
- Credentials & scopes
- Humans log in for a 12h session token; servers use long-lived API keys (
vbk_โฆ). Both carry scopes:read,write,admin. Grant the least a key needs. - Video lifecycle
created โ uploading โ processing โ ready(orfailed). Poll/v1/videos/:id/statusor subscribe to webhooks instead of busy-waiting.- Playback policy
- signed (default) needs a short-lived token per play; public is openly playable. Set it at create time or via PATCH.
- Renditions
- On ingest we build an adaptive HLS ladder (capped by
max_height, shaped byquality_preset). Players pick the best rendition automatically. - Pull zone
- A hostname mapped to an origin (or a storage zone), cached at the edge with instant purge, optional signed URLs, CORS, and rules.
- Storage zone
- An object bucket for static files; can be fronted by a pull zone for CDN delivery.
- Edge function
- JS/TS you deploy that runs in a V8 isolate at the edge, invoked at
/__fn/<id>.
Upload & stream a video
Two ways to get bytes in: remote ingest (pass source_url and we pull it) or direct upload (presigned PUT). Then poll for ready and fetch a playback URL or embed the player.
# Remote ingest โ one call, processing starts automatically
curl -X POST https://api.ollanode.com/v1/videos \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"title":"launch","source_url":"https://example.com/launch.mp4"}'
# Direct upload โ presign, PUT, complete
URL=$(curl -s -X POST https://api.ollanode.com/v1/videos/$VID/upload-url \
-H "authorization: Bearer $TOKEN" -d '{"content_type":"video/mp4"}' | jq -r .url)
curl -X PUT "$URL" -H 'content-type: video/mp4' --data-binary @launch.mp4
curl -X POST https://api.ollanode.com/v1/videos/$VID/upload-complete -H "authorization: Bearer $TOKEN" Embed the hosted player anywhere:
<iframe src="https://api.ollanode.com/embed/$VID?token=$PLAYBACK_TOKEN"
allow="fullscreen" style="border:0;width:100%;aspect-ratio:16/9"></iframe> Protect playback (signed URLs)
Signed videos require a token to play. Mint one server-side per viewer/session with GET /v1/videos/:id/playback โ the response includes a token and expires_at. Pass it to your player or the embed URL. Never ship an API key to the browser; only hand out the short-lived playback token.
curl https://api.ollanode.com/v1/videos/$VID/playback -H "authorization: Bearer $TOKEN"
# โ { "master_url": "โฆm3u8", "token": "โฆ", "policy": "signed", "expires_at": "โฆ" } CDN pull zones
Point a hostname at your origin and serve it cached. Bump TTLs, bypass cache for dynamic paths, enable CORS, protect against hotlinking with signed URLs, and purge โ instantly (full) or by exact path (granular).
# create a zone
curl -X POST https://api.ollanode.com/v1/zones \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"hostname":"cdn.you.com","origin_url":"https://origin.you.com","default_ttl_secs":3600,"cors":"*"}'
# granular purge
curl -X POST https://api.ollanode.com/v1/zones/$ZID/purge \
-H "authorization: Bearer $TOKEN" -d '{"paths":["/app.js","/index.html"]}' Point your hostname's DNS (CNAME) at the edge, then watch live requests / egress / hit-ratio on the zone detail page.
Storage zones
Buckets for static assets. Upload with a presigned PUT, list/delete files, and serve globally by attaching a pull zone (storage_zone_id) so the CDN caches your bucket.
SZ=$(curl -s -X POST https://api.ollanode.com/v1/storage-zones \
-H "authorization: Bearer $TOKEN" -d '{"name":"assets"}' | jq -r .id)
URL=$(curl -s -X POST https://api.ollanode.com/v1/storage-zones/$SZ/upload-url \
-H "authorization: Bearer $TOKEN" -d '{"path":"/logo.png","content_type":"image/png"}' | jq -r .url)
curl -X PUT "$URL" -H 'content-type: image/png' --data-binary @logo.png
# serve it via CDN
curl -X POST https://api.ollanode.com/v1/zones -H "authorization: Bearer $TOKEN" \
-d '{"hostname":"assets.you.com","storage_zone_id":"'$SZ'"}' Edge rules
Attach ordered rules to a zone. They run at the edge in order: a matching block or redirect stops the request; set_header adds a response header. Edit them on the zone detail page or via PATCH.
curl -X PATCH https://api.ollanode.com/v1/zones/$ZID \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"rules":[
{"prefix":null,"action":{"type":"set_header","name":"X-Frame-Options","value":"DENY"}},
{"prefix":"/old","action":{"type":"redirect","status":301,"location":"https://you.com/new"}},
{"prefix":"/private","action":{"type":"block"}}
]}' Edge functions
Deploy JavaScript/TypeScript that runs in a V8 isolate at the edge. Write a standard Deno.serve(handler); we route /__fn/<id> to it. Edit + deploy live on the Functions page, or via the API.
curl -X POST https://api.ollanode.com/v1/functions \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"name":"hello","code":"Deno.serve((req)=>new Response(JSON.stringify({ok:true,url:req.url}),{headers:{\"content-type\":\"application/json\"}}))"}'
# โ invoke:
curl https://api.ollanode.com/__fn/$FN_ID Webhooks
React to events instead of polling. Each delivery is signed with an HMAC of the body using your webhook secret (shown once at creation) in the X-Signature header โ verify it before trusting the payload. Failed deliveries retry with backoff; inspect them under the webhook's deliveries.
Events: video.asset.ready, video.asset.errored, video.asset.processing, video.asset.created, video.asset.thumbnail.ready, video.asset.track.ready, transcript.ready.
curl -X POST https://api.ollanode.com/v1/webhooks \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"url":"https://you.com/hooks/video","events":["video.asset.ready","video.asset.errored"]}'
# โ { "id": "...", "secret": "whsec_..." } (verify X-Signature = HMAC-SHA256(secret, body)) Errors & limits
- 2xx success ยท 400 validation ยท 401 missing/invalid credential ยท 403 wrong scope or not your resource ยท 404 not found ยท 429 rate-limited.
- Errors return JSON
{ "error": { "message": "โฆ" } }. - Rate limits are per-credential; on
429, back off and retry. - Secrets (API keys, webhook secrets, zone signing secrets) are shown once โ store them immediately; rotate via the respective endpoint.
- IDs are prefixed by type (e.g.
vid_โฆ,zone_โฆ,fn_โฆ,stz_โฆ) โ treat them as opaque strings.
Full endpoint list with bodies & responses: API Reference โ