API DocsRequest

Making API Requests

The FFmpeg API accepts requests to process media files using FFmpeg commands. All requests are made to the main endpoint with file uploads and command parameters.

Endpoint

POST https://api.ffmpeg-api.com/ffmpeg/run

Request Format

The API uses multipart/form-data for file uploads and accepts the following parameters:

Required Parameters

ParameterTypeDescription
commandJSON stringFFmpeg command structure with inputs and outputs
File uploadsFileMedia files referenced in the command

Headers

KeyValueRequired
AuthorizationBasic <Your Auth Key>Yes
Content-Typemultipart/form-dataAutomatically set by curl

Command Structure

The command parameter must be a JSON string with the following structure:

{
  "inputs": [
    {
      "options": [],
      "file": "input_filename"
    }
  ],
  "outputs": [
    {
      "options": [],
      "file": "output_filename",
      "maps": []
    }
  ],
  "filter_complex": "optional_filter_graph"
}

Input Object

  • options: Array of FFmpeg input options applied before the input file
    • Format: ["-option", "value", "-another_option", "value"]
    • Examples: ["-ss", "00:00:10"] (seek to 10 seconds), ["-t", "30"] (duration of 30 seconds)
  • file: Filename that exactly matches the uploaded file parameter name

Output Object

  • options: Array of FFmpeg output options applied to the output file
    • Format: ["-option", "value", "-another_option", "value"]
    • Examples: ["-c:v", "libx264", "-crf", "23"] (H.264 codec with quality 23)
  • file: Desired output filename (will be available for download)
  • maps: (Optional) Array of stream mapping specifiers
    • Format: ["input_index:stream_type:stream_index"]
    • Examples: ["0:v"] (video from first input), ["1:a:2"] (third audio track from second input)
    • Can also reference filter outputs: ["[filter_label]"]

Filter Complex

  • filter_complex: (Optional) FFmpeg filter graph for advanced video/audio processing
    • Used for operations like scaling, overlay, concatenation, side-by-side videos
    • Filter outputs can be referenced in output maps using labels like [out]
    • Example: "[0:v]scale=1920:1080[v1];[1:v]scale=1920:1080[v2];[v1][v2]hstack[out]"

Example Requests

Basic GIF to MP4 Conversion

Request Data:

  • File: input.gif (your GIF file)
  • Command: {"inputs":[{"options":[],"file":"input.gif"}],"outputs":[{"options":[],"file":"output.mp4"}]}

cURL Example:

curl -F "input.gif=@/path/to/your/file.gif" \
  https://api.ffmpeg-api.com/ffmpeg/run \
  -H 'Authorization: Basic YOUR_AUTH_KEY_HERE' \
  -F 'command={"inputs":[{"options":[],"file":"input.gif"}],"outputs":[{"options":[],"file":"output.mp4"}]}'

Video with Custom Options

Request Data:

  • File: video.mp4 (your video file)
  • Command: {"inputs":[{"options":["-ss","00:00:10","-t","30"],"file":"video.mp4"}],"outputs":[{"options":["-c:v","libx264","-crf","23"],"file":"output.mp4"}]}

cURL Example:

curl -F "video.mp4=@/path/to/video.mp4" \
  https://api.ffmpeg-api.com/ffmpeg/run \
  -H 'Authorization: Basic YOUR_AUTH_KEY_HERE' \
  -F 'command={"inputs":[{"options":["-ss","00:00:10","-t","30"],"file":"video.mp4"}],"outputs":[{"options":["-c:v","libx264","-crf","23"],"file":"output.mp4"}]}'

Multiple Input Files

Request Data:

  • Files: video.mp4, audio.mp3
  • Command: {"inputs":[{"options":[],"file":"video.mp4"},{"options":[],"file":"audio.mp3"}],"outputs":[{"options":["-c:v","copy","-c:a","aac"],"file":"output.mp4"}]}

cURL Example:

curl -F "video.mp4=@/path/to/video.mp4" \
  -F "audio.mp3=@/path/to/audio.mp3" \
  https://api.ffmpeg-api.com/ffmpeg/run \
  -H 'Authorization: Basic YOUR_AUTH_KEY_HERE' \
  -F 'command={"inputs":[{"options":[],"file":"video.mp4"},{"options":[],"file":"audio.mp3"}],"outputs":[{"options":["-c:v","copy","-c:a","aac"],"file":"output.mp4"}]}'

Stream Mapping with Maps

Extract specific streams from inputs into separate output files:

Request Data:

  • File: movie.mkv (contains multiple video and audio tracks)
  • Command: Extract video-only and specific audio track
{
  "inputs": [{"file": "movie.mkv", "options": []}],
  "outputs": [
    {
      "options": ["-c:v", "libx264", "-crf", "23"],
      "file": "video_only.mp4",
      "maps": ["0:v:0"]
    },
    {
      "options": ["-c:a", "aac", "-b:a", "128k"],
      "file": "audio_track2.m4a",
      "maps": ["0:a:1"]
    }
  ]
}

Filter Complex for Side-by-Side Video

Combine two videos side by side using filter_complex:

Request Data:

  • Files: left_video.mp4, right_video.mp4
  • Command: Scale both videos and place them side by side
{
  "inputs": [
    {"file": "left_video.mp4", "options": []},
    {"file": "right_video.mp4", "options": []}
  ],
  "filter_complex": "[0:v]scale=960:540[left];[1:v]scale=960:540[right];[left][right]hstack[out]",
  "outputs": [
    {
      "file": "side_by_side.mp4",
      "options": ["-c:v", "libx264", "-preset", "medium"],
      "maps": ["[out]"]
    }
  ]
}

Advanced Options Usage

Trimming and Quality Control:

{
  "inputs": [
    {
      "file": "input.mp4",
      "options": ["-ss", "00:01:30", "-t", "00:02:00"]
    }
  ],
  "outputs": [
    {
      "file": "trimmed_high_quality.mp4",
      "options": [
        "-c:v", "libx264",
        "-crf", "18",
        "-preset", "slow",
        "-c:a", "aac",
        "-b:a", "192k"
      ]
    }
  ]
}

Multiple Output Formats:

{
  "inputs": [{"file": "source.mp4", "options": []}],
  "outputs": [
    {
      "file": "compressed.mp4",
      "options": ["-c:v", "libx264", "-crf", "28", "-c:a", "aac"]
    },
    {
      "file": "thumbnail.jpg",
      "options": ["-vf", "scale=320:240", "-vframes", "1", "-ss", "00:00:05"]
    }
  ]
}

File Upload Guidelines

ℹ️

File parameter names in the request must exactly match the file field in your command’s inputs.

File Upload Requirements

  1. Parameter names: Must match the file field in your command inputs
  2. File paths: Any accessible file path (implementation depends on your tool/language)
  3. Multiple files: Upload all files referenced in your command’s inputs

File Size Limits

  • Maximum file size: 100MB per file (will be increased in the future)

Response Format

Success Response

{
  "ok": true,
  "result": [
    {
      "file": "https://.../output.mp4?...",
      "size": 104897
    }
  ]
}

Response Fields:

  • ok: Boolean indicating request success
  • result: Array of output files
  • result[].file: Signed URL to download the processed file (valid for 1 hour)
  • result[].size: File size in bytes

Error Response

{
  "ok": false,
  "error": "Error message describing what went wrong"
}

Best Practices

⚠️

Always validate your FFmpeg command locally before sending it to the API to avoid unnecessary usage charges.

Error Prevention

  1. Check file formats: Ensure input files are in supported formats
  2. Validate paths: Use absolute paths for file uploads
  3. Test commands: Validate FFmpeg syntax before API calls
  4. Handle timeouts: Implement retry logic for large file processing

Language-Specific Examples

Python (requests)

Basic conversion:

import requests
import json
 
files = {
    'input.gif': open('/path/to/file.gif', 'rb'),
    'command': (None, json.dumps({
        "inputs": [{"options": [], "file": "input.gif"}],
        "outputs": [{"options": [], "file": "output.mp4"}]
    }))
}
 
headers = {
    'Authorization': 'Basic YOUR_AUTH_KEY_HERE'
}
 
response = requests.post(
    'https://api.ffmpeg-api.com/ffmpeg/run',
    files=files,
    headers=headers
)
 
result = response.json()
if result['ok']:
    output_url = result['result'][0]['file']
    print(f"Download your file: {output_url}")

Advanced example with stream mapping:

import requests
import json
 
# Extract audio track and create thumbnail
command = {
    "inputs": [
        {
            "file": "movie.mp4",
            "options": []
        }
    ],
    "outputs": [
        {
            "file": "audio_only.m4a",
            "options": ["-c:a", "aac", "-b:a", "128k"],
            "maps": ["0:a:0"]
        },
        {
            "file": "thumbnail.jpg",
            "options": ["-vf", "scale=320:240", "-vframes", "1", "-ss", "00:00:10"],
            "maps": ["0:v:0"]
        }
    ]
}
 
files = {
    'movie.mp4': open('/path/to/movie.mp4', 'rb'),
    'command': (None, json.dumps(command))
}
 
response = requests.post(
    'https://api.ffmpeg-api.com/ffmpeg/run',
    files=files,
    headers={'Authorization': 'Basic YOUR_AUTH_KEY_HERE'}
)
 
result = response.json()
if result['ok']:
    for output in result['result']:
        print(f"Download: {output['file']} ({output['size']} bytes)")

JavaScript (Node.js)

Basic conversion:

const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
 
const form = new FormData();
form.append('input.gif', fs.createReadStream('/path/to/file.gif'));
form.append('command', JSON.stringify({
    inputs: [{ options: [], file: 'input.gif' }],
    outputs: [{ options: [], file: 'output.mp4' }]
}));
 
const response = await fetch('https://api.ffmpeg-api.com/ffmpeg/run', {
    method: 'POST',
    headers: {
        'Authorization': 'Basic YOUR_AUTH_KEY_HERE',
        ...form.getHeaders()
    },
    body: form
});
 
const result = await response.json();
if (result.ok) {
    const outputUrl = result.result[0].file;
    console.log(`Download your file: ${outputUrl}`);
}

Side-by-side video with filter_complex:

const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
 
// Create side-by-side video using filter_complex
const command = {
    inputs: [
        { file: 'video1.mp4', options: [] },
        { file: 'video2.mp4', options: [] }
    ],
    filter_complex: '[0:v]scale=640:360[left];[1:v]scale=640:360[right];[left][right]hstack[out]',
    outputs: [
        {
            file: 'combined.mp4',
            options: ['-c:v', 'libx264', '-preset', 'medium', '-crf', '23'],
            maps: ['[out]']
        }
    ]
};
 
const form = new FormData();
form.append('video1.mp4', fs.createReadStream('/path/to/video1.mp4'));
form.append('video2.mp4', fs.createReadStream('/path/to/video2.mp4'));
form.append('command', JSON.stringify(command));
 
const response = await fetch('https://api.ffmpeg-api.com/ffmpeg/run', {
    method: 'POST',
    headers: {
        'Authorization': 'Basic YOUR_AUTH_KEY_HERE',
        ...form.getHeaders()
    },
    body: form
});
 
const result = await response.json();
if (result.ok) {
    console.log(`Combined video: ${result.result[0].file}`);
}

PHP

Basic conversion:

<?php
$ch = curl_init();
 
$postFields = [
    'input.gif' => new CURLFile('/path/to/file.gif'),
    'command' => json_encode([
        'inputs' => [['options' => [], 'file' => 'input.gif']],
        'outputs' => [['options' => [], 'file' => 'output.mp4']]
    ])
];
 
curl_setopt($ch, CURLOPT_URL, 'https://api.ffmpeg-api.com/ffmpeg/run');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Basic YOUR_AUTH_KEY_HERE'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
$response = curl_exec($ch);
$result = json_decode($response, true);
 
if ($result['ok']) {
    $outputUrl = $result['result'][0]['file'];
    echo "Download your file: " . $outputUrl;
}
curl_close($ch);
?>

Advanced example with stream mapping:

<?php
// Extract specific audio and video streams
$command = [
    'inputs' => [
        ['file' => 'movie.mkv', 'options' => []]
    ],
    'outputs' => [
        [
            'file' => 'video_only.mp4',
            'options' => ['-c:v', 'libx264', '-crf', '23'],
            'maps' => ['0:v:0']
        ],
        [
            'file' => 'audio_only.aac',
            'options' => ['-c:a', 'aac', '-b:a', '128k'],
            'maps' => ['0:a:1']
        ]
    ]
];
 
$ch = curl_init();
$postFields = [
    'movie.mkv' => new CURLFile('/path/to/movie.mkv'),
    'command' => json_encode($command)
];
 
curl_setopt($ch, CURLOPT_URL, 'https://api.ffmpeg-api.com/ffmpeg/run');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Basic YOUR_AUTH_KEY_HERE'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
$response = curl_exec($ch);
$result = json_decode($response, true);
 
if ($result['ok']) {
    foreach ($result['result'] as $output) {
        echo "Download: " . $output['file'] . " (" . $output['size'] . " bytes)\n";
    }
}
curl_close($ch);
?>

Other Tools

HTTPie:

Basic conversion:

http --form POST https://api.ffmpeg-api.com/ffmpeg/run \
    'Authorization:Basic YOUR_AUTH_KEY_HERE' \
    input.gif@/path/to/file.gif \
    command='{"inputs":[{"options":[],"file":"input.gif"}],"outputs":[{"options":[],"file":"output.mp4"}]}'

Video overlay with filter_complex:

http --form POST https://api.ffmpeg-api.com/ffmpeg/run \
    'Authorization:Basic YOUR_AUTH_KEY_HERE' \
    background.mp4@/path/to/background.mp4 \
    overlay.png@/path/to/overlay.png \
    command='{"inputs":[{"file":"background.mp4","options":[]},{"file":"overlay.png","options":["-loop","1"]}],"filter_complex":"[1:v]scale=200:100[ovrl];[0:v][ovrl]overlay=10:10[out]","outputs":[{"file":"result.mp4","options":["-c:v","libx264","-t","10"],"maps":["[out]"]}]}'

Postman:

  • Method: POST
  • URL: https://api.ffmpeg-api.com/ffmpeg/run
  • Headers: Authorization: Basic YOUR_AUTH_KEY_HERE
  • Body: form-data with file upload and command field
ℹ️

For more examples and use cases, check out our FFmpeg recipes section.