Skip to main content

FFmpeg Editor API

Process and transform media using your own FFmpeg command safely on our infrastructure. Submit a job with your media and a command template, then poll the job until it finishes and download the result.

Endpoint

POST /api/uploadposts/ffmpeg/jobs/upload

Headers

NameValueDescription
AuthorizationApikey your-api-key-hereYour API key for authentication.

Parameters

NameTypeRequiredDescription
fileFile (binary)YesMedia file to process.
full_commandStringYesFFmpeg command template that MUST use {input} and {output} placeholders. Example: ffmpeg -y -i {input} -c:v libx264 -crf 23 {output}
output_extensionStringYesDesired output file extension (e.g., mp4, wav, mp3, mov, webm).

Note: If the duration of the input media cannot be detected, the system assumes 60 seconds for quota calculation.

Command Template Rules

For security and reliability, only safe FFmpeg commands are accepted.

  • Use placeholders: {input} (or indexed {input0}, {input1}, …) for input files and {output} for the output file; do not hardcode filenames. The first input can be referenced as {input} or {input0}.
  • Allowed pattern starts with ffmpeg and may include typical flags (e.g., -y, -i, -c:v, -c:a, -r, -b:v, filters, etc.).
  • Blocked characters/constructs to prevent command injection: ;, |, &, $, \``, $(, newlines, carriage returns, and destructive commands like rm/rmdir`.
  • If validation fails, the API returns 400 Bad Request with a helpful message.

Responses

  • 202 Accepted (job created)
{
"success": true,
"job_id": "a97bbb5a-139b-46ca-b893-6e8d303d5934",
"status": "PENDING"
}

Check Job Status

Poll the job until it finishes.

GET /api/uploadposts/ffmpeg/jobs/{job_id}

Example response:

{
"job_id": "a97bbb5a-139b-46ca-b893-6e8d303d5934",
"status": "FINISHED",
"duration_seconds": 120,
"output_extension": "mp4"
}

Statuses: PENDING, PROCESSING, FINISHED, ERROR.

Download Result

When status is FINISHED, download the processed file.

GET /api/uploadposts/ffmpeg/jobs/{job_id}/download

Response headers include the appropriate Content-Type and a Content-Disposition attachment filename (e.g., output.mp4, output.wav). The response body is the binary media.

Example: Convert to MP4 (H.264)

curl \
-H 'Authorization: Apikey your-api-key-here' \
-F 'file=@/path/to/input.mov' \
-F 'full_command=ffmpeg -y -i {input} -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k {output}' \
-F 'output_extension=mp4' \
-X POST https://api.upload-post.com/api/uploadposts/ffmpeg/jobs/upload

Example: Extract Audio to WAV

curl \
-H 'Authorization: Apikey your-api-key-here' \
-F 'file=@/path/to/input.mp4' \
-F 'full_command=ffmpeg -y -i {input} -vn -acodec pcm_s16le -ar 44100 -ac 2 {output}' \
-F 'output_extension=wav' \
-X POST https://api.upload-post.com/api/uploadposts/ffmpeg/jobs/upload

Concatenate/Merge multiple videos (NEW)

The API now supports multiple input files for operations like concatenation. You can use placeholders {input0}, {input1}, {input2}, etc., in full_command.

Option A: Send multiple URLs (JSON endpoint)

curl -X POST https://api.upload-post.com/api/uploadposts/ffmpeg/jobs \
-H 'Content-Type: application/json' \
-H 'Authorization: Apikey your-api-key-here' \
-d '{
"files": [
"https://tu-cdn.com/video1.mp4",
"https://tu-cdn.com/video2.mp4",
"https://tu-cdn.com/video3.mp4"
],
"full_command": "ffmpeg -y -hide_banner -i {input0} -i {input1} -i {input2} -filter_complex \"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]\" -map \"[outv]\" -map \"[outa]\" -c:v h264_nvenc -preset p5 -cq 23 -c:a aac -b:a 128k {output}",
"output_extension": "mp4",
"publish": true
}'

Option B: Upload multiple files (multipart/form-data)

curl -X POST https://api.upload-post.com/api/uploadposts/ffmpeg/jobs/upload \
-H 'Authorization: Apikey your-api-key-here' \
-F "file=@/ruta/video1.mp4" \
-F "file1=@/ruta/video2.mp4" \
-F "file2=@/ruta/video3.mp4" \
-F 'full_command=ffmpeg -y -hide_banner -i {input0} -i {input1} -i {input2} -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" -c:v h264_nvenc -preset p5 -cq 23 -c:a aac -b:a 128k {output}' \
-F "output_extension=mp4" \
-F "publish=true"

Concatenation examples

Simple concatenation (2 videos):

{
"files": ["https://cdn.com/part1.mp4", "https://cdn.com/part2.mp4"],
"full_command": "ffmpeg -y -i {input0} -i {input1} -filter_complex \"[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]\" -map \"[v]\" -map \"[a]\" -c:v h264_nvenc -cq 23 -c:a aac {output}",
"output_extension": "mp4"
}

Concatenation with re-encoding (multiple videos):

{
"files": [
"https://cdn.com/intro.mp4",
"https://cdn.com/contenido.mp4",
"https://cdn.com/outro.mp4"
],
"full_command": "ffmpeg -y -hwaccel cuda -i {input0} -i {input1} -i {input2} -filter_complex \"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]\" -map \"[outv]\" -map \"[outa]\" -c:v h264_nvenc -preset p5 -rc vbr -cq 23 -b:v 4M -c:a aac -b:a 128k {output}",
"output_extension": "mp4"
}

Using the concat demuxer (no re-encoding — faster but requires identical formats):

First create a text file with the list of videos, upload it as file and the videos as file1, file2, etc.:

# Create list (concat-list.txt)
echo "file '/work/.../in-src-0'" > concat-list.txt
echo "file '/work/.../in-src-1'" >> concat-list.txt
echo "file '/work/.../in-src-2'" >> concat-list.txt

# Note: For this method you'll need to adjust paths in the command or use the filter_complex method above

Important: The {input} placeholder still works as before (points to the first file). For multiple inputs, use {input0}, {input1}, {input2}, etc.

Limitation: The predefined presets (h264_social, hevc_social, copy_mux) and ffmpeg_args only support a single file. For multiple inputs, you must use full_command.

Quotas by Plan (minutes of media/month)

PlanMinutes/Month
free30
basic300
professional1000
advanced3000
business10000

Resets on the 1st of each month at 00:00 UTC.

Errors

  • 400 Bad Request: Invalid or unsafe FFmpeg command, missing parameters.
  • 401 Unauthorized: Invalid or expired API key.
  • 404 Not Found: Job not found.
  • 429 Too Many Requests: Monthly quota exceeded (response includes current usage when applicable).
  • 500 Internal Server Error: Processing error.

Notes

  • Jobs are asynchronous; always poll the job status before attempting to download the output.
  • Quota checks use detected media duration to ensure fair usage across plans.