{"openapi":"3.1.0","info":{"title":"Very Good FFmpeg API","version":"1.0.0","description":"The FFmpeg API with usage-based pricing. Submit jobs with standard FFmpeg syntax and track progress via webhooks or polling.\n\n\nBuilt for video SaaS, UGC tools, and AI pipelines that need high-performance media wrangling without managing worker fleets."},"servers":[{"url":"https://ffmpeg-api.way.srl/api","description":"Production API Server"}],"security":[{"bearerAuth":[]}],"paths":{"/ffmpeg":{"post":{"summary":"Run FFmpeg Commands","description":"Run an FFmpeg command on our infrastructure.","parameters":[{"name":"wait","in":"query","description":"Wait for the job to complete before responding.","required":false,"schema":{"type":"boolean","default":false}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"input_files":{"type":"object","propertyNames":{"type":"string","minLength":1,"pattern":"^[A-Za-z0-9_.-]+$","title":"File name","description":"Use letters, numbers, underscores, hyphens, and dots. Do not start with a dot or use '..'.","example":"input.mp4"},"additionalProperties":{"type":"string","format":"uri"},"description":"Map of input file name -> url. File names must match template values in ffmpeg_commands.","example":{"input.mp4":"https://storage.verygoodffmpeg.com/sample.mp4"}},"output_files":{"minItems":1,"type":"array","items":{"type":"string","minLength":1,"pattern":"^[A-Za-z0-9_.%:*?-]+$","title":"Output file name or glob pattern","description":"A literal output file name, or a glob pattern (using the wildcards * and ?) that captures a variable set of outputs such as HLS segments or image sequences. Allowed characters: letters, numbers, underscores, hyphens, dots, percent signs, colons, and the wildcards * and ?. Do not start with a dot or use '..'.","example":"output.mp4"},"description":"Output file names or glob patterns. Literal names must match template values in ffmpeg_commands; glob patterns (e.g. 'seg_*.ts' or 'frame_*.png') are expanded to the files ffmpeg actually produces, so you don't need to know the exact names in advance.","example":["output.mp4","seg_*.ts"]},"ffmpeg_commands":{"minItems":1,"type":"array","items":{"type":"string","minLength":1},"description":"List of FFmpeg command strings. Use {{key}} or <<key>> placeholders to reference file names from input_files and output_files.","example":["-i {{input.mp4}} -t 5 {{output.mp4}}"]},"webhook_url":{"description":"URL to call when the job completes or fails.","example":"https://example.com/webhooks/ffmpeg","type":"string","format":"uri"},"machine":{"default":"cpu","description":"Select 'nvidia' to run commands using cuda specific filters/encoders.","type":"string","enum":["cpu","nvidia"]},"timeout_seconds":{"description":"Optional execution timeout for the job in seconds. Defaults to 5 minutes; may be raised up to 6 hours.","example":300,"type":"integer","minimum":-9007199254740991,"maximum":21600}},"required":["input_files","output_files","ffmpeg_commands"]}}}},"responses":{"200":{"description":"Job created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Job"}},"required":["data"],"additionalProperties":false,"description":"Single job response wrapper"}}}},"400":{"description":"Invalid request body"},"401":{"description":"Invalid or missing API key"}}}},"/jobs":{"get":{"summary":"List Jobs","description":"Get a list of jobs in your account.","parameters":[{"name":"limit","in":"query","description":"Maximum number of jobs to return.","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"offset","in":"query","description":"Number of jobs to skip.","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Successfully retrieved jobs","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"pagingParams":{"type":"object","properties":{"limit":{"type":"number","description":"Number of items returned","example":50},"offset":{"type":"number","description":"Number of items skipped","example":0},"total":{"type":"number","description":"Total number of items available","example":100},"hasMore":{"type":"boolean","description":"Whether more items are available","example":true}},"required":["limit","offset","total","hasMore"],"additionalProperties":false}},"required":["data","pagingParams"],"additionalProperties":false,"description":"Paginated jobs list response"}}}},"401":{"description":"Invalid or missing API key"}}}},"/jobs/{id}":{"get":{"summary":"Get a Job","description":"Get a single job by ID.","parameters":[{"name":"id","in":"path","description":"Job ID.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved the job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Job"}},"required":["data"],"additionalProperties":false,"description":"Single job response wrapper"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"Job not found"}}}},"/jobs/{id}/cancel":{"post":{"summary":"Cancel a Job","description":"Cancel a running or queued job.","parameters":[{"name":"id","in":"path","description":"Job ID.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully cancelled the job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Job"}},"required":["data"],"additionalProperties":false,"description":"Single job response wrapper"}}}},"401":{"description":"Invalid or missing API key"},"404":{"description":"Job not found"}}}},"/tmp-file":{"post":{"summary":"Prepare a File Upload","description":"Generate a presigned upload URL you can use for temporary file storage.","responses":{"200":{"description":"Presigned URLs created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"upload_url":{"type":"string","description":"Presigned URL for uploading the file","example":"https://tmp.example.com/upload?signature=abc"},"download_url":{"type":"string","description":"Presigned URL for downloading the file","example":"https://tmp.example.com/download?signature=abc"}},"required":["upload_url","download_url"],"additionalProperties":false}},"required":["data"],"additionalProperties":false,"description":"Temporary file URL pair response"}}}},"401":{"description":"Invalid or missing API key"}}}}},"components":{"schemas":{"Job":{"type":"object","properties":{"id":{"type":"string","description":"Unique job identifier.","example":"job_abc123xyz"},"status":{"type":"string","enum":["queued","running","succeeded","failed","cancelled"],"description":"Current lifecycle state of the job"},"queued_at":{"type":"string","description":"ISO 8601 timestamp when the job entered the queue.","example":"2024-01-15T10:30:00.000Z"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 timestamp when the job started running. Null if not started.","example":"2024-01-15T10:30:05.000Z"},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 timestamp when the job finished. Null if still running.","example":"2024-01-15T10:35:00.000Z"},"created_at":{"type":"string","description":"ISO 8601 timestamp when the job record was created.","example":"2024-01-15T10:30:00.000Z"},"updated_at":{"type":"string","description":"ISO 8601 timestamp of the last update to the job record.","example":"2024-01-15T10:35:00.000Z"},"error_message":{"type":"string","description":"Error message if the job failed. Empty string if the job has not failed.","example":"ffmpeg exited with code 1: Invalid data found when processing input"},"ffmpeg_commands":{"type":"array","items":{"type":"string"},"description":"The FFmpeg command strings that were submitted.","example":["-i {{input.mp4}} -t 5 {{output.mp4}}"]},"input_files":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Named input file URLs that were provided.","example":{"input":"https://storage.verygoodffmpeg.com/sample.mp4"}},"output_files":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Named output file presigned URLs, keyed by the concrete file names that were produced (glob patterns from the request are expanded to the actual files). Empty object until the job succeeds and outputs are ready.","example":{"output":"https://tmp.example.com/output/abc123/output.mp4"}},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Webhook URL that will be notified on job completion. Null if not set.","example":"https://example.com/webhooks/ffmpeg"},"timeout_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Execution timeout in seconds applied to this job. Null if not set.","example":300},"total_input_bytes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Total size in bytes of all input files. Null until the job finishes.","example":10485760},"total_output_bytes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Total size in bytes of all output files. Null until the job finishes.","example":5242880},"progress":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Overall completion percentage (0-100) reported by the running agent. Null while unknown (queued, or media duration not yet determined); 100 when succeeded.","example":42.5},"speed":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Current encoding speed as a multiple of realtime (e.g. 2.5 = 2.5x). Present while running.","example":2.5},"fps":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Current frames-per-second throughput. Present while running.","example":120},"eta_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Estimated seconds remaining for the current command. Present while running.","example":8},"command_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Zero-based index of the ffmpeg command currently running (for multi-command jobs such as 2-pass or HLS).","example":0},"commands_total":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Total number of ffmpeg commands in the job.","example":1}},"required":["id","status","queued_at","started_at","finished_at","created_at","updated_at","error_message","ffmpeg_commands","input_files","output_files","webhook_url","timeout_seconds","total_input_bytes","total_output_bytes"],"additionalProperties":false}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","name":"Authorization","description":"API key for authentication."}}}}