API

Everything in the app is an API. Authenticate with an API key and drive projects, clips, and downloads programmatically.

Authentication

Create a key in Settings → API keys (shown once — store it safely) and send it on every request:

curl https://your-deployment/api/usage \
  -H "x-api-key: YOUR_KEY"

Core endpoints

Method & pathWhat it does
POST /api/projects/uploadsCreate a project + direct-upload URL. PUT your file to uploadUrl, then…
POST /api/projects/:id/uploadedTell the pipeline the upload finished (starts analysis).
POST /api/projects/importsImport by URL: { "url": "…", "contentType": "podcast" }
GET /api/sessionsList projects (analyses).
GET /api/sessions/:id/progressHonest pipeline stage snapshot (SSE stream at …/progress/stream).
POST /api/sessions/:id/cancelCancel an in-flight analysis.
POST /api/sessions/:id/retryRe-run a failed/cancelled analysis.
GET /api/clips?sort=scoreList clips (cursor pagination via nextCursor).
PATCH /api/clips/:idStudio edits: title, caption, startTs/endTs, captionPreset.
POST /api/clips/:id/rerenderRe-render the short at the current edits.
GET /api/clips/:id/downloadSigned MP4 download URL (expires; request per download).
GET /api/usagePlan, minutes used/included, period reset.

Example: URL import to downloaded short

# 1. Import
PROJECT=$(curl -s -X POST https://your-deployment/api/projects/imports \
  -H "x-api-key: $KEY" -H "content-type: application/json" \
  -d '{"url":"https://www.twitch.tv/videos/123456789","contentType":"gaming"}' \
  | jq -r .id)

# 2. Poll progress until the stages finish
curl -s https://your-deployment/api/sessions/$PROJECT/progress -H "x-api-key: $KEY"

# 3. List the project's clips
curl -s "https://your-deployment/api/clips?sessionId=$PROJECT&sort=score" \
  -H "x-api-key: $KEY"

# 4. Fetch a signed download URL
curl -s https://your-deployment/api/clips/CLIP_ID/download -H "x-api-key: $KEY"

Conventions & limits

TopicBehavior
ErrorsStandard HTTP codes with a JSON body: { "message": "human-readable reason" }.
ValidationUnknown fields are stripped; invalid fields return 400 with details.
Rate limitingPer-key limits apply (configurable per key); 429 when exceeded.
Plan gatesThe same minute/concurrency/clip-cap rules as the UI — expect 400s with the limit named.
Signed URLsPlayback and download URLs expire; re-request rather than storing them.
The API surface is the same one the web app uses — it's exercised by the full test suite on every change. An MCP server is also available for agent integrations; see the repository README.