REST API
Create videos from your own code. Authenticate with a personal token from Settings → API tokens. Jobs use the LLM and voice keys selected in your settings. Machine-readable spec: OpenAPI 3.1.
Create a video
curl -X POST https://video.textocad.com/api/v1/videos \
-H "Authorization: Bearer $BOARDCAST_TOKEN" \
-H "content-type: application/json" \
-d '{
"topic": "Explain how a heat pump works for high school students",
"options": { "seconds": 75, "language": "en", "theme": "whiteboard", "audience": "high school students" },
"mode": "full",
"webhook_url": "https://example.com/hooks/boardcast"
}'Returns 202 with { id, job_id, status: "queued" }. Use document_url instead of topic for a public PDF, DOCX, PPTX, MD or TXT, or send multipart/form-data with a file field. mode: "draft" stops after the script and narration so you can edit it in the web app.
Check progress
curl https://video.textocad.com/api/v1/videos/$ID -H "Authorization: Bearer $BOARDCAST_TOKEN"
{
"id": "…", "status": "rendering", "progress": 0.62,
"video_url": null, "srt_url": null,
"usage": { "input_tokens": 9123, "output_tokens": 3410, "tts_characters": 1180 }
}Status goes queued → planning → voicing → rendering → uploading → done (or failed with error). video_url, download_url and srt_url are signed and valid for one hour; fetch the video again for fresh links. Live updates: GET /api/v1/projects/:id/events (Server-Sent Events).
Other endpoints
GET /api/v1/videos | List your videos (limit, offset) |
DELETE /api/v1/videos/:id | Delete a video and its files |
GET /api/v1/videos/:id?include=script | Also return the script (scene DSL) and timeline |
PUT /api/v1/projects/:id | Save an edited script { script } |
POST /api/v1/projects/:id/render | Render the current script |
POST /api/v1/projects/:id/regenerate-beat | { beat_index, instruction } |
GET /api/v1/usage?days=30 | Tokens, voice characters, render seconds |
GET /api/v1/icons?q=… | Search the drawing library |
Webhooks
When a job with webhook_url finishes, Boardcast POSTs { event: "video.completed" | "video.failed", video_id, job_id, status, error? } with the header Boardcast-Signature: t=<unix>,v1=<hex>. Verify it:
import crypto from 'node:crypto';
const [t, v1] = header.split(',').map((p) => p.split('=')[1]);
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(`${t}.${rawBody}`).digest('hex');
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1)) && Date.now() / 1000 - Number(t) < 300;Limits
Up to 180 s per video, 1 job(s) running at a time and 20 videos per day per account, 60 requests per minute per token, uploads up to 20 MB. Errors are JSON: { "error": "…" } with status 400, 401, 404, 413, 422 or 429.