API Documentation

Complete guide to using the FFMPEG Video Processing API

Overview

The FFMPEG Video Merger API provides three powerful video processing capabilities:

Image + Audio

Create videos by combining static images with audio files

Video Merge

Concatenate multiple videos from URLs into one seamless video

Picture in Picture

Overlay one video on top of another with customizable positioning

Base URL: https://ffmpegapi.net/api/

Authentication

All API endpoints require authentication using API keys. You can provide your API key in three ways:

Header (Recommended)
X-API-Key: your_api_key_here
Query Parameter
?api_key=your_api_key_here
Form Data
api_key=your_api_key_here
Need an API Key? Sign up for free to get your API key.

Async Processing

For long-running video processing tasks that may take several minutes, you can use async processing to avoid timeouts and improve user experience.

How it works: Add "async": true to your request JSON to process jobs in the background. You'll receive a job_id immediately and can check progress using the job status endpoint.
Sync Processing (Default)
  • Process immediately
  • Get result in same response
  • May timeout for large files
Async Processing
  • No timeout issues
  • Better for large files
  • Check progress anytime
Job Status Values
Status Description
pending Job is queued and waiting to be processed
processing Job is currently being processed
completed Job finished successfully, download URL available
failed Job failed, error message available

API Endpoints

Image & Audio Merge

POST
/api/merge_image_audio

Create a video by combining a static image with an audio file from URLs. The image will be displayed for the duration of the audio. Supports async processing for large files.

Request Format

Content-Type: application/json

Parameters
Parameter Type Required Description
image String Yes URL to image file (PNG, JPG, JPEG)
audio String Yes URL to audio file (MP3, WAV, M4A)
async Boolean No Process job asynchronously (default: false)
Request Example
{
  "image": "https://example.com/image.jpg",
  "audio": "https://example.com/audio.mp3",
  "async": true
}
Sync Response
{
  "success": true,
  "message": "Video created successfully",
  "download_url": "https://ffmpegapi.net/download/filename.mp4",
  "filename": "unique_filename.mp4"
}
Async Response
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
  "status_url": "https://ffmpegapi.net/api/job/550e8400-e29b-41d4-a716-446655440000/status"
}

Video Merge

POST
/api/merge_videos

Concatenate multiple videos from URLs into a single video. All videos should have the same aspect ratio for best results.

Request Format

Content-Type: application/json

Parameters
Parameter Type Required Description
video_urls Array Yes Array of video URLs (minimum 2 required)
audio_url String No Optional audio URL to replace original audio
async Boolean No Process job asynchronously (default: false)
Request Example
{
  "video_urls": [
    "https://example.com/video1.mp4",
    "https://example.com/video2.mp4",
    "https://example.com/video3.mp4"
  ],
  "audio_url": "https://example.com/audio.mp3",
  "async": true
}
Sync Response
{
  "success": true,
  "message": "Videos merged successfully",
  "download_url": "https://ffmpegapi.net/download/merged_filename.mp4",
  "filename": "unique_merged_filename.mp4"
}
Async Response
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
  "status_url": "https://ffmpegapi.net/api/job/550e8400-e29b-41d4-a716-446655440000/status"
}

Picture in Picture

POST
/api/picture_in_picture

Create a picture-in-picture video by overlaying one video on top of another with customizable positioning and scaling.

Request Format

Content-Type: application/json

Parameters
Parameter Type Required Description
main_video_url String Yes URL of the main background video
pip_video_url String Yes URL of the video to overlay (picture-in-picture)
position String No Position of overlay. Options: top-left, top-center, top-right, middle-left, middle, middle-right, bottom-left, bottom-center, bottom-right. Default: bottom-right
scale String No Scale of overlay video. Options: iw/4:ih/4 (quarter), iw/3:ih/3 (third), iw/2:ih/2 (half). Default: iw/4:ih/4
audio_option String No Audio source for final video. Options: video1 (main video audio), video2 (overlay video audio), mute (no audio). Default: video1
async Boolean No Process job asynchronously (default: false)
Request Example
{
  "main_video_url": "https://example.com/main-video.mp4",
  "pip_video_url": "https://example.com/overlay-video.mp4",
  "position": "top-right",
  "scale": "iw/3:ih/3",
  "audio_option": "video2",
  "async": true
}
Response
{
  "success": true,
  "message": "Picture-in-picture video created successfully",
  "download_url": "https://ffmpegapi.net/download/pip_filename.mp4",
  "filename": "unique_pip_filename.mp4"
}
Async Response
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
  "status_url": "https://ffmpegapi.net/api/job/550e8400-e29b-41d4-a716-446655440000/status"
}

Job Status

GET
/api/job/{job_id}/status

Check the status of an asynchronous job. Use this endpoint to monitor the progress of jobs submitted with async: true.

Parameters
Parameter Type Required Description
job_id String Yes Job ID returned when submitting async request
Request Example
curl -X GET "https://ffmpegapi.net/api/job/550e8400-e29b-41d4-a716-446655440000/status" \
  -H "X-API-Key: your_api_key_here"
Response Examples
Pending Job
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_type": "merge_image_audio",
  "status": "pending",
  "created_at": "2025-08-19T22:00:00.000Z",
  "updated_at": "2025-08-19T22:00:00.000Z"
}
Processing Job
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_type": "merge_image_audio",
  "status": "processing",
  "created_at": "2025-08-19T22:00:00.000Z",
  "updated_at": "2025-08-19T22:01:30.000Z"
}
Completed Job
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_type": "merge_image_audio",
  "status": "completed",
  "created_at": "2025-08-19T22:00:00.000Z",
  "updated_at": "2025-08-19T22:03:45.000Z",
  "message": "Video created successfully",
  "download_url": "https://ffmpegapi.net/download/filename.mp4",
  "filename": "unique_filename.mp4"
}
Failed Job
{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "job_type": "merge_image_audio",
  "status": "failed",
  "created_at": "2025-08-19T22:00:00.000Z",
  "updated_at": "2025-08-19T22:02:15.000Z",
  "error": "Failed to download image: Invalid URL"
}

Error Handling

All endpoints return consistent error responses with appropriate HTTP status codes.

Authentication Error (401)
{
  "success": false,
  "error": "API key is required"
}
Validation Error (400)
{
  "success": false,
  "error": "Both image and audio files are required"
}
File Too Large (413)
{
  "success": false,
  "error": "File too large. Maximum file size is 100MB."
}
Processing Error (500)
{
  "success": false,
  "error": "FFMPEG processing failed: [details]"
}

Code Examples

Image & Audio Merge
curl -X POST "https://ffmpegapi.net/api/merge_image_audio" \
  -H "X-API-Key: your_api_key_here" \
  -F "image=@/path/to/image.jpg" \
  -F "audio=@/path/to/audio.mp3"
Video Merge
curl -X POST "https://ffmpegapi.net/api/merge_videos" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "video_urls": [
      "https://example.com/video1.mp4",
      "https://example.com/video2.mp4"
    ]
  }'
Picture in Picture
curl -X POST "https://ffmpegapi.net/api/picture_in_picture" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "main_video_url": "https://example.com/main.mp4",
    "pip_video_url": "https://example.com/overlay.mp4",
    "position": "top-right",
    "scale": "iw/4:ih/4"
  }'
Image & Audio Merge
import requests

url = "https://ffmpegapi.net/api/merge_image_audio"
headers = {"X-API-Key": "your_api_key_here"}

with open("image.jpg", "rb") as img, open("audio.mp3", "rb") as aud:
    files = {
        "image": img,
        "audio": aud
    }
    response = requests.post(url, headers=headers, files=files)
    
if response.status_code == 200:
    result = response.json()
    download_url = result["download_url"]
    print(f"Video created: {download_url}")
else:
    print(f"Error: {response.json()['error']}")
Video Merge
import requests
import json

url = "https://ffmpegapi.net/api/merge_videos"
headers = {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here"
}
data = {
    "video_urls": [
        "https://example.com/video1.mp4",
        "https://example.com/video2.mp4"
    ]
}

response = requests.post(url, headers=headers, json=data)

if response.status_code == 200:
    result = response.json()
    download_url = result["download_url"]
    print(f"Videos merged: {download_url}")
else:
    print(f"Error: {response.json()['error']}")
Picture in Picture
import requests

url = "https://ffmpegapi.net/api/picture_in_picture"
headers = {
    "Content-Type": "application/json",
    "X-API-Key": "your_api_key_here"
}
data = {
    "main_video_url": "https://example.com/main.mp4",
    "pip_video_url": "https://example.com/overlay.mp4",
    "position": "top-right",
    "scale": "iw/4:ih/4"
}

response = requests.post(url, headers=headers, json=data)

if response.status_code == 200:
    result = response.json()
    download_url = result["download_url"]
    print(f"PiP video created: {download_url}")
else:
    print(f"Error: {response.json()['error']}")
Image & Audio Merge
const formData = new FormData();
formData.append('image', imageFile);
formData.append('audio', audioFile);

const response = await fetch('https://ffmpegapi.net/api/merge_image_audio', {
    method: 'POST',
    headers: {
        'X-API-Key': 'your_api_key_here'
    },
    body: formData
});

const result = await response.json();

if (result.success) {
    console.log('Video created:', result.download_url);
} else {
    console.error('Error:', result.error);
}
Video Merge
const data = {
    video_urls: [
        'https://example.com/video1.mp4',
        'https://example.com/video2.mp4'
    ]
};

const response = await fetch('https://ffmpegapi.net/api/merge_videos', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'your_api_key_here'
    },
    body: JSON.stringify(data)
});

const result = await response.json();

if (result.success) {
    console.log('Videos merged:', result.download_url);
} else {
    console.error('Error:', result.error);
}
Picture in Picture
const data = {
    main_video_url: 'https://example.com/main.mp4',
    pip_video_url: 'https://example.com/overlay.mp4',
    position: 'top-right',
    scale: 'iw/4:ih/4',
    audio_option: 'video1'  // Options: 'video1', 'video2', 'mute'
};

const response = await fetch('https://ffmpegapi.net/api/picture_in_picture', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'your_api_key_here'
    },
    body: JSON.stringify(data)
});

const result = await response.json();

if (result.success) {
    console.log('PiP video created:', result.download_url);
} else {
    console.error('Error:', result.error);
}

Rate Limits & Guidelines

Processing Times
  • Image + Audio: 1-5 minutes
  • Video Merge: 2-10 minutes
  • Picture in Picture: 3-15 minutes
Processing time depends on file sizes and complexity
File Limits
  • Max file size: 100MB per file
  • Supported image formats: PNG, JPG, JPEG
  • Supported audio formats: MP3, WAV, M4A
  • Supported video formats: MP4, WebM, MOV
Best Practices: For video merging, ensure all videos have the same resolution and aspect ratio. For picture-in-picture, the overlay video should be smaller than the main video for best results.

Need help? Questions about the API? try the web interface first.