BoardcastSign in

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/videosList your videos (limit, offset)
DELETE /api/v1/videos/:idDelete a video and its files
GET /api/v1/videos/:id?include=scriptAlso return the script (scene DSL) and timeline
PUT /api/v1/projects/:idSave an edited script { script }
POST /api/v1/projects/:id/renderRender the current script
POST /api/v1/projects/:id/regenerate-beat{ beat_index, instruction }
GET /api/v1/usage?days=30Tokens, 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.