On this page
DocsRaw ffmpeg
Migrating from Rendi
Move Rendi run-ffmpeg-command calls to Videxo jobs: the same aliases, a different endpoint, header and response.
Rendi and Videxo both run an ffmpeg command over files named by aliases, so most commands move as they are. What changes is the endpoint, the key header, a field name and the shape of the response. This page compares with Rendi's public API reference as of 2026-11-05.
The request#
| Rendi | Videxo | |
|---|---|---|
| Endpoint | POST https://api.rendi.dev/v1/run-ffmpeg-command | POST VIDEXO_API_URL/v1/jobs |
| Key | X-API-KEY: <key> | Authorization: Bearer <key> |
| Inputs | input_files, aliases in_... | input_files, aliases in_... |
| Outputs | output_files, aliases out_... | output_files, aliases out_... |
| Command | ffmpeg_command | command |
| In the command | {{in_1}}, {{out_1}} | {{in_1}}, {{out_1}} |
| Your own data | metadata | metadata |
So a Rendi body becomes a Videxo body by renaming ffmpeg_command to command. Our aliases are
in_ or out_ and 1 to 48 letters, digits or underscores, and an input is an http or https
URL or a completed upload. Rendi's vcpu_count and max_command_run_seconds have no
field here: your plan sets the longest job (Limits per plan), and a body with an
unknown field is rejected.
Before you switch, check each command against the command rules: the MCP tool
check_command does it without an API key, and POST /v1/jobs returns 400 command_invalid with
the reason when a command uses an option, filter or format that is not allowed.
curl "$VIDEXO_API_URL/v1/jobs" \
-H "Authorization: Bearer $VIDEXO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_files": {
"in_video": "https://videxo.io/samples/talk.mp4"
},
"output_files": {
"out_main": "talk-720p.mp4"
},
"command": "-i {{in_video}} -vf scale=-2:720 -c:v libx264 -crf 23 -c:a copy {{out_main}}",
"metadata": {
"order": "1234"
}
}'Copy failed. The text is selected; copy it with your keyboard.
const response = await fetch(`${process.env.VIDEXO_API_URL}/v1/jobs`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VIDEXO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"input_files": {
"in_video": "https://videxo.io/samples/talk.mp4"
},
"output_files": {
"out_main": "talk-720p.mp4"
},
"command": "-i {{in_video}} -vf scale=-2:720 -c:v libx264 -crf 23 -c:a copy {{out_main}}",
"metadata": {
"order": "1234"
}
}),
});
const job = await response.json();Copy failed. The text is selected; copy it with your keyboard.
The response#
Rendi returns a command_id and you poll GET /v1/commands/{command_id}. Videxo returns 202
with the whole job, and you poll GET /v1/jobs/{id} (Jobs and their states):
Rendi status | Videxo state |
|---|---|
QUEUED | queued |
PROCESSING | running |
SUCCESS | succeeded |
FAILED | failed |
A job can also be cancelled with POST /v1/jobs/{id}/cancel. Outputs are listed in outputs
with their filename, size_bytes (bytes, where Rendi gives size_mbytes), sha256 and a signed
download_url that lasts up to one hour, in place of Rendi's storage_url. Read the job again for
a fresh link.
Webhooks#
Both send a webhook when a job ends. Ours follow Standard Webhooks: the body carries the whole job,
and the webhook-signature header lets you check it came from us (Webhooks).
Set webhook_url on the job, or a default endpoint for the account on the dashboard's Webhooks
page.
Chained commands#
Rendi's run-chained-ffmpeg-commands runs up to 10 commands where a later one reads an earlier
one's output. A Videxo job is one ffmpeg run. One command with several outputs, or a JSON job
with a list of outputs (Operations), covers the common case of several files
from one input, and fetches the input once.