API Reference
Base URL: https://api.html2reel.com
Authentication
Render endpoints use the X-API-Key header with a key from your dashboard. Account endpoints (/me, /me/keys) use a Bearer JWT from Kinde — intended for the dashboard, not for API clients.
POST /v1/reels
Submit a reel render job. Returns a job ID immediately (status 202).
Body
html(string, required) — the self-contained HTML template to render. Inline all CSS, JS, and asset URLs.duration_seconds(float, required) — reel length. Hard cap is set per deployment (default 60).width(int, optional) — viewport width in px. Defaults to the template's CSS body width.height(int, optional) — viewport height in px. Defaults to the template's CSS body height.fps(24|30|60, default30).audio_url(string, optional) — background audio. Muxed with auto fade-out over the last 1.5 s (clamped to one quarter of the reel length on very short clips).callback_url(string, optional) — webhook target for async delivery. SSRF-validated.
Response (202)
{"job_id":"abc-123","status":"queued"}GET /v1/reels/{id}
Status + result for a render job (scoped to your API key). Whilequeued or processing the response carries a Retry-After: 10 header — honour it instead of tight-looping.
# queued / processing (Retry-After: 10)
{"status":"queued","url":null,"error":null}
# done — url is the rendered mp4 on R2
{"status":"done","url":"https://.../result.mp4","error":null}
# failed
{"status":"failed","url":null,"error":"..."}Webhook payload
When callback_url is set, html2reel POSTs the final state (with retries: immediate, +30 s, +5 min) when the job reaches done or failed:
{"job_id":"abc-123","status":"done","url":"https://.../result.mp4","error":null}GET /me
(Bearer JWT) Current user + list of active (non-revoked) API keys.
POST /me/keys
(Bearer JWT) Create a new API key.
# Request
{"label":"Production"}
# Response (201) — raw key shown ONCE
{"id":"...","label":"Production","key_prefix":"h2r_a1b2c3d4","key":"h2r_a1b2c3d4...","created_at":"..."}DELETE /me/keys/{id}
(Bearer JWT) Soft-delete a key. Subsequent requests with it return 401.
Errors
400— invalidcallback_url(not http(s) or resolves to a private address).401— missing/invalid/revoked key, or bad JWT.403— account pending approval (key creation gated during beta).404— unknown job ID (or owned by another key).422— malformed request body (e.g. missinghtml).