Speak API
BetaQuickstart
Turn a recording into a word-timed transcript, subtitle files and captioned videos with a few HTTP calls. Long-running work is asynchronous: you start it, then poll or receive a webhook.
Basics
- Base URL:
https://capxion.me/api/v1 - Authenticate every request with
Authorization: Bearer sk_live_…. Create keys under Settings → API keys. - JSON in, JSON out. Times are seconds (floats); timestamps are ISO 8601 UTC.
- Calls spend your account's credits exactly like the app: transcription is 1 credit per started 10 minutes of media, exports 1 credit per started minute of the exported range.
- The API is in beta. We avoid breaking changes, but shapes may still move; the reference always matches what this deployment serves.
From file to captions in five steps
- 1
Set your key
shellexport SPEAK_API_KEY="sk_live_..." # keep it on the server, never in a browser curl https://capxion.me/api/v1/account -H "Authorization: Bearer $SPEAK_API_KEY" - 2
Send the media
Either upload a file: ask for a signed URL, then PUT the bytes to it in one request (no Authorization header on that PUT; send the file's Content-Type)…
shellcurl -X POST https://capxion.me/api/v1/uploads \ -H "Authorization: Bearer $SPEAK_API_KEY" -H "Content-Type: application/json" \ -d '{ "filename": "harbour-walk.mp4", "content_type": "video/mp4", "size": 48211337 }' # => { "upload_id": "9a8b…", "upload_url": "https://…", "expires_at": "…" } curl -X PUT "$UPLOAD_URL" -H "Content-Type: video/mp4" --data-binary @harbour-walk.mp4 curl -X POST https://capxion.me/api/v1/projects \ -H "Authorization: Bearer $SPEAK_API_KEY" -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "upload_id": "9a8b…", "kind": "video", "format": "9:16", "style": { "template": "bold", "placement": "bottom" } }'…or point at a public HTTPS link to an audio or video file (Dropbox share links work; streaming sites don't). The project starts as
importing; transcription begins automatically once the file is in.shellcurl -X POST https://capxion.me/api/v1/projects \ -H "Authorization: Bearer $SPEAK_API_KEY" -H "Content-Type: application/json" \ -d '{ "source_url": "https://www.dropbox.com/s/abc123/harbour-walk.mp4?dl=0", "kind": "video" }' - 3
Wait for the transcript
The project response carries a
job_id. PollGET /jobs/{job_id}(or the project) every few seconds until the project's status isready, or subscribe totranscript.completed.shellcurl https://capxion.me/api/v1/jobs/$JOB_ID -H "Authorization: Bearer $SPEAK_API_KEY" # { "id": "…", "type": "transcription", "status": "processing", "progress": 0.42, "error": null, … } - 4
Fetch the transcript or subtitles
shellcurl "https://capxion.me/api/v1/projects/$PROJECT_ID/transcript" -H "Authorization: Bearer $SPEAK_API_KEY" # JSON, word timings curl "https://capxion.me/api/v1/projects/$PROJECT_ID/transcript?format=srt" -H "Authorization: Bearer $SPEAK_API_KEY" > captions.srt curl "https://capxion.me/api/v1/projects/$PROJECT_ID/transcript?format=vtt" -H "Authorization: Bearer $SPEAK_API_KEY" > captions.vttFix a word with
PUT /projects/{project_id}/transcriptand the full list of lines; subtitle files and exports use your edits. - 5
Render captioned videos
shellcurl -X POST https://capxion.me/api/v1/projects/$PROJECT_ID/exports \ -H "Authorization: Bearer $SPEAK_API_KEY" -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "presets": ["tiktok", "youtube"], "resolution": "1080p", "range_start": 12, "range_end": 42 }' # Poll each export until "completed", then download (the URL is valid for an hour) curl https://capxion.me/api/v1/exports/$EXPORT_ID -H "Authorization: Bearer $SPEAK_API_KEY"
SDKs and MCP
Typed TypeScript and Python clients (beta) wrap these calls with retries, automatic idempotency keys and wait helpers. Point them at this deployment with baseUrl / base_url set to https://capxion.me/api/v1.
import { Speak } from "@speak/sdk";
const speak = new Speak({ apiKey: process.env.SPEAK_API_KEY, baseUrl: "https://capxion.me/api/v1" });
const { upload_id } = await speak.uploads.uploadFile("./harbour-walk.mp4");
const project = await speak.projects.create({ upload_id, kind: "video" });
await speak.projects.waitUntilReady(project.id);
const srt = await speak.transcripts.get(project.id, { format: "srt" });