Endpoints
| Mode | Endpoint | Use case |
|---|---|---|
| Text-to-Video | POST /api/v1/videos/text-to-video | A generated scene from a prompt, scored with a music bed |
| Image-to-Video | POST /api/v1/videos/image-to-video | Animate a still image (product shot, photo) from a motion prompt |
| AI influencer | POST /api/v1/videos/ai-influencer | A persona or a photo of a person speaks your script with lip-synced narration (talking head); choose the engine |
| Personas | POST /api/v1/avatars | Create a reusable AI influencer presenter from one photo (also GET and DELETE) |
Lengths are 30 seconds (default) or 1 minute, rendered as a sequence of continuous shots. For a narrated, captioned video built from stock footage, use the Stock Video API. For clips from existing YouTube videos, use the YouTube Clipper API.
Live keys require Idempotency-Key. The response is the standard receipt: 200 { success, data: { job_id, video_id, status, poll_url, price_usd_cents } } (job id also in the X-Job-Id header; the top-level jobId/videoId are deprecated aliases). Poll data.poll_url until data.job.status is completed and read data.job.artifacts.videoUrl. See Jobs.
Dry run (free). Add "dry_run": true to any request on this page to validate it and get the exact price (model, tier and length in data.price.breakdown) without creating a job or being charged; no Idempotency-Key is needed. Invalid input, such as a prompt over 1,000 characters or an unsupported resolution, returns the same 400 INPUT_INVALID as a real call, and a real call rejects it before charging. See Dry runs.
Text-to-Video
A generated scene from a prompt, with a licensed instrumental music bed underneath. Describe one subject, its action, the camera and the mood. Add a script to have it narrated with captions, and a brand for your logo and colours (see Narration, captions and brand).
curl -X POST https://api.reelsbuilder.ai/api/v1/videos/text-to-video \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Cyberpunk Tokyo at dawn, neon reflections in puddles, slow drone shot",
"quality_tier": "medium",
"duration_sec": 30,
"aspect_ratio": "9:16"
}'Choose quality with quality_tier: low (Wan 3.0, 720p), medium (Kling 3.0 Standard), high (Kling 3.0 Pro), xhigh (Seedance 2.0) or max (Veo 3.1). Or pin an exact model with model. Current model ids: bytedance/seedance-2.0 (default), google/veo-3.1, kling-3-t2v, kling-3.0-standard, kling-3.0-pro, wan-3.0, fal-ai/wan/v2.7, fal-ai/ltx-2.3, fal-ai/pixverse/v6. The live list, with the 30s and 60s price of every tier and model, is in pricing.ai_video of GET /api/v1/tools. Unknown model ids silently fall back to the default model — check the X-Api-Credits-Model response header to see which model ran.
Other fields: duration_sec (30 default or 60; a single native clip of up to 15 seconds is also accepted where the model supports that length; aliases duration, duration_target_sec), aspect_ratio (alias aspectRatio), resolution and webhook_url (alias webhookUrl).
| Field | Type | Description |
|---|---|---|
music | boolean | Default true: a licensed instrumental track from our library is mixed under the video, faded in and out, and the result is loudness-normalized for social platforms. Send false for no music. No price change. Alias: include_music. |
native_audio | boolean | Keep the model's own generated soundtrack (ambient sound and effects). Default false on kling-3.0-standard and kling-3.0-pro (the medium and high tiers), which also makes them cheaper; default true on every other model. With true, the music bed is ducked under the native audio. With native_audio: false and music: false the MP4 still has a silent audio track, so it uploads cleanly to every platform. |
delivery | object | Optional. { "visibility": "private" } keeps the finished files in a private bucket instead of our public CDN; the job then returns links that expire after 24 hours. See Private delivery. |
Narration, captions and brand
| Field | What it controls |
|---|---|
prompt | What is shown: the scene the model renders. Never spoken. |
script | What is said: narrated word for word by an ElevenLabs voice. |
curl -X POST https://api.reelsbuilder.ai/api/v1/videos/text-to-video \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A security analyst in a calm, sunlit office watches a wall of red alerts turn green",
"script": "Your SOC team is drowning in alerts. Acme Cloud triages them in seconds, so analysts only see what matters. Try it free at acme.com.",
"quality_tier": "medium",
"duration_sec": 30,
"brand": { "name": "Acme Cloud", "logo_url": "https://acme.com/logo.png", "primary_color": "#0A66C2", "website_url": "https://acme.com" }
}'| Field | Type | Description |
|---|---|---|
script | string | Narration, spoken verbatim. Budget about 2.4 words per second: ~72 words for 30 seconds, ~144 for 1 minute. A script slightly over budget adds one extra shot to the video (for example 30s becomes 40s on Kling) and is charged for it; a longer one returns a free 400 INPUT_INVALID that states the word budget. Maximum 2,000 characters. |
content_purpose | enum | With no script: we write the narration from your prompt for this purpose (education, sales, awareness, product_demo, case_study, news, entertainment), sized to the length, with your brand name and website woven in. With neither field there is no narration. |
voice_id | string | ElevenLabs voice id. Default: a female voice, or a male one with voice_gender: "male". Aliases: voice, voiceId. |
voice_gender | enum | female (default) or male, used when there is no voice_id. |
captions | boolean | Default true when there is narration: big word-by-word captions with the active word highlighted. No effect without narration. Alias: include_captions. |
brand | object | Same contract as the Stock Video API: logo_url (public https image) is placed bottom-right, accent_color (else primary_color) colours the highlighted caption word, name and website_url go into a generated script. Top level only. |
The music bed ducks under the narration (and under the model's own audio when native_audio is on). Narration adds a few cents for speech and word timing: see prices_narrated in GET /api/v1/tools.
Image-to-Video
curl -X POST https://api.reelsbuilder.ai/api/v1/videos/image-to-video \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://your-cdn.example.com/product.jpg",
"prompt": "slow zoom in, gentle parallax",
"quality_tier": "low",
"duration_sec": 30
}'Same model selection, fields and response as Text-to-Video, plus image_url. Describe the motion in prompt.
AI influencer (talking head)
A presenter says your script word for word, with natural lip sync and an ElevenLabs voice. Good for spokesperson, founder-style and UGC-style ads. We pick a good default; you can choose the render engine on every call, and every engine has a published price.
There are two ways to supply the presenter:
- Persona (
avatar_id), recommended. Create a reusable presenter once from one photo, then render it as often as you like on any engine it supports. Avatar III on a persona is the cheapest render. - Photo (
image_url). No setup; the photo is animated on Avatar IV, the only engine that accepts a raw photo.
Personas
curl -X POST https://api.reelsbuilder.ai/api/v1/avatars \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: acme-founder-persona-1" \
-H "Content-Type: application/json" \
-d '{ "image_url": "https://your-cdn.example.com/presenter.jpg", "name": "Acme founder" }'
# -> 201 { "success": true, "data": { "avatar_id": "6703...", "name": "Acme founder",
# "status": "ready", "supported_engines": ["avatar_iii", "avatar_iv", "avatar_v"] } }| Endpoint | Price | Description |
|---|---|---|
POST /api/v1/avatars | $2.65 once | Body { image_url, name? }. Usually ready within about 20 seconds (201, status: "ready"); otherwise 202 with status: "processing" and a poll_url. Requires Idempotency-Key. Refunded if creation fails. |
GET /api/v1/avatars | free | Your personas, newest first, with status and supported_engines. |
GET /api/v1/avatars/{avatar_id} | free | One persona; poll it until status is ready. |
DELETE /api/v1/avatars/{avatar_id} | free | Deletes the persona and its stored likeness. |
Personas are private to your account: another account'savatar_id returns 404 AVATAR_NOT_FOUND. The photo passes a content-safety check (422 when blocked, refunded). Only send photos you have the rights to use.
Engines and prices
| Engine | Input | 30 seconds | 1 minute | When to use it |
|---|---|---|---|---|
avatar_iii (default for avatar_id) | avatar_id | $1.00 | $2.00 | Best lip sync and the cheapest. Slower to render (about 6.5 minutes for a short clip in our tests). |
avatar_iv (only engine for image_url) | image_url or avatar_id | $2.45 | $4.90 | More expressive head and body motion; about 3.5 minutes to render. |
avatar_v | avatar_id | $7.25 | $14.50 | Premium and experimental. Only for personas whose supported_engines lists it. Price is provisional. |
Price = (the engine's per-second provider cost × spoken seconds + narration + storage) × 2, rounded up to 5 cents, with a 5-second minimum. Spoken length is estimated from the script (about 2.5 words per second at speed 1.0). GET /api/v1/tools returns the same table in pricing.ai_influencer, and each response carries the exact charge in X-Api-Credits-Cost-Usd-Cents and the engine used in X-Api-Credits-Engine.
Presenter finishing
The API accepts boolean captions and music, both defaulting to true, plus an optional per-request brand for a logo and caption accent. Brand name, tone and industry do not rewrite the supplied script. Check the deployed generate_ai_influencer schema at GET /api/v1/tools before using these fields; all three were advertised on October 7. Unsupported fields can be ignored, so request acceptance alone proves nothing.
Finishing keeps the provider's speech, adds captions and a licensed music bed when available, and applies the requested logo and accent color. The script remains verbatim. If finishing fails, the job can complete with the original provider video instead. Inspect returned influencerFinishingmetadata where available: applied: false with an error indicates that fallback. A completed job does not guarantee captions, music or a logo; review the actual video before publishing. This release does not establish avatar quality, likeness consent or directory eligibility.
Render a video
curl -X POST https://api.reelsbuilder.ai/api/v1/videos/ai-influencer \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: acme-spokesperson-0042" \
-H "Content-Type: application/json" \
-d '{
"avatar_id": "6703...",
"engine": "avatar_iii",
"script": "Your SOC team is drowning in alerts. Acme Cloud triages them in seconds, so your analysts only see what matters. Book a demo at acme.com.",
"aspect_ratio": "9:16"
}'
# -> 200 { "success": true, "data": { "job_id": "...", "video_id": "...", "status": "queued", "poll_url": "/api/v1/jobs/...", "price_usd_cents": 245 } }| Field | Type | Description |
|---|---|---|
avatar_id | string | A persona from POST /api/v1/avatars with status: "ready". Send this or image_url, not both. |
engine | enum | avatar_iii (default for avatar_id), avatar_iv or avatar_v. Must be in the persona's supported_engines (else a free 400 ENGINE_NOT_SUPPORTED). With image_url, only avatar_iv is accepted. |
image_url | URL | Public https photo of one person, face clearly visible and facing the camera. Portrait crops work best. Renders on Avatar IV. |
script | string | Spoken word for word. About 75 words = 30 seconds, 150 words = 1 minute. Maximum 120 seconds of speech (about 300 words). Required, except with format: "presenter_broll", which also accepts topic instead (see Presenter + B-roll). |
format | enum | talking_head (default) or presenter_broll. Same price. |
voice_id | string | ElevenLabs voice id. When omitted, a default voice that matches the presenter is chosen. Alias: voiceId, voice. |
voice_gender | enum | female or male: picks the matching default voice when you do not send voice_id. If neither is sent, we match the voice to the presenter in the photo. |
speed | number | Speech speed, 0.5–1.5. Default 1.0. |
aspect_ratio | enum | 9:16 (default), 16:9 or 1:1. Alias: aspectRatio. |
dry_run | boolean | Free: validate and price (engine and spoken seconds in data.price.breakdown) without rendering or charging. |
delivery | object | Optional. { "visibility": "private" } keeps the finished files in a private bucket instead of our public CDN; the job then returns links that expire after 24 hours. See Private delivery. |
Poll data.poll_url (GET /api/v1/jobs/{job_id}) like any other job. Free errors (nothing is charged): 400 INPUT_INVALID (both or neither of image_url/avatar_id, non-https or internal URLs, scripts over 120 seconds, a non-IV engine with image_url), 404 AVATAR_NOT_FOUND, 409 AVATAR_NOT_READY (retry after polling the persona) and 400 ENGINE_NOT_SUPPORTED. Scripts pass a content-safety check.
Presenter + B-roll
format: "presenter_broll" is the edit organic "AI explainer" channels use, made for organic reach rather than ads. It has three layouts:
layout: "creator"(the default with 9:16): the edit top creators use. Every shot is planned for a purpose (set the scene, show the problem, show the proof, land the payoff). The presenter appears only on the hook, opinion and payoff lines and the close, never longer than 2.5 seconds at a time and at most 35% of the video, with a punch-in each time. Everything else is full-screen stock footage or a full-screen motion graphic while the voice keeps running. No clip is held longer than 4 seconds (one earned peak moment may hold up to 6), clip lengths and transitions vary, cuts land on the spoken words, captions are short 1–3 word phrases inside the platform safe zone, and subtle sound effects mark the cuts and on-screen messages. The voice is cast to match the presenter's face; an avatar keeps its voice for every video.layout: "split": a 1080×1920 split screen. The top half shows a visual for what is being said, changing every 1.5 to 4 seconds for the whole video: mostly motion graphics of the thing itself (the message thread, the notification, the number, the steps), with real stock footage where a real-world scene helps. The bottom half is the presenter, always visible, cropped chest-up around the face (the crop is fixed for the whole video). A short caption phrase sits on the seam between the halves, and your logo sits small at the top right.layout: "cutaway"(the default for 16:9 and 1:1): the presenter full frame; explanatory lines cut to full-screen stock B-roll while the voice keeps running. The hook (first sentence) and the last sentence stay on the presenter, and the video never stays on B-roll for more than about 8 seconds in a row.
Send script (spoken word for word) or topic. With topic we write the script: a hook first (a surprising fact, a question or a bold claim), one idea, concrete examples, short spoken sentences, and no sales pitch or "link in bio" call to action. The written script is returned in the job's artifacts.script.
curl -X POST https://api.reelsbuilder.ai/api/v1/videos/ai-influencer \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: acme-explainer-0007" \
-H "Content-Type: application/json" \
-d '{
"avatar_id": "6703...",
"format": "presenter_broll",
"topic": "Why most new hires take three months to become productive, and the one onboarding change that halves it",
"duration_sec": 45,
"layout": "creator",
"caption_style": "seam",
"broll": { "visuals": "stock", "footage_keywords": ["office", "laptop"] },
"brand": { "logo_url": "https://cdn.acme.com/logo.png", "accent_color": "#00C2FF" },
"aspect_ratio": "9:16"
}'
# -> 200 { "success": true, "data": { "job_id": "...", "status": "queued", "poll_url": "/api/v1/jobs/...", "price_usd_cents": 150 } }| Field | Type | Description |
|---|---|---|
topic | string | Up to 500 characters: what the video teaches. Only with presenter_broll; send it instead of script. |
duration_sec | integer | With topic: target spoken length, 15–90 seconds. Default 30. The price is the engine's price for this many seconds of speech (a 45-second Avatar III render costs the same as a 45-second script). Ignored with script, which is priced from its length as usual. It is a target for the speech, not an exact file length: the written script can run a few seconds short or long, and an opening card and the end card (about 3 seconds each) can be added on top. Requests for 45 seconds have delivered files of 39 to 51 seconds; read the real length from artifacts.durationSec. |
content_purpose | enum | With topic: the editorial job of the script. Default education. |
layout | enum | creator (default with 9:16 or no aspect_ratio; needs 9:16), split (needs 9:16) or cutaway (default for 16:9 and 1:1). Same price. |
caption_style | enum | seam (default for creator and split): one 1–3 word phrase at a time, white bold text in a rounded dark box, the key word in brand.accent_color; on the seam for split shots, on the lower-middle line inside the safe zone for full-screen shots. karaoke (default for cutaway): word-highlight captions at the bottom. On creator either value burns the creator edit's own captions (1–2 words, the spoken word highlighted), placed clear of its graphics. |
broll.visuals | enum | stock (default): motion graphics we render ourselves in your accent colour (the message thread, notification, inbox, number, steps, comparison or quote each line is about), real stock footage where a real-world scene helps, and headline cards; no AI images. generated: the same graphics, with AI scene stills for the footage moments (at most about 1 shot in 4). mixed: graphics and real footage, AI stills only when no footage fits. generated and mixed are opt-in; see the note below. Same price. |
broll.coverage | number | cutaway only: share of the runtime on B-roll, 0.2–0.8. Default 0.5. Creator and split videos plan their own coverage. |
broll.footage_keywords | string[] | Terms that steer every B-roll search (up to 32). |
broll.exclude_keywords | string[] | Never use footage tagged with these terms (up to 32). |
broll.clip_type | enum | Stock footage niche. Default: inferred from brand.industry/keywords and the topic, else business. |
brand.name | string | With topic: may appear once, naturally, in the written script. |
Render time: a presenter + B-roll video is planned, searched for footage and edited shot by shot, so it is our slowest product. Measured on production in October 2026: about 15–25 minutes for one 30–45 second video, and 35–45 minutes each when two or more run at the same time. Pass a webhook_url, or poll every 15 seconds; see How long jobs take.
More creator-layout options
All optional and at the same price. The complete field reference, with every limit and error code, is in llms.txt; the request schema your key can use is in GET /api/v1/tools.
| Field | What it does |
|---|---|
host | { "type": "logo", "style": "cube" | "card" | "auto", "url_text": "acme.com" }: a faceless edit where your logo is the animated host. Do not send avatar_id, image_url or engine with it. Needs a logo (brand.logo_url, a brand_id kit or host.logo_url). A 30-second logo-host video is $1.00. |
outro, outro_cta | A 2.5–3 second animated end card with your logo, domain and a call-to-action line of up to 40 characters. On by default when a logo is available; outro: false ends on the last shot. |
progress_bar | true or { "enabled": true, "position": "top" | "bottom", "color": "#RRGGBB" }: a thin bar that fills over the video. Off by default. |
presenter_placement | bottom_left (default) or bottom_center: where the cut-out presenter sits over the footage. |
instructions | Up to 1,000 characters of free-text steering for this video (angle, hook, tone). It cannot override content rules, your brand kit's banned topics or the closing line. |
brand_id, series_id | A saved brand kit (POST /api/v1/b2b/brands) and your own series id. The first video of a series fixes its presenter, voice and engine; later videos reuse them, and the same topic twice returns a free 409 SERIES_TOPIC_REPEATED. Sending a different avatar_id, voice_id or engine to an existing series returns a free 409 SERIES_CONFLICT: start a new series_id to change presenter. |
variations | { "count": 2 } (1–5): one request writes that many different scripts for the same topic and queues one job for each. You are charged the single-video price for every variation, and the response lists all the job ids in data.job_ids: poll each one. See the timeout note below. |
How a variations request answers. It records the set and its jobs and answers within a few seconds; the scripts are written and compared with each other right after, so the first answer carries distinctness.status: "pending". Send the same request with the same Idempotency-Key again to read the verdict (no new jobs, no charge). If your client never saw the answer, resend it: an identical request is recognised for 5 minutes whatever key it carries and returns the first set. See Idempotency.
Privacy note for generated visuals: generated visuals are produced by a third-party image model (Higgsfield); prompts derived from your script are sent to it. We remove your brand name, links, e-mail addresses and handles from those prompts and never send your logo. With the default visuals: "stock" nothing is sent to an image model.
Stock footage: footage comes from licensed free-stock libraries (Pixabay, Coverr; free commercial use, no attribution required) and our own library. Only a short search query is sent to them, without your brand name. People shown in stock footage are never presented as endorsing you or your product.
A creator video falls back to the split screen if the creator edit cannot be built, a split video falls back to the cutaway edit, and the cutaway edit falls back to the talking head; you always get a video at the same price. A creator video also returns metadata.storyboard (every shot with its purpose and the reason it is there) and metadata.qa (clip lengths, presenter screen time, cut timing, caption safe zone, loudness). metadata.presenterBroll.layout says which layout was delivered, and each entry of shots says where its visual came from (stock, generated or card).
B-roll is best effort and never fails a paid render. If the shots cannot be timed against the presenter's speech, or no footage matches, you get the talking head with captions, music and logo at the same price, and the video's metadata.presenterBroll reads { "applied": false, "reason": "..." }. When B-roll is applied it lists every cut: { "applied": true, "shots": [{ "start": 3.1, "end": 6.0, "clipId": "...", "query": "..." }] }. Captions always come from the presenter's actual speech.
Your own presenter recording (presenter_video_url) is built but not enabled yet: requests return a free 400 INPUT_INVALID until it has a published price. It will take a public https mp4 or mov of up to 90 seconds and 200 MB, with sound, instead of avatar_id or image_url.
Pricing
- Priced per model and length (30 seconds or 1 minute). Get the exact price before spending with
dry_run: true. The charge is returned indata.price_usd_centsand theX-Api-Credits-Cost-Usd-Centsresponse header (and in a402 INSUFFICIENT_API_CREDITSbody) and reported byGET /api/v1/usage. - On
kling-3.0-standardandkling-3.0-pro,native_audio: truecosts more: seeprices_native_audionext topricesinGET /api/v1/tools. The music bed is included in every price. - AI influencer is priced per engine and spoken length: from $1.00 per 30 seconds (Avatar III on a persona) to $2.45 (Avatar IV, any photo) and $7.25 (Avatar V). Creating a persona costs $2.65 once. See Engines and prices.
- Failed jobs are refunded. Sandbox keys (
rb_test_) return a fixture and charge nothing. - At most 5 heavy render jobs can be active per account; the sixth returns
429 RENDER_CONCURRENCY_LIMIT_EXCEEDED.
See also
- Stock Video API — narrated, captioned videos from stock footage
- YouTube Clipper API
- Multi-Platform Post API — publish a finished video
- Errors