{"openapi":"3.1.0","info":{"title":"FFmpeg API","version":"1.0.0","description":"This is the documentation for the FFmpeg REST API.","termsOfService":"https://ffmpeg-api.com/terms","contact":{"name":"FFmpeg API Support","email":"support@ffmpeg-api.com"}},"tags":[{"name":"FFmpeg","description":"For running FFmpeg tasks"},{"name":"FFprobe","description":"For analyzing media metadata with FFprobe"},{"name":"Jobs","description":"For managing async processing jobs"},{"name":"Directories","description":"For creating and managing directories"},{"name":"Files","description":"For uploading and managing files"},{"name":"AI","description":"AI-powered endpoints that accept natural language instructions"}],"components":{"schemas":{},"parameters":{}},"paths":{"/ffmpeg/run":{"post":{"tags":["FFmpeg"],"deprecated":true,"summary":"Execute an FFmpeg task with inputs and outputs.","description":"Deprecated: use POST /ffmpeg/process instead. Submit a JSON-encoded FFmpeg task via multipart/form-data. Provide a `command` field that describes inputs, outputs, and options.","operationId":"post_FfmpegRun","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"multipart/form-data":{"schema":{"allOf":[{"type":"object","properties":{"command":{"type":"string","description":"JSON string describing the FFmpeg task. Example shape: { inputs: [{ file, options }], outputs: [{ file, options }] }."}},"required":["command"]},{"type":"object","additionalProperties":{}}]}}}},"responses":{"200":{"description":"Successful response with the execution result.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{}},"required":["ok"]}}}}}}},"/ffmpeg/process":{"post":{"tags":["FFmpeg"],"summary":"Process an FFmpeg task","description":"Submit a JSON-encoded FFmpeg task. Each input's `file_path` can be either `<dir_id>/<file_name>` (uploaded file) or a direct HTTPS URL. URL inputs are automatically imported to storage before processing. **Important**: Output files are registered in the target directory. Use `output_dir_id` to specify where outputs go, or it will be inferred from file_path inputs (or auto-created for URL-only requests).","operationId":"post_FfmpegProcess","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"inputs":{"type":"array","items":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"},"options":{"type":"array","items":{"type":"string"},"default":[]}},"required":["file_path"]}},"outputs":{"type":"array","items":{"type":"object","properties":{"file":{"type":"string","description":"Output file name, e.g. output.mp4 or output_%03d.png. **Warning**: Must not conflict with existing input filenames in the same directory."},"options":{"type":"array","items":{"type":"string"},"default":[]},"maps":{"type":"array","items":{"type":"string"}}},"required":["file"]}},"filter_complex":{"type":"string"},"output_dir_id":{"type":"string","description":"Target directory for outputs. If omitted: uses directory from file_path inputs, or creates a new temporary directory for URL-only inputs."}},"required":["inputs","outputs"]}},"required":["task"]}}}},"responses":{"200":{"description":"Successful response with the execution result.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"array","items":{"type":"object","properties":{"size_bytes":{"type":"number","description":"File size in bytes"},"download_url":{"type":"string","description":"Pre-signed download URL for the file"},"file_name":{"type":"string","description":"Name of the output file"}},"required":["size_bytes","download_url","file_name"]},"description":"Array of output files with download URLs and metadata. These files are automatically registered in the database within the same directory as your input files."},"usage":{"type":"object","properties":{"time_sec":{"type":"number","description":"Processing time in seconds"},"input_size_gb":{"type":"number","description":"Total input file size in GB"},"output_size_gb":{"type":"number","description":"Total output file size in GB"},"gb_sec":{"type":"number","description":"GB-seconds of compute usage"}},"required":["time_sec","input_size_gb","output_size_gb","gb_sec"],"description":"Processing usage statistics"}},"required":["ok","result","usage"]}}}},"400":{"description":"Bad Request - Invalid input data","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]},"examples":{"invalidJson":{"summary":"Invalid JSON in request body","value":{"ok":false,"error":"Invalid JSON in request body"}},"missingBody":{"summary":"Missing request body","value":{"ok":false,"error":"Request body is required"}},"missingTask":{"summary":"Missing task object","value":{"ok":false,"error":"Task object is required in request body"}},"invalidFilePath":{"summary":"Invalid file_path format","value":{"ok":false,"error":"Invalid file_path format. Expected <dir_id>/<file_name>"}},"filenameConflict":{"summary":"Output filename conflicts with input filename","value":{"ok":false,"error":"Output filename 'output.mp4' conflicts with an existing input file"}},"mixedDirectories":{"summary":"Input files from different directories","value":{"ok":false,"error":"All input files must be from the same directory"}}}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]},"example":{"ok":false,"error":"Invalid API key"}}}},"403":{"description":"Forbidden - Quota exceeded or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]},"examples":{"quotaExceeded":{"summary":"Monthly quota exceeded","value":{"ok":false,"error":"Quota exceeded"}},"fileSizeQuota":{"summary":"Input files size exceeds remaining quota","value":{"ok":false,"error":"Quota exceeded. Input files size (2.500 GB) exceeds remaining quota (1.200 GB)"}},"fileSizeExceeded":{"summary":"File size exceeds plan limit","value":{"ok":false,"error":"File 'video.mp4' size (750.25 MB) exceeds plan (starter) max file size limit of 500 MB. See https://ffmpeg-api.com/pricing for more details."}},"unauthorizedDirectory":{"summary":"Unauthorized access to directory","value":{"ok":false,"error":"Unauthorized access to directory"}}}}}},"404":{"description":"Not Found - Directory or file not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]},"examples":{"directoryNotFound":{"summary":"Directory not found","value":{"ok":false,"error":"Directory not found"}},"fileNotFound":{"summary":"File not found in directory","value":{"ok":false,"error":"File not found in directory"}}}}}},"500":{"description":"Internal Server Error - Processing failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]},"examples":{"processingFailed":{"summary":"FFmpeg processing failed","value":{"ok":false,"error":"FFmpeg command failed with exit code 1"}},"parsingError":{"summary":"Response parsing failed","value":{"ok":false,"error":"Failed to parse response"}}}}}}}}},"/jobs":{"get":{"tags":["Jobs"],"summary":"List async jobs","description":"List all async FFmpeg jobs for your account with filtering, pagination, and sorting options.","operationId":"get_FfmpegJobsList","parameters":[{"schema":{"type":"string","description":"Filter by status. Comma-separated for multiple: pending,processing,completed,failed,cancelled"},"required":false,"description":"Filter by status. Comma-separated for multiple: pending,processing,completed,failed,cancelled","name":"status","in":"query"},{"schema":{"type":"string","default":"20","description":"Number of results to return (1-100, default: 20)"},"required":false,"description":"Number of results to return (1-100, default: 20)","name":"limit","in":"query"},{"schema":{"type":"string","default":"0","description":"Pagination offset (default: 0)"},"required":false,"description":"Pagination offset (default: 0)","name":"offset","in":"query"},{"schema":{"type":"string","enum":["created_at_desc","created_at_asc"],"default":"created_at_desc","description":"Sort order (default: created_at_desc)"},"required":false,"description":"Sort order (default: created_at_desc)","name":"sort","in":"query"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Jobs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique job identifier"},"status":{"type":"string","enum":["pending","processing","completed","failed","cancelled"],"description":"Current job status"},"webhook_url":{"type":["string","null"],"description":"Webhook URL for notifications"},"created_at":{"type":"string","description":"ISO timestamp when job was created"},"updated_at":{"type":"string","description":"ISO timestamp when job was last updated"},"completed_at":{"type":["string","null"],"description":"ISO timestamp when job completed"},"input_count":{"type":"number","description":"Number of input files"},"output_count":{"type":"number","description":"Number of output files"},"has_error":{"type":"boolean","description":"Whether the job has an error"}},"required":["id","status","webhook_url","created_at","updated_at","completed_at","input_count","output_count","has_error"]}},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of jobs matching filter"},"limit":{"type":"number","description":"Number of results per page"},"offset":{"type":"number","description":"Current offset"},"has_more":{"type":"boolean","description":"Whether there are more results"}},"required":["total","limit","offset","has_more"]}},"required":["ok","jobs","pagination"]}}}},"400":{"description":"Bad request - invalid parameters","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}}},"/job/{jobId}":{"get":{"tags":["Jobs"],"summary":"Get async job status","description":"Check the status of an async FFmpeg job. Returns the current status and, if completed, the results.","operationId":"get_FfmpegJobStatus","parameters":[{"schema":{"type":"string","description":"The job ID returned when creating an async job"},"required":true,"description":"The job ID returned when creating an async job","name":"jobId","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Job status retrieved successfully","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"ok":{"type":"boolean"},"job_id":{"type":"string"},"status":{"type":"string","enum":["pending","processing"]},"task":{"description":"The task that was submitted"}},"required":["ok","job_id","status"]},{"type":"object","properties":{"ok":{"type":"boolean"},"job_id":{"type":"string"},"status":{"type":"string","enum":["completed"]},"task":{"description":"The task that was submitted"},"result":{"type":"array","items":{"type":"object","properties":{"size_bytes":{"type":"number","description":"File size in bytes"},"download_url":{"type":"string","description":"Pre-signed download URL for the file"},"file_name":{"type":"string","description":"Name of the output file"}},"required":["size_bytes","download_url","file_name"]}},"usage":{"type":"object","properties":{"time_sec":{"type":"number","description":"Processing time in seconds"},"input_size_gb":{"type":"number","description":"Total input file size in GB"},"output_size_gb":{"type":"number","description":"Total output file size in GB"},"gb_sec":{"type":"number","description":"GB-seconds of compute usage"}},"required":["time_sec","input_size_gb","output_size_gb","gb_sec"]}},"required":["ok","job_id","status","result","usage"]},{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"job_id":{"type":"string"},"status":{"type":"string","enum":["failed"]},"task":{"description":"The task that was submitted"},"error":{"type":"string"}},"required":["ok","job_id","status","error"]},{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"job_id":{"type":"string"},"status":{"type":"string","enum":["cancelled"]},"task":{"description":"The task that was submitted"}},"required":["ok","job_id","status"]}]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Job belongs to another account","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}},"delete":{"tags":["Jobs"],"summary":"Cancel a pending job","description":"Cancel and delete an async FFmpeg job. Only jobs in 'pending' status can be deleted. Jobs that are already processing, completed, or failed cannot be deleted.","operationId":"delete_FfmpegJobDelete","parameters":[{"schema":{"type":"string","description":"The job ID to cancel"},"required":true,"description":"The job ID to cancel","name":"jobId","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Job cancelled successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"message":{"type":"string"}},"required":["ok","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"409":{"description":"Job cannot be cancelled (not in pending status)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}}},"/ffprobe/analyze":{"post":{"tags":["FFprobe"],"summary":"Analyze media metadata with ffprobe","description":"Returns technical metadata for a file using ffprobe. Accepts either a `file_path` (`<dir_id>/<file_name>`) for uploaded files, or a direct HTTPS URL.","operationId":"post_FfprobeProcess","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"},"probe":{"type":"object","properties":{"format":{"type":"array","items":{"type":"string"},"description":"Array of format fields to return. Empty array returns all fields. Examples: duration, bit_rate, size, filename, nb_streams, format_name"},"streams":{"type":"array","items":{"type":"string"},"description":"Array of stream fields to return. Empty array returns all fields. Examples: codec_name, width, height, bit_rate, duration, sample_rate"},"chapters":{"type":"array","items":{"type":"string"},"description":"Array of chapter fields to return. Empty array returns all fields. Examples: id, start_time, end_time, title, tags"},"programs":{"type":"array","items":{"type":"string"},"description":"Array of program fields to return. Empty array returns all fields. Examples: program_id, program_num, pmt_pid, pcr_pid"},"frames":{"type":"array","items":{"type":"string"},"description":"Array of frame fields to return. Empty array returns all fields. Requires `select_streams`. Examples: pkt_pts_time, pkt_size, key_frame, width, height, pict_type"},"packets":{"type":"array","items":{"type":"string"},"description":"Array of packet fields to return. Empty array returns all fields. Requires `select_streams`. Examples: pts_time, dts_time, size, duration_time, flags, pos"},"error":{"type":"array","items":{"type":"string"},"description":"Array of error fields to return on failure. Empty array returns all fields. Examples: code, string, line, category"},"select_streams":{"type":"string","description":"Select streams, e.g. v:0, a:0"},"read_intervals":{"type":"string","description":"Read intervals, e.g. 0%+10"},"count_frames":{"type":"boolean","description":"Count frames"},"skip_frame":{"type":"string","description":"Skip frame"},"analyzeduration":{"anyOf":[{"type":"string"},{"type":"number"}],"description":"Analyzeduration in seconds, e.g. 10s or 10"},"probesize":{"anyOf":[{"type":"string"},{"type":"number"}],"description":"Probesize in bytes, e.g. 10M or 1024k"}}}},"required":["file_path","probe"]}}}},"responses":{"200":{"description":"Successful response with ffprobe JSON (filtered by options).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string","description":"Error message, if any"},"result":{"type":"object","additionalProperties":{},"description":"FFprobe JSON result"},"usage":{"type":"object","properties":{"time_sec":{"type":"number","description":"Processing time in seconds"},"input_size_gb":{"type":"number","description":"Total input file size in GB"},"output_size_gb":{"type":"number","description":"Total output file size in GB"},"gb_sec":{"type":"number","description":"GB-seconds of compute usage"}},"required":["time_sec","input_size_gb","output_size_gb","gb_sec"],"description":"Processing usage statistics"}},"required":["ok","usage"]}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Quota exceeded or file size limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]},"examples":{"quotaExceeded":{"summary":"Monthly quota exceeded","value":{"ok":false,"error":"Quota exceeded"}},"fileSizeExceeded":{"summary":"File size exceeds plan limit","value":{"ok":false,"error":"File 'video.mp4' size (750.25 MB) exceeds plan (starter) max file size limit of 500 MB. See https://ffmpeg-api.com/pricing for more details."}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}}}}},"/ffmpeg/process/async":{"post":{"tags":["FFmpeg"],"summary":"Submit an async FFmpeg task","description":"Submit an FFmpeg task for asynchronous processing. Each input's `file_path` can be either `<dir_id>/<file_name>` (uploaded file) or a direct HTTPS URL. URL inputs are imported to storage before the job is queued, ensuring they remain available when processing starts. Returns immediately with a job_id for polling via GET /job/:jobId. Optionally provide a webhook_url for completion callbacks.","operationId":"post_FfmpegProcessAsync","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"object","properties":{"inputs":{"type":"array","items":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"},"options":{"type":"array","items":{"type":"string"},"default":[]}},"required":["file_path"]}},"outputs":{"type":"array","items":{"type":"object","properties":{"file":{"type":"string","description":"Output file name, e.g. output.mp4 or output_%03d.png. **Warning**: Must not conflict with existing input filenames in the same directory."},"options":{"type":"array","items":{"type":"string"},"default":[]},"maps":{"type":"array","items":{"type":"string"}}},"required":["file"]}},"filter_complex":{"type":"string"},"output_dir_id":{"type":"string","description":"Target directory for outputs. If omitted: uses directory from file_path inputs, or creates a new temporary directory for URL-only inputs."}},"required":["inputs","outputs"]},"webhook_url":{"type":"string","format":"uri","description":"Optional HTTPS URL to receive a POST callback when the job completes or fails. Must be publicly accessible (no localhost or private IPs)."}},"required":["task"]}}}},"responses":{"202":{"description":"Job accepted for processing","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"job_id":{"type":"string","description":"Unique identifier for the job"},"status":{"type":"string","enum":["pending"],"description":"Initial job status"}},"required":["ok","job_id","status"]}}}},"400":{"description":"Bad Request - Invalid input data","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Quota exceeded or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"404":{"description":"Not Found - Directory or file not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}}},"/ai/ffprobe/analyze":{"post":{"tags":["AI"],"summary":"Analyze media metadata using natural language","description":"Describe what you want to know about a media file in plain English. The AI translates your instructions into the appropriate ffprobe configuration and returns the results. Accepts either a `file_path` (`<dir_id>/<file_name>`) for uploaded files, or a direct HTTPS URL.","operationId":"post_AiFfprobeProcess","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"},"instructions":{"type":"string","description":"Natural language description of what metadata you want. Examples: \"Get the video resolution and duration\", \"Show me all audio stream details\", \"What codecs are used?\""}},"required":["file_path","instructions"]}}}},"responses":{"200":{"description":"Successful response with ffprobe JSON (filtered by AI-generated options).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string","description":"Error message, if any"},"result":{"type":"object","additionalProperties":{},"description":"FFprobe JSON result"},"usage":{"type":"object","properties":{"time_sec":{"type":"number","description":"Processing time in seconds"},"input_size_gb":{"type":"number","description":"Total input file size in GB"},"output_size_gb":{"type":"number","description":"Total output file size in GB"},"gb_sec":{"type":"number","description":"GB-seconds of compute usage"}},"required":["time_sec","input_size_gb","output_size_gb","gb_sec"],"description":"Processing usage statistics"},"generated_probe":{"type":"object","additionalProperties":{},"description":"The probe configuration generated by the AI from your instructions"}},"required":["ok","usage"]}}}},"400":{"description":"Bad Request - Invalid input or AI translation failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Quota exceeded or file size limit","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]}}}}}}},"/ai/ffmpeg/process":{"post":{"tags":["AI"],"summary":"Process an FFmpeg task using natural language","description":"Describe what you want to do with your media files in plain English. The AI translates your instructions into the appropriate FFmpeg command and processes it. Each input's `file_path` can be either `<dir_id>/<file_name>` (uploaded file) or a direct HTTPS URL.","operationId":"post_AiFfmpegProcess","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"inputs":{"type":"array","items":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"}},"required":["file_path"]},"description":"Array of input files to process"},"instructions":{"type":"string","description":"Natural language description of what to do. Examples: \"Convert to 720p MP4\", \"Extract audio as MP3\", \"Trim from 0:30 to 1:00 and add a fade-in\""},"output_dir_id":{"type":"string","description":"Target directory for outputs. If omitted: uses directory from file_path inputs, or creates a new temporary directory for URL-only inputs."}},"required":["inputs","instructions"]}}}},"responses":{"200":{"description":"Successful response with the execution result.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"array","items":{"type":"object","properties":{"size_bytes":{"type":"number","description":"File size in bytes"},"download_url":{"type":"string","description":"Pre-signed download URL for the file"},"file_name":{"type":"string","description":"Name of the output file"}},"required":["size_bytes","download_url","file_name"]},"description":"Array of output files with download URLs and metadata."},"usage":{"type":"object","properties":{"time_sec":{"type":"number","description":"Processing time in seconds"},"input_size_gb":{"type":"number","description":"Total input file size in GB"},"output_size_gb":{"type":"number","description":"Total output file size in GB"},"gb_sec":{"type":"number","description":"GB-seconds of compute usage"}},"required":["time_sec","input_size_gb","output_size_gb","gb_sec"],"description":"Processing usage statistics"},"generated_command":{"type":"object","additionalProperties":{},"description":"The FFmpeg task generated by the AI from your instructions"}},"required":["ok","result","usage"]}}}},"400":{"description":"Bad Request - Invalid input data or AI translation failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Quota exceeded or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"404":{"description":"Not Found - Directory or file not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error - Processing failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}}},"/ai/ffmpeg/process/async":{"post":{"tags":["AI"],"summary":"Submit an async FFmpeg task using natural language","description":"Describe what you want to do with your media files in plain English. The AI translates your instructions into the appropriate FFmpeg command and submits it for asynchronous processing. Returns immediately with a job_id for polling via GET /job/:jobId. Optionally provide a webhook_url for completion callbacks.","operationId":"post_AiFfmpegProcessAsync","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"inputs":{"type":"array","items":{"type":"object","properties":{"file_path":{"type":"string","description":"`<dir_id>/<file_name>` of an uploaded file, or a direct HTTPS URL"}},"required":["file_path"]},"description":"Array of input files to process"},"instructions":{"type":"string","description":"Natural language description of what to do. Examples: \"Convert to 720p MP4\", \"Extract audio as MP3\", \"Trim from 0:30 to 1:00 and add a fade-in\""},"output_dir_id":{"type":"string","description":"Target directory for outputs. If omitted: uses directory from file_path inputs, or creates a new temporary directory for URL-only inputs."},"webhook_url":{"type":"string","format":"uri","description":"Optional HTTPS URL to receive a POST callback when the job completes or fails. Must be publicly accessible (no localhost or private IPs)."}},"required":["inputs","instructions"]}}}},"responses":{"202":{"description":"Job accepted for processing","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"job_id":{"type":"string","description":"Unique identifier for the job"},"status":{"type":"string","enum":["pending"],"description":"Initial job status"},"generated_command":{"type":"object","additionalProperties":{},"description":"The FFmpeg task generated by the AI from your instructions"}},"required":["ok","job_id","status"]}}}},"400":{"description":"Bad Request - Invalid input data or AI translation failed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Quota exceeded or unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"404":{"description":"Not Found - Directory or file not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Error message describing what went wrong"}},"required":["ok","error"]}}}}}}},"/file":{"post":{"tags":["Files"],"summary":"Create a file and get a presigned upload URL","description":"Add a new file entry in a directory and returns a presigned S3-compatible PUT URL to upload the file bytes. If `dir_id` is omitted, a new temporary directory is created automatically (24h TTL). File names are case-sensitive and must be unique per directory. The returned upload URL is valid for 1 hour and may include headers that you must send with the PUT request.","operationId":"post_FileCreate","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"dir_id":{"type":"string","description":"Optional target directory ID that you own (from POST /directory or GET /directory). If omitted, a new temporary directory is created automatically (expires in ~24 hours)."},"file_name":{"type":"string","description":"File name to use. Must be unique within the target directory."}},"required":["file_name"]}}}},"responses":{"200":{"description":"The file record was created successfully and a presigned PUT URL was issued. Use the provided `upload.url`, `upload.method` (always PUT), and `upload.headers` when uploading the raw file bytes. The URL expires after `upload.expiresInSeconds`.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"file":{"type":"object","properties":{"dir_id":{"type":"string","description":"Directory ID containing the file"},"added_on":{"type":"string","description":"ISO timestamp when the file record was created"},"file_name":{"type":"string","description":"Provided file name"},"file_path":{"type":"string","description":"File path to use when calling ffmpeg/process: <dir_id>/<file_name>"}},"required":["dir_id","added_on","file_name","file_path"]},"upload":{"type":"object","properties":{"url":{"type":"string","description":"Presigned S3-compatible URL to PUT the file bytes."},"method":{"type":"string","enum":["PUT"],"description":"HTTP method to use for upload; always PUT"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Optional headers to include with the PUT request."},"expiresInSeconds":{"type":"number","description":"Seconds until the presigned URL expires (default ~3600)."}},"required":["url","method","expiresInSeconds"]}},"required":["ok","file","upload"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"403":{"description":"You do not have access to the specified directory (if provided).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"The specified directory was not found (if provided).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"409":{"description":"A file with the same name already exists in the directory.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Unexpected server error while creating the file or URL.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"},"details":{"type":"string"}},"required":["ok","error"]}}}}}}},"/file/download/{dirId}/{fileName}":{"get":{"tags":["Files"],"summary":"Get a presigned download URL for a file","description":"Retrieve a presigned download URL for a file stored in our storage. The URL is valid for 5 minutes. The file path should be provided in the URL as '/file/download/dir_id/file_name' where dir_id/file_name is the format returned by the file creation endpoint.","operationId":"get_FileDownload","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)"},"required":true,"description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)","name":"dirId","in":"path"},{"schema":{"type":"string","pattern":"^[^/]{1,255}$","description":"File name (1-255 chars, no slashes)"},"required":true,"description":"File name (1-255 chars, no slashes)","name":"fileName","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Presigned download URL generated successfully. Use the provided URL to download the file directly from our storage.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"download":{"type":"object","properties":{"url":{"type":"string","description":"Presigned URL to download the file via GET request"},"method":{"type":"string","enum":["GET"],"description":"HTTP method to use for download; always GET"},"expiresInSeconds":{"type":"number","description":"Seconds until the presigned URL expires"},"file_path":{"type":"string","description":"The file path in format: dir_id/file_name"},"file_size":{"type":"number","description":"File size in bytes"},"file_type":{"type":["string","null"],"description":"MIME type of the file (e.g., 'video/mp4')"}},"required":["url","method","expiresInSeconds","file_path","file_size","file_type"]}},"required":["ok","download"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"The specified file or directory was not found.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Unexpected server error while generating download URL.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}}}}},"/file/{dirId}/{fileName}":{"get":{"tags":["Files"],"summary":"Get file information","description":"Retrieve file metadata (file type and size) for a stored file. The file path should be provided in the URL as '/file/dir_id/file_name' where dir_id/file_name is the format returned by the file creation endpoint.","operationId":"get_FileInfo","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)"},"required":true,"description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)","name":"dirId","in":"path"},{"schema":{"type":"string","pattern":"^[^/]{1,255}$","description":"File name (1-255 chars, no slashes)"},"required":true,"description":"File name (1-255 chars, no slashes)","name":"fileName","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"File information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"file_info":{"type":"object","properties":{"file_path":{"type":"string","description":"The requested file path"},"file_type":{"type":["string","null"],"description":"MIME type of the file (e.g., 'video/mp4', 'image/jpeg')"},"file_size":{"type":"number","description":"File size in bytes"}},"required":["file_path","file_type","file_size"]}},"required":["ok","file_info"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"The specified file was not found.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Unexpected server error while retrieving file information.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}}}},"delete":{"tags":["Files"],"summary":"Delete a file","description":"Delete a file from storage and remove its database record. The file path should be provided in the URL as '/file/dir_id/file_name' where dir_id/file_name is the format returned by the file creation endpoint. This operation is irreversible.","operationId":"delete_FileDelete","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,64}$","description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)"},"required":true,"description":"Directory ID (1-64 chars, A-Z a-z 0-9 _ -)","name":"dirId","in":"path"},{"schema":{"type":"string","pattern":"^[^/]{1,255}$","description":"File name (1-255 chars, no slashes)"},"required":true,"description":"File name (1-255 chars, no slashes)","name":"fileName","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"File deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"deleted":{"type":"object","properties":{"file_path":{"type":"string","description":"The deleted file path in format: dir_id/file_name"}},"required":["file_path"]}},"required":["ok","deleted"]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"The specified file or directory was not found.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Unexpected server error while deleting the file.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}}}}},"/directory":{"post":{"tags":["Directories"],"summary":"Create a temporary working directory","description":"Create a short-lived workspace for your files and outputs. Use this before uploading inputs or running FFmpeg so you can group related artifacts. The directory (and its files) auto‑expires based on TTL.","operationId":"post_DirectoryCreate","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ttl":{"type":"number","description":"Optional expiry in seconds. Directory and files are deleted after this time. Default: 24h (86,400). Max: 7d (604,800)."}}}}}},"responses":{"200":{"description":"Returns the created directory","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"directory":{"type":"object","properties":{"id":{"type":"string"},"ttl":{"type":"number"}},"required":["id","ttl"]}},"required":["ok","directory"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error - Failed to create directory","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"},"details":{"type":"string"}},"required":["ok","error"]}}}}}},"get":{"tags":["Directories"],"summary":"List your directories","description":"Discover existing workspaces for your account. Pair with GET /directory/:dirId to inspect files inside a specific directory.","operationId":"get_DirectoriesGet","parameters":[{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Successful response with directories you own.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"directories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ttl":{"type":"number"},"added_on":{"type":"string"}},"required":["id","ttl","added_on"]}}},"required":["ok","directories"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error - Failed to fetch directories","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"},"details":{"type":"string"}},"required":["ok","error"]}}}}}}},"/directory/{dirId}":{"get":{"tags":["Directories"],"summary":"List files in one of your directories","description":"Fetch the current file inventory for a directory you own. Use this before downloading artifacts or after an FFmpeg run to see what was produced.","externalDocs":{"url":"https://ffmpeg-api.com/docs/api/directories","description":"directory documentation"},"operationId":"get_FilesGet","parameters":[{"schema":{"type":"string","description":"Directory ID to list files of. Obtain from POST /directory or GET /directory"},"required":true,"description":"Directory ID to list files of. Obtain from POST /directory or GET /directory","name":"dirId","in":"path"},{"schema":{"type":"string","description":"Your secret API key. Format: Basic &lt;key&gt;"},"required":true,"description":"Your secret API key. Format: Basic &lt;key&gt;","name":"Authorization","in":"header"}],"responses":{"200":{"description":"Successful response with the files registered in this directory.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"files":{"type":"array","items":{"type":"object","properties":{"file_name":{"type":"string"},"added_on":{"type":"string"}},"required":["file_name","added_on"]}}},"required":["ok","files"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"403":{"description":"Forbidden - Unauthorized access to directory","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"404":{"description":"Not Found - Directory not found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}},"required":["ok","error"]}}}},"500":{"description":"Internal Server Error - Failed to fetch files","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"},"details":{"type":"string"}},"required":["ok","error"]}}}}}}}},"webhooks":{}}