Automation API
Create captioned videos programmatically from your product or workflow.
The tscaps automation API lets you generate videos with burned-in captions programmatically. Submit a video source and a caption template, track processing progress, and download the finished video file.
All rendering and subtitle burn-in runs on our cloud infrastructure, powered by the same typography and animation engine as the tscaps Studio editor.
Building with AI coding agents?
You can equip your AI assistant (Cursor, Claude Code, GitHub Copilot, Windsurf, etc.) with the complete API specification or install our official skill:
- Full documentation dump: llms-full.txt (single markdown file containing all endpoint schemas and parameters).
- Documentation map: llms.txt (structured index per llmstxt.org).
- Official Agent Skill (
tscaps-api): Install vianpx skills add francozanardi/tscaps --skill tscaps-apior inspect SKILL.md on GitHub.
Authentication
All requests to the Automation API require an API key. Pass your secret key in the Authorization header as a Bearer token:
Authorization: Bearer TSCAPS_API_KEY
You can generate and manage keys in your API keys dashboard. Keep your keys secure and do not expose them in client-side code.
The API base URL is:
https://api.tscaps.io
Quickstart
Follow these three steps to submit your first video, track rendering progress, and retrieve the finished output.
1. Start a job
Send a POST request to /v1/automation-jobs with a publicly accessible video URL and the ID of the template you want to apply.
curl -X POST https://api.tscaps.io/v1/automation-jobs \
-H "Authorization: Bearer $TSCAPS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"videoUrl": "https://example.com/reel.mp4",
"templateId": "mira"
}'
const response = await fetch("https://api.tscaps.io/v1/automation-jobs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TSCAPS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
videoUrl: "https://example.com/reel.mp4",
templateId: "mira",
}),
});
const job = await response.json();
console.log(`Job queued: ${job.id}`);
import os
import requests
response = requests.post(
"https://api.tscaps.io/v1/automation-jobs",
headers={"Authorization": f"Bearer {os.environ['TSCAPS_API_KEY']}"},
json={
"videoUrl": "https://example.com/reel.mp4",
"templateId": "mira",
},
)
job = response.json()
print(f"Job queued: {job['id']}")
The API responds immediately with 202 Accepted and a job object:
{
"id": "9f2c48e1-5b7a-4a29-8874-9dfc8227b610",
"status": "queued",
"phase": "queued",
"templateId": "mira",
"quotedSeconds": null,
"format": "mp4",
"quality": "high",
"resolution": null,
"percent": null,
"downloadUrl": null,
"outputExpiresAt": null,
"failureReason": null,
"failureCode": null,
"settledAt": null,
"createdAt": "2026-09-12T10:11:38.000Z"
}
Direct file uploads: If your video file is stored locally or behind a private firewall, use our Direct file uploads flow to upload the binary file directly via presigned URLs.
2. Check job status
Video processing is asynchronous. Poll GET /v1/automation-jobs/:id until status resolves to succeeded or failed.
curl https://api.tscaps.io/v1/automation-jobs/9f2c48e1-5b7a-4a29-8874-9dfc8227b610 \
-H "Authorization: Bearer $TSCAPS_API_KEY"
async function waitForVideo(jobId) {
while (true) {
const response = await fetch(`https://api.tscaps.io/v1/automation-jobs/${jobId}`, {
headers: { Authorization: `Bearer ${process.env.TSCAPS_API_KEY}` },
});
const state = await response.json();
if (state.status === "succeeded") {
return state.downloadUrl;
}
if (state.status === "failed") {
throw new Error(`Job failed: ${state.failureCode} (${state.failureReason})`);
}
if (state.status === "cancelled") {
throw new Error("Job was cancelled.");
}
// Wait 5 seconds before checking again
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
const downloadUrl = await waitForVideo(job.id);
console.log(`Finished video: ${downloadUrl}`);
import os
import time
import requests
def wait_for_video(job_id):
headers = {"Authorization": f"Bearer {os.environ['TSCAPS_API_KEY']}"}
while True:
response = requests.get(
f"https://api.tscaps.io/v1/automation-jobs/{job_id}",
headers=headers,
)
state = response.json()
if state["status"] == "succeeded":
return state["downloadUrl"]
if state["status"] == "failed":
raise RuntimeError(f"Job failed: {state['failureCode']} ({state['failureReason']})")
if state["status"] == "cancelled":
raise RuntimeError("Job was cancelled.")
# Wait 5 seconds before checking again
time.sleep(5)
download_url = wait_for_video(job["id"])
print(f"Finished video: {download_url}")
As the job runs, the phase property progresses through:
queued: Waiting for processing capacity.ingesting: Downloading and validating the source video.transcribing: Extracting speech and aligning timestamps.rendering: Drawing caption animations and burning them into the video frames (percentreflects render completion from 0 to 100).succeeded: The output file is rendered, uploaded, and ready to download.
Real-time webhook notifications
Instead of polling, configure a
webhookUrlto receive an instant callback as soon as the job finishes. Learn more in the Webhooks guide.
3. Download the result
When status reaches succeeded, the response includes downloadUrl, a secure presigned URL pointing directly to the final rendered video, and outputExpiresAt indicating when the link expires (stored for 7 days).
{
"id": "9f2c48e1-5b7a-4a29-8874-9dfc8227b610",
"status": "succeeded",
"phase": "succeeded",
"templateId": "mira",
"quotedSeconds": 48,
"format": "mp4",
"quality": "high",
"resolution": { "width": 1080, "height": 1920 },
"percent": null,
"downloadUrl": "https://storage.tscaps.io/outputs/9f2c48e1-...?token=...",
"outputExpiresAt": "2026-09-19T10:14:00.000Z",
"failureReason": null,
"failureCode": null,
"settledAt": "2026-09-12T10:12:26.000Z",
"createdAt": "2026-09-12T10:11:38.000Z"
}
Next steps
- API reference: Inspect every endpoint, request parameter, frame budget rule, and failure code.
- Direct file uploads: Learn how to upload private video files without a public URL.
- Webhooks: Receive asynchronous delivery notifications and verify signatures.
- Limits & quotas: Review duration, resolution, concurrency, and rate limits per plan.