API DocsAPI Reference

API Reference

Complete reference for all FFmpeg API endpoints. Quick to scan, easy to implement.

📚 Complete OpenAPI Specification

Machine-readable API spec for code generation and testing

Download OpenAPI →

Base URL & Authentication

Base URL: https://api.ffmpeg-api.com

Authentication: All endpoints require Basic Auth header with your API key:

Authorization: Basic YOUR_API_KEY
🔑

Get your API header from the Dashboard. It comes pre-formatted as Basic abc123...

🎬 Processing Endpoints

POST /ffmpeg/process

Transform media files using FFmpeg commands. Inputs can be uploaded files or direct HTTPS URLs.

POST /ffmpeg/processCore Endpoint

Request Body

{
"task": {
  "inputs": [
    {
      "file_path": "dir_abc123/input.mp4",
      "options": ["-ss", "10", "-t", "30"]
    }
  ],
  "outputs": [
    {
      "file": "output.mp4",
      "options": ["-crf", "23", "-preset", "medium"],
      "maps": ["0:v", "0:a"]
    }
  ],
  "filter_complex": "[0:v]scale=1280:720[out]",
  "output_dir_id": "dir_abc123"
}
}
Required Fields
  • task.inputs[] - Input files array
  • task.outputs[] - Output specifications
  • inputs[].file_path - dir_id/filename or HTTPS URL
  • outputs[].file - Output filename
Optional Fields
  • inputs[].options[] - Input FFmpeg options
  • outputs[].options[] - Output FFmpeg options
  • outputs[].maps[] - Stream mappings
  • filter_complex - Filter graph string
  • output_dir_id - Target directory for outputs
URL Input Support

file_path accepts HTTPS URLs directly. URLs are imported to storage before processing.

  • • Must be HTTPS (HTTP not allowed)
  • • Subject to same file size limits as uploads
  • • Private/localhost URLs blocked for security
Directory Resolution

Outputs are stored in a directory determined by (in priority order):

  1. output_dir_id if provided
  2. Directory from dir_id/filename inputs
  3. Auto-created temporary directory (for URL-only inputs)

Response

{
"ok": true,
"result": [
  {
    "file_name": "output.mp4",
    "size_bytes": 1234567,
    "download_url": "https://storage.example.com/result.mp4"
  }
],
"usage": {
  "time_sec": 12.5,
  "input_size_gb": 0.098,
  "output_size_gb": 0.015,
  "gb_sec": 1.4125
}
}

Important: All input files must be in the same directory. Output filenames cannot conflict with existing input files.

POST /ffmpeg/run [Deprecated]

Legacy endpoint for multipart uploads.

⚠️

This endpoint is deprecated and will be removed by Feb 28th, 2026. Use POST /ffmpeg/process instead.

⚠️

Migration Required

This endpoint is deprecated. See the Migration Guide for updating your code.

POST /ffmpeg/process/async

Submit an FFmpeg task for asynchronous (background) processing. Returns immediately with a job ID. Inputs can be uploaded files or direct HTTPS URLs.

POST /ffmpeg/process/asyncAsync

Request Body

{
"task": {
  "inputs": [{ "file_path": "dir_abc123/input.mp4" }],
  "outputs": [{ "file": "output.mp4", "options": ["-crf", "23"] }],
  "output_dir_id": "dir_abc123"
},
"webhook_url": "https://yoursite.com/callback"
}
Required Fields
  • task - Same structure as /ffmpeg/process
  • inputs[].file_path - dir_id/filename or HTTPS URL
Optional Fields
  • webhook_url - HTTPS URL for completion callback
  • output_dir_id - Target directory for outputs

URL Inputs: When using URL inputs, files are imported to storage before the job is queued. This ensures URLs remain available when processing starts, even if the original URL expires.

Response (202 Accepted)

{
"ok": true,
"job_id": "job_abc123xyz"
}

Webhook Requirements: Must be HTTPS. Cannot be localhost or private IP addresses. Receives POST with job results when complete.

Webhook Payload - Success

{
"job_id": "job_abc123xyz",
"status": "completed",
"result": [
  {
    "file_name": "output.mp4",
    "size_bytes": 1234567,
    "download_url": "https://storage.example.com/result.mp4"
  }
],
"usage": {
  "time_sec": 12.5,
  "input_size_gb": 0.098,
  "output_size_gb": 0.015,
  "gb_sec": 1.4125
}
}

Webhook Payload - Failure

{
"job_id": "job_abc123xyz",
"status": "failed",
"error": "FFmpeg processing error: Invalid input format"
}

⏳ Job Management Endpoints

GET /job/{jobId}

Check the status of an async processing job.

GET /job/{jobId}

URL Parameters

jobId - The job ID returned from /ffmpeg/process/async

Response - Pending/Processing

{
"ok": true,
"job_id": "job_abc123xyz",
"status": "pending"  // or "processing"
}

Response - Completed

{
"ok": true,
"job_id": "job_abc123xyz",
"status": "completed",
"result": [
  {
    "file_name": "output.mp4",
    "size_bytes": 1234567,
    "download_url": "https://storage.example.com/result.mp4"
  }
],
"usage": {
  "time_sec": 12.5,
  "input_size_gb": 0.098,
  "output_size_gb": 0.015,
  "gb_sec": 1.4125
}
}

Response - Failed

{
"ok": false,
"job_id": "job_abc123xyz",
"status": "failed",
"error": "FFmpeg processing error: Invalid input format"
}
Job Statuses
pending
processing
completed
failed

DELETE /job/{jobId}

Cancel a pending job. Only jobs in pending status can be cancelled.

DELETE /job/{jobId}

URL Parameters

jobId - The job ID to cancel

Response (200 OK)

{
"ok": true,
"message": "Job cancelled successfully"
}

Error Response (409 Conflict)

{
"ok": false,
"error": "Cannot cancel job in 'processing' status. Only pending jobs can be cancelled."
}

Note: Jobs already in processing, completed, or failed status cannot be cancelled.

🔍 Analysis Endpoints

POST /ffprobe/analyze

Analyze media metadata using FFprobe. Extract technical information about files including format details, stream properties, and frame/packet data. Supports both uploaded files and direct HTTPS URLs.

POST /ffprobe/analyzeAnalysis

Request Body

{
"file_path": "dir_abc123/video.mp4",
"probe": {
  "format": ["duration", "size", "bit_rate"],
  "streams": ["codec_name", "width", "height", "sample_rate"],
  "select_streams": "v:0"
}
}
Required Fields
  • file_path - dir_id/filename or HTTPS URL
Optional Fields
  • probe.format[] - Format fields to return
  • probe.streams[] - Stream fields to return
  • probe.select_streams - Stream selection (e.g., “v:0”)
  • probe.frames[] - Frame data (requires select_streams)

URL Support: You can analyze files directly from HTTPS URLs without uploading. URLs are analyzed in place (not imported to storage).

Probe Options

Section Arrays
  • format[] - File format info (duration, size, bit_rate)
  • streams[] - Stream properties (codec, dimensions, sample_rate)
  • chapters[] - Chapter information
  • programs[] - Program data (MPEG-TS)
  • frames[] - Frame-level data
  • packets[] - Packet-level data
Control Options
  • select_streams - Stream selector (“v:0”, “a”, “s:1”)
  • read_intervals - Time/frame ranges (“0%+10”, “#500”)
  • count_frames - Count frames without dumping
  • analyzeduration - Analysis time limit (”10s”)
  • probesize - Probe size limit (“10M”)

Response

{
"ok": true,
"result": {
  "format": {
    "duration": "120.5",
    "size": "15728640",
    "bit_rate": "1048576"
  },
  "streams": [
    {
      "codec_name": "h264",
      "width": 1920,
      "height": 1080,
      "sample_rate": "48000"
    }
  ]
},
"usage": {
  "time_sec": 2.1,
  "input_size_gb": 0.015,
  "output_size_gb": 0.0001,
  "gb_sec": 0.0315
}
}

Tip: Empty arrays [] return all fields for that section. Use specific field names to reduce response size.

Important: frames and packets require select_streams to prevent excessive output. Resource limits: 60s max analysis, 50MB max probe size.

📁 File Management Endpoints

POST /file

Register a file and get a secure upload URL.

POST /file

Request Body

{
"file_name": "video.mp4",
"dir_id": "dir_abc123"  // optional
}
Parameters
file_name *required - Filename for the uploaded file
dir_id optional - Directory ID (creates temp directory if omitted)

Response

{
"ok": true,
"file": {
  "dir_id": "dir_abc123",
  "file_name": "video.mp4",
  "file_path": "dir_abc123/video.mp4",
  "added_on": "2024-01-01T00:00:00Z"
},
"upload": {
  "url": "https://presigned-upload-url...",
  "method": "PUT",
  "headers": {},
  "expiresInSeconds": 300
}
}

GET /file/{dirId}/{fileName}

Get file metadata (type and size) for a stored file.

GET /file/{dirId}/{fileName}

URL Parameters

dirId - Directory ID (1-64 chars, A-Z a-z 0-9 _ -)
fileName - File name (1-255 chars, no slashes)

Response

{
"ok": true,
"file_info": {
  "file_path": "dir_abc123/video.mp4",
  "file_type": "video/mp4",
  "file_size": 1048576
}
}

Note: This endpoint requires authentication and returns 404 if the file doesn’t exist or you don’t have access.

GET /file/download/{dirId}/{fileName}

Get a presigned download URL for a stored file. The URL is valid for 5 minutes.

GET /file/download/{dirId}/{fileName}

URL Parameters

dirId - Directory ID (1-64 chars, A-Z a-z 0-9 _ -)
fileName - File name (1-255 chars, no slashes)

Response

{
"ok": true,
"download": {
  "url": "https://presigned-download-url...",
  "method": "GET",
  "expiresInSeconds": 300,
  "file_path": "dir_abc123/video.mp4",
  "file_size": 1048576,
  "file_type": "video/mp4"
}
}

Tip: Use the returned url to download the file directly via GET request. The URL expires after 5 minutes.

Note: This endpoint verifies directory ownership and file existence before generating the download URL. Returns 404 if the file is not found or you don’t have access.

DELETE /file/{dirId}/{fileName}

Delete a file from storage. This operation is irreversible.

DELETE /file/{dirId}/{fileName}

URL Parameters

dirId - Directory ID (1-64 chars, A-Z a-z 0-9 _ -)
fileName - File name (1-255 chars, no slashes)

Response

{
"ok": true,
"deleted": {
  "file_path": "dir_abc123/video.mp4"
}
}

Warning: This operation permanently deletes the file from storage and removes its database record. This action cannot be undone.

POST /directory

Create a temporary working directory (optional for organization).

POST /directory

Request Body

{
"ttl": 86400  // optional, seconds (default: 24 hours)
}

Response

{
"ok": true,
"directory": {
  "id": "dir_abc123",
  "ttl": 86400
}
}

GET /directory

List all your directories.

GET /directory

Response

{
"ok": true,
"directories": [
  {
    "id": "dir_abc123",
    "ttl": 86400,
    "added_on": "2024-01-01T10:00:00Z"
  }
]
}

GET /directory/{dirId}

List files in a specific directory.

GET /directory/{dirId}

URL Parameters

dirId *required - Directory ID to list files from

Response

{
"ok": true,
"files": [
  {
    "file_name": "video.mp4",
    "added_on": "2024-01-01T10:30:00Z"
  },
  {
    "file_name": "audio.wav",
    "added_on": "2024-01-01T10:35:00Z"
  }
]
}

⚠️ Error Responses

All error responses follow the same format:

{
  "ok": false,
  "error": "Descriptive error message"
}

HTTP Status Codes

Client Errors (4xx)

  • 400 Bad Request - Invalid JSON, missing fields
  • 401 Unauthorized - Invalid API key
  • 403 Forbidden - Quota exceeded, expired URL
  • 404 Not Found - File/directory doesn’t exist

Server Errors (5xx)

  • 500 Internal Error - FFmpeg processing failed
  • 502 Bad Gateway - Upstream service issue
  • 503 Service Unavailable - Temporary outage

Common Error Scenarios

400 “Invalid task format”

Common causes:

  • Missing required fields (inputs, outputs)
  • Invalid file_path format
  • Output filename conflicts with input
  • Mixed directories in inputs

401 “Invalid API key”

Check your authentication:

  • API key format: Basic abc123…
  • Header name: Authorization (not Auth)
  • Copy key exactly from dashboard

403 “Upload URL expired”

Upload URLs expire after 5 minutes:

  • Request new upload URL from /file
  • Upload immediately after getting URL
  • Implement retry logic for expired URLs

500 “FFmpeg processing failed”

Processing issues:

  • Invalid FFmpeg options syntax
  • Incompatible input/output formats
  • Complex filter graph errors
  • File corruption or unsupported codec

Quick Examples

Upload and Process

# 1. Register file
curl -X POST https://api.ffmpeg-api.com/file \\
  -H "Authorization: Basic YOUR_API_KEY" \\
  -d '{"file_name":"video.mp4"}'
 
# 2. Upload to presigned URL
curl -X PUT "$UPLOAD_URL" --data-binary @video.mp4
 
# 3. Process
curl -X POST https://api.ffmpeg-api.com/ffmpeg/process \\
  -H "Authorization: Basic YOUR_API_KEY" \\
  -d '{"task":{"inputs":[{"file_path":"dir_123/video.mp4"}],"outputs":[{"file":"compressed.mp4","options":["-crf","28"]}]}}'

Analyze Media

# Analyze video properties
curl -X POST https://api.ffmpeg-api.com/ffprobe/analyze \\
  -H "Authorization: Basic YOUR_API_KEY" \\
  -d '{
    "file_path": "dir_123/video.mp4",
    "probe": {
      "format": ["duration", "size"],
      "streams": ["codec_name", "width", "height"],
      "select_streams": "v:0"
    }
  }'

List Resources

# List directories
curl -H "Authorization: Basic YOUR_API_KEY" \\
  https://api.ffmpeg-api.com/directory
 
# List files in directory
curl -H "Authorization: Basic YOUR_API_KEY" \\
  https://api.ffmpeg-api.com/directory/dir_123

Download Files

# Get download URL for a file
curl -H "Authorization: Basic YOUR_API_KEY" \\
  https://api.ffmpeg-api.com/file/download/dir_123/video.mp4
 
# Use the returned URL to download the file
curl -o downloaded.mp4 "$DOWNLOAD_URL"

Delete Files

# Delete a file permanently
curl -X DELETE -H "Authorization: Basic YOUR_API_KEY" \\
  https://api.ffmpeg-api.com/file/dir_123/video.mp4

Need more details? See our guides: