Videos

A video moves through four stages: create (credits charged), generate (poll status), render (free, produces the MP4) and publish (free). This guide walks the whole lifecycle; publishing and scheduling covers the last stage in depth.

Models and cost

Pick the model in POST /videos. Credits are charged at creation, not at render:

ModelCreditsWhat you get
storyboard20Static AI scenes with motion effects
motion_lite50Animated transitions between scenes
motion_pro100Cinematic AI motion video

GET /options?kind=models returns the same catalog with costs, so an agent can decide programmatically.

1. Create (POST /videos, scope videos:write)

Send a finished narration script and a voice id (from GET /voices). Optional fields: style, language, name, enableBackgroundMusic, masterStyle, globalNegativePrompt.

bash
curl -s -X POST https://faceless.so/api/v1/videos \
  -H "Authorization: Bearer $FACELESS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"script": "Did you know the ocean has lakes and rivers of its own? ...", "voiceId": "EXAVITQu4vr4xnSDxMaL", "model": "storyboard"}'

Response (201):

json
{
  "success": true,
  "data": {
    "id": "665f1b2a9c31a2b3c4d5e801",
    "name": "Did you kn...",
    "model": "storyboard",
    "status": "processing",
    "creditsUsed": 20,
    "statusUrl": "/api/v1/videos/665f1b2a9c31a2b3c4d5e801/status"
  }
}

Common errors: 402 insufficient_credits (top up before retrying), 403 usage_limit_reached (plan project limit, upgrade to create more), 429 rate_limited (10 creations per 60s per key; wait for Retry-After).

2. Poll generation (GET /videos/{id}/status, scope videos:read)

Generation is asynchronous and typically takes a few minutes. Poll every 10 to 30 seconds until status is completed or failed:

bash
curl -s https://faceless.so/api/v1/videos/665f1b2a9c31a2b3c4d5e801/status \
  -H "Authorization: Bearer $FACELESS_API_KEY"
json
{
  "success": true,
  "data": { "id": "665f1b2a9c31a2b3c4d5e801", "status": "processing", "percentCompleted": 62, "readyForEditing": false, "errorMessages": [], "renderedVideoUrl": null }
}

On failed, read errorMessages for the reason. With the CLI, faceless videos create --wait and faceless videos status <id> handle the polling.

3. Render (POST /videos/{id}/render, scope videos:write)

Rendering assembles the final MP4 in the cloud. It is free (credits were charged at creation) and requires generation to be completed first.

bash
curl -s -X POST https://faceless.so/api/v1/videos/665f1b2a9c31a2b3c4d5e801/render \
  -H "Authorization: Bearer $FACELESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"codec": "h264"}'

The 202 response contains a renderId. Poll GET /renders/{renderId} (scope videos:read) every 5 to 15 seconds; renders typically finish in under two minutes:

bash
curl -s https://faceless.so/api/v1/renders/abcd1234efgh \
  -H "Authorization: Bearer $FACELESS_API_KEY"
json
{
  "success": true,
  "data": { "renderId": "abcd1234efgh", "status": "done", "overallProgress": 1, "url": "https://exports.faceless.so/renders/665f1b2a9c31a2b3c4d5e801/1722333444555.mp4" }
}

status is in-progress (with overallProgress 0 to 1), done (with the MP4 url) or error. The MP4 url is a direct download; it also appears as renderedVideoUrl on the video.

4. Publish

Publish immediately with POST /posts, or set per-platform metadata with PATCH /videos/{id} and schedule with POST /posts/schedule. Both are free; see publishing and scheduling.

Captioning existing footage (POST /videos/captions)

To caption a video or audio file you already have (no AI visuals, no credit cost), send its public URL. Processing is asynchronous; poll GET /videos/{id}/status like any other video.

bash
curl -s -X POST https://faceless.so/api/v1/videos/captions \
  -H "Authorization: Bearer $FACELESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"videoUrl": "https://example.com/clip.mp4", "language": "English"}'

Provide videoUrl or audioUrl (an audio file becomes a captioned video). Rate limit: 10 per 300s.

Managing videos

  • GET /videos (scope videos:read): paginated list, newest first, with renderedVideoUrl when available. ?archived=true for archived only.
  • GET /videos/{id}: one video with script, voice, model, status and post metadata.
  • PATCH /videos/{id} (scope videos:write): rename, or set per-platform post metadata before scheduling.
  • DELETE /videos/{id} (scope videos:write): permanent, no credit refund.

A 404 not_found on any of these means the id does not exist or belongs to another team.