API RapidVideoMaker
The REST API lets you process video files from any HTTP client — Python scripts, n8n workflows, third-party tools. Six modes available: Merge videos (multiple MP4), Edit audio (1 MP4 + 1 MP3), Create a video (1 JPG/PNG + 1 MP3), Overlay video (2 MP4 picture-in-picture), Text to MP3 (no file upload). Processing is asynchronous: submit your request, then poll for the result.
Complete workflow
Every integration follows the same 4-step sequence:
POST /api/v1/render.phpmultipart/form-data with your Bearer token. 1 JPG/PNG image + 1 MP3 + mode=image_to_video → video generation. 1 MP4 + 1 MP3 → audio edit (add mode=mix_audio to overlay tracks). Multiple MP4 → merge. The server returns a unique job_id.GET /api/v1/jobs.php?job_id=…queued → processing → ready (or error). The response includes the queue position and an estimated time remaining.ready, the response contains a ready-to-use download_url field.GET /api/download.php?job_id=…410 Gone (instead of 404) to indicate the job existed but is no longer retrievable.Authentication
Every request must include your API token. Two formats are accepted:
Your token is available in your member space — one token per account, created automatically at registration. It is only shown in the clear once — keep it safe. If you lose it, you can regenerate it from your member space.
Quota
Each member account has 10 requests per day, shared between the web interface and the API. Failed jobs do not consume quota. The counter resets at midnight UTC.
POST responses include quota_used and quota_remaining. When the limit is exceeded, the server responds 429.
Queue
One job is processed at a time. If multiple jobs are submitted simultaneously, they are queued and processed in arrival order. While waiting, the status response includes:
queue_position— position of the job in the queue (1 = next to be processed)queue_total— total number of jobs waitingeta_minutes— estimated time before processing starts
/api/v1/jobs.php endpoint accepts at most 12 calls per minute per token (1 every 5 s). Beyond that, the server responds 429 with a Retry-After: 5 header. Recommendation: 10 seconds between each call. Available transitions
Pass transition_type=none (default) for a direct merge, or one of the types below for a fade between clips:
Duration (transition_duration) is between 0.2 and 2.0 seconds. If a clip is too short to accommodate the transition, it is ignored and the merge proceeds without transition.
Endpoints
Six modes, accessible via the mode field (omit mode with multiple MP4s to auto-detect fusion):
| Usage | API Mode(s) | Required files | Description |
|---|---|---|---|
| Merge videos | fusion |
2–20 MP4 files | Clips are assembled end-to-end in the order provided. Optional transitions between clips. |
| Edit audio | add_audio or mix_audio |
1 MP4 + 1 MP3 | Replaces or enriches the audio track of a video. The video track is never re-encoded (-c:v copy).add_audio — the original audio is deleted and fully replaced by the MP3.mix_audio — the original audio is kept and the MP3 is overlaid (amix). Pass options={"mp3_volume":…} to adjust the added MP3 volume. If the video has no audio, behaves like add_audio. |
| Create a video | image_to_video |
1 JPG/PNG + 1 MP3 | Generates a video from a still image and an audio file. Text overlay, fades, resolution and fps configurable via the options field. |
| Overlay video | overlay_video |
2 MP4 | Overlays a second video on top of the main one. Position, size, opacity and audio configurable via the options field. |
| Text to MP3 | text_to_mp3 |
(text only) | Converts text to speech and returns an MP3 file. No file upload required — send mode=text_to_mp3, text and lang as form fields. Supports all 20 site languages. |
add_audio and mix_audio accept only 1 MP4 + 1 MP3 (exactly). image_to_video accepts only 1 JPG/PNG + 1 MP3 (exactly). Any other combination is rejected with an explicit error code. MIME types are verified by magic bytes, not only by extension. Multiple MP4s without a mode field → auto-detect fusion.-c:v copy).Common parameters (multipart/form-data)
| Field | Type | Req. | Description |
|---|---|---|---|
| videos[] | File[] | YES | Files to process. Depending on mode: 2–20 MP4, or 1 MP4 + 1 MP3, or 1 image (JPG/PNG) + 1 MP3. Max 500 MB per file. |
| mode | string | * | image_to_video | add_audio | mix_audio | overlay_video | text_to_mp3. Required for these non-fusion modes. Omitting mode with only MP4 files always triggers fusion (stream-copy concat) — never overlay_video, even if exactly 2 MP4s are uploaded. For audio editing: add_audio deletes the original, mix_audio keeps it and overlays. If the mode field is provided, uploaded files must match exactly — otherwise the request is rejected. |
| order | JSON | fusion mode only — JSON array of indices defining the clip order. | |
| transition_type | string | fusion mode only. Default: none. See the list of available transitions. | |
| transition_duration | float | fusion mode only. Duration 0.2–2.0 s. Default: 0.5. | |
| options | JSON | image_to_video mode only — JSON object of render parameters (see below). | |
| callback_url | string | Public URL (http/https) called at job completion. The response includes a webhook_secret. |
options parameters — image_to_video mode
All optional. Values not provided → defaults applied by the worker.
| Key | Type | Default | Description |
|---|---|---|---|
| text | string | "" | Text shown as overlay. Empty = no text. Max 500 characters. |
| font_size | int | 60 | Font size in pixels. Range: 10–300. Recommended: 36, 48, 60, 72, 96. |
| text_color | string | "white" | Text color (e.g. white, yellow, #ffffff, 0xffffff). |
| text_position | string | "center" | Text position: center, top, bottom. |
| box | bool | true | Semi-transparent background behind the text. |
| box_color | string | "black@0.4" | Color + opacity in FFmpeg format: color@opacity. Colors: black, white, yellow, #ff4444, #00ccff, #ff8800, #ff69b4… Opacity: 0.0–1.0 (e.g. black@0.4 = black at 40%, white@0.70 = white at 70%). |
| fade_duration | float | 0.5 | Fade in/out duration in seconds (0–2). Text is included in the fade. 0 = no fade. |
| width | int | 1080 | Video width in pixels (64–3840, forced even). Standard combos: 1080/1920/720/1280. |
| height | int | 1920 | Video height in pixels (64–3840, forced even). |
| fps | int | 24 | Frame rate (1–60). |
| image_fit | string | "contain" | Framing mode: contain = the full image is visible, empty areas filled by bg_color (letterbox/pillarbox); cover = image zoomed to fill the entire frame, centered, excess edges cropped (no black bars). The bg_color parameter is ignored in cover mode. |
| bg_color | string | "black" | Background (padding) color if the image does not fill the target resolution — relevant only with image_fit=contain (e.g. black, white, #1a1a2e). |
| enable_image_motion | bool | false | Enables photo animation. If false, the image stays static. If true, the effect defined by image_motion_effect is applied via the FFmpeg zoompan filter. |
| image_motion_effect | string | "ken_burns" | Animation effect (ignored if enable_image_motion is false). Accepted values: zoom_in, zoom_out, pan_left_to_right, pan_right_to_left, pan_top_to_bottom, pan_bottom_to_top, zoom_pan_soft, ken_burns. Default if absent or invalid: ken_burns. |
| motion_intensity | float | 1.0 | Photo animation intensity (0.25–2.0). Multiplies zoom amplitude and pan speed. 0.25 = very subtle, 1.0 = default, 2.0 = double amplitude. Ignored if enable_image_motion is false. |
| text_effect | string | "none" | Text overlay animation (ignored if text is absent or text_mode is word_by_word). Accepted values: none, fade_in (fade-in), slide_up (slide from bottom), slide_down (slide from top), slide_left (slide from right), bounce (continuous vertical oscillation). |
| text_effect_intensity | float | 1.0 | Text animation intensity (0.25–2.0). Controls fade speed, slide entry duration, or bounce frequency and amplitude. Ignored if text_effect is none. |
| text_border_width | int | 0 | Thickness of the black outline around characters, in pixels (0 = disabled, 1–10). Improves readability on bright or colored backgrounds. Ignored if text is absent. |
| text_mode | string | "static" | Text reveal mode. static (default): full text visible from frame 1. word_by_word: words appear one by one at the rate set by word_reveal_speed. Mutually exclusive with text_effect: if text_mode=word_by_word, text_effect is ignored. |
| word_reveal_speed | float | 1.5 | Word reveal speed in words per second (0.3–5.0, default 1.5). Only used when text_mode=word_by_word. Recommended value for OpenAI TTS sync: 2.0. |
| word_anim | string | "none" | Word appearance animation. none (default): instant reveal. fade: each new word fades in over 0.2s with a crossfade to the previous block. Only used when text_mode=word_by_word. |
options parameters — overlay_video mode
All optional. Upload order matters: the first file is the main video (background), the second file is the overlay (foreground). Use chroma_key to remove a green screen from the overlay.
| Key | Type | Default | Description |
|---|---|---|---|
| position | string | "bottom-right" | Corner where the overlay is placed: top-left, top-right, bottom-left, bottom-right, or center. |
| scale | float | 0.30 | Overlay size as a fraction of the main video width. 0.25 = 25% of the width. Range: 0.05–1.0. |
| opacity | float | 1.0 | Overlay transparency. 1.0 = fully opaque, 0.0 = invisible. |
| margin | int | 10 | Gap in pixels between the overlay and the frame edge. Ignored when position=center. Range: 0–200. |
| audio | string | "main" | Which audio to keep. main: main video audio only. overlay: overlay audio only. mix: both tracks blended at equal volume. |
| chroma_key | bool | false | Set to true to remove the pure green (#00FF00) background of the overlay — useful for webcam or animations filmed on a green screen. |
| chroma_similarity | float | 0.20 | Green screen tolerance. Low = strict match (preserves subject edges). High = broader removal (handles uneven lighting). Recommended: 0.10–0.20 for a digital green, 0.25–0.45 for a physical screen. Range: 0.01–0.60. |
options parameters — Edit audio (mix_audio)
Available only with mode=mix_audio. Ignored for add_audio.
| Key | Type | Default | Description |
|---|---|---|---|
| mp3_volume | float | 1.0 | Volume of the overlaid MP3 (0.0 = muted, 1.0 = original volume, 2.0 = double). Values above 1.0 may clip. |
Success response (HTTP 200)
curl example — image_to_video mode
curl example — Edit audio
curl example — overlay_video mode
curl example — Merge videos
Possible statuses
| Status | Meaning | Additional fields |
|---|---|---|
| queued | In queue, not yet processed | queue_position, queue_total, eta_minutes |
| processing | FFmpeg processing in progress | — |
| ready | Completed — file available | download_url, created_at, expires_at |
| error | Processing failed | error (message) |
Responses by status
curl example
Common parameters (multipart/form-data)
| apidocs_th_param | Type | Default | apidocs_th_desc |
|---|---|---|---|
page | integer | 1 | Page number (starts at 1) |
limit | integer | 20 | Results per page (max 50, default 20) |
Responses by status
Publishes a finished job (status=ready) to one or more social accounts. The token must belong to a member account (not an admin token).
account_id for each account is shown there.Common parameters (multipart/form-data)
| apidocs_th_param | Type | apidocs_th_required | apidocs_th_desc |
|---|---|---|---|
job_id | string | apidocs_required | Job ID (hex 32 chars) of the finished video |
publications | array | apidocs_required | Array of publication objects (max 10) |
Publication object
| apidocs_th_param | Type | apidocs_th_required | apidocs_th_desc |
|---|---|---|---|
account_id | integer | apidocs_required | ID of the connected social account — find it in the Publications page of your member area |
title | string | — | Video title (max 512 chars) |
description | string | — | Video description (max 5 000 chars) |
tags | string | — | Comma-separated tags (max 1 024 chars) |
visibility | string | — | public | private | unlisted — Default: public |
tiktok_mode | string | — | draft | direct — TikTok only — default: direct |
tiktok_privacy | string | direct mode | TikTok only — required in direct mode |
allow_comment | boolean | — | TikTok only — allow comments |
allow_duet | boolean | — | TikTok only — allow duets |
allow_stitch | boolean | — | TikTok only — allow stitches |
your_brand | boolean | — | TikTok only — organic promotional content ("Your Brand"). |
branded_content | boolean | — | TikTok only — branded content disclosure |
tiktok_cover_ms | integer | — | TikTok only — cover frame timestamp in ms (0–60 000, default 1 000) |
Responses by status
Per-publication error codes
| apidocs_th_code | Meaning |
|---|---|
job_not_ready | Job not finished yet |
mode_not_supported | text_to_mp3 jobs cannot be published |
account_not_found | Account not found or disconnected |
tiktok_privacy_required | Privacy level required in direct mode |
publication_failed | Provider returned an error during upload |
cURL example
Returns the final MP4 file as a stream (Content-Type: video/mp4). Does not require a token — the URL is sufficiently opaque. Available only when the status is ready.
The file is kept for 2 hours after the job completes, then deleted. Download it as soon as the status becomes ready.
Optional parameter
| Parameter | Description |
|---|---|
| filename | Suggested name for the downloaded file (e.g. my-video.mp4) |
curl example
Webhooks
Webhooks are an alternative to polling: instead of checking the status every X seconds, you provide a URL and the server calls you automatically when the job completes.
How it works
- Pass
callback_urlin the POST to/api/v1/render.php - The response contains a
webhook_secret— keep it to verify signatures - When the job reaches
readyorerror, the server sends a signed JSONPOSTto your URL - Verify the signature with
HMAC-SHA256(webhook_secret, raw_body)
callback_url must be a publicly accessible URL (http or https). Private, loopback and reserved IP addresses are blocked server-side. Timeout: 10 seconds. Received payload
Headers sent by the server
| Header | Value |
|---|---|
| Content-Type | application/json |
| X-RVM-Signature | sha256=<hmac_hex> — HMAC-SHA256 signature of the raw body |
| X-RVM-Job-Id | The relevant job_id |
Signature verification
Error codes
| HTTP | JSON code | Cause |
|---|---|---|
| 401 | unauthorized | Token missing, invalid or revoked |
| 400 | missing_files | No files received |
| 400 | too_few_files | Fewer than 2 files sent |
| 400 | too_many_files | More than 20 files sent |
| 400 | invalid_mime | Unsupported file — only MP4, MP3 and JPG/PNG images are accepted (MIME verified by magic bytes) |
| 400 | wrong_file_count | The number of files does not match the chosen mode (e.g. 3 files with mode=add_audio which requires 2) |
| 400 | wrong_file_types | File types do not match the chosen mode (e.g. 2 MP4s with mode=add_audio which requires 1 MP4 + 1 MP3; or 1 MP4 + 1 MP3 with mode=image_to_video) |
| 400 | invalid_file_combination | File combination without a specified mode does not match any supported mode |
| 400 | invalid_options | The options field is not valid JSON or contains an expected object |
| 400 | invalid_option | A value in options is invalid (color, font name, position…) |
| 400 | file_too_large | A file exceeds 500 MB |
| 400 | invalid_order | The order array is not a valid permutation |
| 400 | invalid_job_id | Incorrect job_id format (must be 32-char hex) |
| 404 | job_not_found | Job not found — job_id unknown or never existed |
| 410 | job_expired | Job expired — existed but the 2h recovery window has passed |
| 429 | quota_exceeded | 10 successful jobs/day reached (all modes combined) |
| 429 | rate_limited | More than 12 calls/min on /api/v1/jobs.php — wait Retry-After seconds |
| 500 | server_error | Internal server error |
Integration examples
Examples for each mode — install requests with pip install requests.
Common configuration
image_to_video mode — image + audio → video
Edit audio
overlay_video mode — picture-in-picture
Merge videos
Polling + download (common to all modes)
Two approaches in n8n: polling (status loop) or webhook (server calls n8n). The webhook is recommended — cleaner, zero unnecessary load.
Approach A — Webhook (recommended)
3 nodes only, no loop.
Node 1 — Webhook trigger
Add a Webhook node as the workflow input (method POST). Note the generated URL, e.g. https://your-n8n.com/webhook/rvm-callback.
Node 2 — Create the job (HTTP Request)
| Method | POST |
| URL | https://rapidvideomaker.com/api/v1/render.php |
| Authentication | Header Auth — Authorization: Bearer rvm_… |
| Body Content Type | Form-Data Multipart |
| Body params | Binary field videos[] for each clip + Text field callback_url = webhook node URL above |
Keep the webhook_secret from the response in a workflow variable to verify the signature upon receipt.
Node 3 — Process the result (in the webhook-triggered workflow)
When n8n receives the server's POST, $json.status is ready or error. If ready, $json.download_url contains the direct download URL.
{{ $headers['x-rvm-signature'] }} with sha256= + HMAC-SHA256 of the raw body from your webhook_secret. Use a Code node with crypto.createHmac('sha256', secret).update(body).digest('hex').Approach B — Polling (without webhook)
5 nodes, status loop every 10 s.
Node 1 — Create the job — same config as above, without callback_url.
Node 2 — Wait — 10 seconds.
Node 3 — Poll status (HTTP Request GET)
| URL | https://rapidvideomaker.com/api/v1/jobs.php |
| Query params | job_id = {{ $('Node 1').item.json.job_id }} |
| Authentication | Header Auth — same token |
Node 4 — If: {{ $json.status }} === 'ready' → true: Node 5 / false: back to Node 2.
Node 5 — Download: HTTP Request GET on {{ $json.download_url }}, Response Format File.
Step 1 — Create the job (choose a mode)
Step 2 — Polling
Step 3 — Download
Best practices
- Polling frequency: the
/api/v1/jobs.phpendpoint is limited to 12 calls/min per token. Allow at least 5 seconds between calls (10 s recommended) to avoid a429. Job duration varies by mode and file size (from a few seconds to several minutes). - Timeout: implement a client-side timeout (e.g. 10 minutes). If the job is not
readyafter this delay, treat it as an error. - Download quickly: as soon as the status is
ready, download the file. It is deleted 2 hours after the job completes. - Quota management: check
quota_remainingin the POST response. If0, the next job will be rejected with429. - Network errors: in case of a network error during polling, wait and retry — the job continues executing server-side independently.
ready.