Generate personalized videos programmatically. Use the same API that powers our visual builder.
New to the API? Start with the Quickstart Guide for a step-by-step tutorial.
All API requests require an API key. Include it in the X-API-Key header or as a Bearer token.
X-API-Key: sf_live_a1b2c3d4e5f6... # Or using Authorization header: Authorization: Bearer sf_live_a1b2c3d4e5f6...
Create API keys in your Dashboard Settings. API keys require Studio tier or above.
API keys are scoped to limit access to specific resources. Choose the minimal set of scopes needed for your integration.
| Scope | Description |
|---|---|
| videos:create | Create single render jobs |
| videos:create:batch | Create batch render jobs (CSV) |
| videos:read | Poll render status, get video URLs |
| videos:delete | Delete rendered videos |
| templates:read | List templates, view data schemas |
| templates:write | Create, update, fork, and delete templates |
| projects:read | List and view saved projects |
| projects:write | Create, update, delete projects |
| billing:read | View credit balance and usage history |
| webhooks:manage | Create and update webhook endpoints |
| keys:manage | Create and revoke API keys |
Most integrations need videos:create and videos:read. If you need batch rendering, also include videos:create:batch.
https://app.sigfigsstudio.com/api
Rate limits are applied per API key. Exceeding limits returns 429 Too Many Requests.
| Endpoint | Limit |
|---|---|
| POST /render | 30/min |
| POST /render/batch | 5/min |
| GET /render/:id | 120/min |
| GET/POST /keys | 30/min |
Response headers include X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After.
/api/renderCreate a render job. Returns a job ID for status polling.
templateIdemeritus, laureate, rewind, pulse, handshakedatabrandaccentColor (hex), logoUrl, logoPosition.audioincludeVoiceover (bool), voiceId (string), musicTrack.scenesoutputresolution ("720p" | "1080p" | "4k"), fps (30 | 60).curl -X POST https://app.sigfigsstudio.com/api/render \
-H "Content-Type: application/json" \
-H "X-API-Key: sf_live_YOUR_KEY_HERE" \
-d '{
"templateId": "emeritus",
"data": {
"authorId": "A5001825849"
},
"brand": {
"accentColor": "#14b8a6"
},
"audio": {
"includeVoiceover": true,
"voiceId": "en-GB-RyanNeural"
}
}'{
"success": true,
"jobId": "78008b5b-4207-4b2e-a1c5-9b923f519d4c",
"status": "pending",
"templateId": "emeritus",
"displayName": "Dr. Jane Smith",
"creditsRemaining": 97,
"message": "Render job created. Poll GET /api/render/[jobId] for status."
}/api/render/:idPoll for render job status. Returns video URL when complete.
{
"success": true,
"job": {
"id": "78008b5b-...",
"status": "complete",
"outputUrl": "https://skkroo2x4wm2v7c8.public.blob.vercel-storage.com/emeritus/78008b5b.mp4",
"authorName": "Dr. Jane Smith",
"createdAt": "2026-03-19T19:18:53.849Z",
"completedAt": "2026-03-19T19:19:20.614Z"
}
}Status values: pending → processing → complete | failed. Typical render time: 30-120 seconds.
/api/render/batchCreate multiple render jobs from a CSV-style rows array. Max 100 per batch.
{
"templateId": "emeritus",
"headers": ["name", "openalex_id", "institution"],
"rows": [
["Dr. Jane Smith", "A5001825849", "MIT"],
["Prof. John Doe", "A5002345678", "Stanford"],
["Dr. Sarah Lee", "A5003456789", "Oxford"]
]
}{
"success": true,
"batchId": "batch-abc123",
"jobIds": ["job-1", "job-2", "job-3"],
"totalJobs": 3,
"status": "pending"
}/api/keysList your API keys (key values are never shown after creation).
/api/keysCreate a new API key. Returns the key value once.
/api/keys/:idRevoke an API key immediately.
curl -X POST https://app.sigfigsstudio.com/api/keys \
-H "Content-Type: application/json" \
-H "Cookie: [your session cookie]" \
-d '{ "name": "Production", "scopes": "render-batch" }'curl -X POST https://app.sigfigsstudio.com/api/keys \
-H "Content-Type: application/json" \
-H "Cookie: [your session cookie]" \
-d '{ "name": "Production", "scopes": "videos:create,videos:create:batch,videos:read" }'{
"success": true,
"key": "sf_live_a1b2c3d4e5f6789...",
"apiKey": {
"id": "clx...",
"name": "Production",
"keyPrefix": "sf_live_a1b2c3d4",
"scopes": "videos:create,videos:create:batch,videos:read"
},
"message": "Save this API key — it won't be shown again."
}Available presets: render-only, render-batch, full-access, read-only, admin.
Create custom templates from scratch, fork existing ones, or browse the library.
/api/templatesList your templates + built-in templates.
/api/templatesCreate a new template from scratch or fork an existing one.
/api/templates/:idGet a single template with full scene config.
/api/templates/:idUpdate scenes, data slots, defaults, or visibility.
/api/templates/:idDelete a custom template.
curl -X POST https://app.sigfigsstudio.com/api/templates \
-H "Content-Type: application/json" \
-H "X-API-Key: sf_live_YOUR_KEY" \
-d '{
"name": "Quarterly Review",
"scenes": [
{ "primitiveId": "title-intro", "voScript": "Welcome to Q[quarter] [year]." },
{ "primitiveId": "stat-counters", "voScript": "[revenue] in revenue. [growth]% growth." },
{ "primitiveId": "bar-race" },
{ "primitiveId": "comparison-bars" },
{ "primitiveId": "outro" }
],
"dataSlots": [
{ "key": "revenue", "type": "number", "required": true },
{ "key": "growth", "type": "number" },
{ "key": "quarter", "type": "text", "required": true }
],
"defaults": { "voiceId": "en-GB-RyanNeural", "accentColor": "#6366F1" }
}'curl -X POST https://app.sigfigsstudio.com/api/templates \
-H "Content-Type: application/json" \
-H "X-API-Key: sf_live_YOUR_KEY" \
-d '{
"name": "My Custom Emeritus",
"forkFrom": "emeritus",
"scenes": [
{ "primitiveId": "title-intro", "voScript": "Celebrating [name]." },
{ "primitiveId": "radar" },
{ "primitiveId": "bar-race" },
{ "primitiveId": "world-map" },
{ "primitiveId": "outro" }
]
}'{
"success": true,
"template": {
"id": "clx1abc2def3...",
"name": "My Custom Emeritus",
"scenes": [...],
"baseTemplateId": "emeritus",
"visibility": "private"
},
"message": "Template forked from emeritus."
}/api/primitivesBrowse all available animated primitives. Filter by category. No auth required.
Primitives are the building blocks — animated charts, counters, maps, badges, and more. Use them when creating custom templates.
curl https://app.sigfigsstudio.com/api/primitives # Filter by category curl https://app.sigfigsstudio.com/api/primitives?category=Data%20Viz
{
"success": true,
"primitives": [
{
"id": "bar-race",
"label": "Bar Chart Race",
"category": "Data Viz",
"description": "Animated ranking race over time",
"animationOptions": ["animate-on-init"],
"defaultDuration": 6,
"dataInputs": ["items[]", "values[]"]
},
...
],
"categories": ["Text", "Data Viz", "Gamification", "Comparison", ...],
"total": 72
}Each template expects different data fields. Some templates fetch data from external sources automatically.
Academic research career celebration
authorIdperson_nameinstitutionOverrideAuthor literary career spotlight
hardcover_idperson_namebooksYear-in-review / Spotify Wrapped style
person_nametotalWorkoutstotalMinutespercentileradarDataBusiness monthly/quarterly review
person_nameperiodkeyStatscategoriesClient onboarding video
company_nameperson_nameindustrymilestonescompanyStats| Voice ID | Description | Tier |
|---|---|---|
| en-GB-RyanNeural | Male, British, professional | Free |
| en-US-GuyNeural | Male, American, neutral | Free |
| en-US-JennyNeural | Female, American, friendly | Free |
| en-GB-SoniaNeural | Female, British, confident | Free |
| elevenlabs-custom | Bring your own ElevenLabs voice | Studio+ |
| Code | Meaning |
|---|---|
| 400 | Invalid request — check the error details |
| 401 | Missing or invalid API key |
| 402 | Insufficient credits |
| 403 | Feature requires higher tier or insufficient API key scope |
| 429 | Rate limit exceeded — check Retry-After header |
| 502 | External data source failed (e.g., OpenAlex down) |
The API is a standard REST API — use any HTTP client. Here are quick examples:
import requests
API_KEY = "sf_live_YOUR_KEY"
BASE = "https://app.sigfigsstudio.com/api"
# Render a video
job = requests.post(f"{BASE}/render", json={
"templateId": "emeritus",
"data": {"authorId": "A5001825849"},
}, headers={"X-API-Key": API_KEY}).json()
print(f"Job created: {job['jobId']}")
# Poll for completion
import time
while True:
status = requests.get(
f"{BASE}/render/{job['jobId']}",
headers={"X-API-Key": API_KEY}
).json()
if status["job"]["status"] == "complete":
print(f"Video: {status['job']['outputUrl']}")
break
time.sleep(5)const API_KEY = "sf_live_YOUR_KEY";
const BASE = "https://app.sigfigsstudio.com/api";
// Render a video
const { jobId } = await fetch(`${BASE}/render`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
},
body: JSON.stringify({
templateId: "client-welcome",
data: {
company_name: "Meridian Health",
person_name: "Sarah Chen",
industry: "Healthcare",
},
}),
}).then(r => r.json());
// Poll for completion
const poll = setInterval(async () => {
const { job } = await fetch(
`${BASE}/render/${jobId}`,
{ headers: { "X-API-Key": API_KEY } }
).then(r => r.json());
if (job.status === "complete") {
clearInterval(poll);
console.log("Video:", job.outputUrl);
}
}, 5000);Create an API key in your dashboard and start generating videos in minutes.