{
  "openapi": "3.1.0",
  "info": {
    "title": "FFMPEG API",
    "version": "1.0.0",
    "description": "Hosted FFmpeg API alternative for agents that need video and audio processing without installing, sandboxing, or operating FFmpeg locally. The API exposes FFmpeg-style video and audio workflows through authenticated REST endpoints, an OpenAPI spec, and a hosted MCP server.",
    "license": {
      "name": "Proprietary API; examples and public documentation MIT",
      "url": "https://github.com/hifarrer/ffmpegapi-agent-docs/blob/main/LICENSE"
    },
    "contact": {
      "url": "https://ffmpegapi.net/contact"
    },
    "termsOfService": "https://ffmpegapi.net/terms"
  },
  "servers": [
    {
      "url": "https://ffmpegapi.net"
    }
  ],
  "paths": {
    "/api/merge_image_audio": {
      "post": {
        "operationId": "mergeImageAudio",
        "tags": [
          "Image"
        ],
        "summary": "Create an MP4 video from image/audio pairs.",
        "description": "Combines one or more image/audio pairs. Each image is shown for the duration of its matching audio file, then the next image is displayed when the next audio begins. JSON requests should use image_urls and audio_urls arrays for multi-pair videos, or legacy image and audio strings for a single pair. Optional image transitions and a default slow zoom effect are supported.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Image and Audio Merge completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "request is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "oneOf": [
                  {
                    "required": [
                      "image_urls",
                      "audio_urls"
                    ]
                  },
                  {
                    "required": [
                      "image",
                      "audio"
                    ]
                  }
                ],
                "properties": {
                  "image_urls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "minItems": 1,
                    "description": "Image URLs for multi-pair requests. Must align by index with audio_urls."
                  },
                  "audio_urls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "minItems": 1,
                    "description": "Audio URLs for multi-pair requests. Must align by index with image_urls."
                  },
                  "image": {
                    "type": "string",
                    "format": "uri",
                    "description": "Legacy single image URL."
                  },
                  "audio": {
                    "type": "string",
                    "format": "uri",
                    "description": "Legacy single audio URL."
                  },
                  "transition_effect": {
                    "type": "string",
                    "enum": [
                      "none",
                      "fade",
                      "wipeleft",
                      "wiperight",
                      "wipeup",
                      "wipedown",
                      "slideleft",
                      "slideright",
                      "slideup",
                      "slidedown",
                      "circlecrop",
                      "rectcrop",
                      "distance",
                      "fadeblack",
                      "fadewhite",
                      "radial",
                      "smoothleft",
                      "smoothright",
                      "smoothup",
                      "smoothdown"
                    ],
                    "description": "Optional transition between image changes."
                  },
                  "transition_duration": {
                    "type": "number",
                    "minimum": 0.1,
                    "maximum": 5,
                    "description": "Transition duration in seconds. Defaults to 0.5 when transition_effect is set."
                  },
                  "dimensions": {
                    "type": "string",
                    "pattern": "^\\d+x\\d+$",
                    "description": "Optional output dimensions such as 1280x720 or 1080x1920."
                  },
                  "zoom_effect": {
                    "type": "boolean",
                    "default": true,
                    "description": "Slowly zoom each image while its paired audio plays."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Image and Audio Merge request",
                  "value": {
                    "image_urls": [
                      "https://example.com/intro.jpg",
                      "https://example.com/chapter-1.jpg"
                    ],
                    "audio_urls": [
                      "https://example.com/intro.mp3",
                      "https://example.com/chapter-1.mp3"
                    ],
                    "transition_effect": "fade",
                    "transition_duration": 0.75,
                    "dimensions": "1280x720",
                    "zoom_effect": true,
                    "async": false
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/merge_videos": {
      "post": {
        "operationId": "mergeVideos",
        "tags": [
          "Video"
        ],
        "summary": "Concatenate videos into a single MP4.",
        "description": "Downloads one or more videos, normalizes them when needed, and concatenates them. Optional audio replacement, output dimensions, subtitle burn-in, and watermark overlay are supported.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Video Merge completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_urls is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_urls"
                ],
                "properties": {
                  "video_urls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "minItems": 1,
                    "description": "Video URLs to merge. Use at least one URL."
                  },
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional replacement audio URL."
                  },
                  "dimensions": {
                    "type": "string",
                    "pattern": "^\\d+x\\d+$",
                    "examples": [
                      "1920x1080",
                      "1080x1920"
                    ],
                    "description": "Optional output dimensions such as 1920x1080."
                  },
                  "subtitle_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional ASS/SSA subtitle URL to burn into the merged video."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional watermark image URL."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Video Merge request",
                  "value": {
                    "video_urls": [
                      "https://example.com/intro.mp4",
                      "https://example.com/main.mp4"
                    ],
                    "dimensions": "1920x1080"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/neonvideo_merge_videos": {
      "post": {
        "operationId": "neonvideoMergeVideos",
        "tags": [
          "Neonvideo"
        ],
        "summary": "Concatenate videos with optional outro video support.",
        "description": "Downloads one or more videos, normalizes and concatenates them, and can append an outro video that keeps its own audio. Optional audio replacement, output dimensions, subtitle burn-in, and watermark overlay are supported.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Neonvideo Merge Videos completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_urls is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_urls"
                ],
                "properties": {
                  "video_urls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "minItems": 1,
                    "description": "Video URLs to merge. Use at least one URL."
                  },
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional replacement audio URL for the main merged video. Not used during outro playback."
                  },
                  "outro_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional outro video URL to append. The outro keeps its own audio."
                  },
                  "dimensions": {
                    "type": "string",
                    "pattern": "^\\d+x\\d+$",
                    "examples": [
                      "1920x1080",
                      "1080x1920"
                    ],
                    "description": "Optional output dimensions such as 1920x1080."
                  },
                  "subtitle_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional ASS/SSA subtitle URL to burn into the merged video."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional watermark image URL."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Neonvideo Merge Videos request",
                  "value": {
                    "video_urls": [
                      "https://example.com/intro.mp4",
                      "https://example.com/main.mp4"
                    ],
                    "outro_url": "https://example.com/outro.mp4",
                    "dimensions": "1920x1080"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/video_loop": {
      "post": {
        "operationId": "videoLoop",
        "tags": [
          "Video"
        ],
        "summary": "Loop a video by count or until it matches an audio track.",
        "description": "Repeats one video a fixed number of times, or calculates the loop count needed to match a provided audio track. Optional watermark overlay is supported.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Video Loop completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL to loop."
                  },
                  "number_of_loops": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Positive number of times to repeat the video."
                  },
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional audio URL. Required if number_of_loops is omitted."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional watermark image URL."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Video Loop request",
                  "value": {
                    "video_url": "https://example.com/clip.mp4",
                    "number_of_loops": 3
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/picture_in_picture": {
      "post": {
        "operationId": "pictureInPicture",
        "tags": [
          "Picture"
        ],
        "summary": "Overlay one video on another.",
        "description": "Creates a picture-in-picture composition using a main video and an overlay video with configurable position, scale, and audio source.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Picture in Picture completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "main_video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "main_video_url",
                  "pip_video_url"
                ],
                "properties": {
                  "main_video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Main/background video URL."
                  },
                  "pip_video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Overlay/PiP video URL."
                  },
                  "position": {
                    "type": "string",
                    "enum": [
                      "top-left",
                      "top-right",
                      "bottom-left",
                      "bottom-right",
                      "center"
                    ],
                    "default": "bottom-right",
                    "description": "Overlay position. Common values: top-left, top-right, bottom-left, bottom-right, center."
                  },
                  "scale": {
                    "type": "string",
                    "default": "iw/4:ih/4",
                    "description": "FFmpeg scale expression for the overlay."
                  },
                  "audio_option": {
                    "type": "string",
                    "enum": [
                      "video1",
                      "video2",
                      "mute"
                    ],
                    "default": "video1",
                    "description": "Audio source: video1, video2, or mute."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Picture in Picture request",
                  "value": {
                    "main_video_url": "https://example.com/main.mp4",
                    "pip_video_url": "https://example.com/overlay.mp4",
                    "position": "top-right"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/add_watermark": {
      "post": {
        "operationId": "addWatermark",
        "tags": [
          "Add"
        ],
        "summary": "Overlay a watermark image onto a video.",
        "description": "Adds a watermark image to a video with configurable placement and scale.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Add Watermark completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url",
                  "watermark_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Watermark image URL."
                  },
                  "position": {
                    "type": "string",
                    "enum": [
                      "top-left",
                      "top-center",
                      "top-right",
                      "middle-left",
                      "middle",
                      "middle-right",
                      "bottom-left",
                      "bottom-center",
                      "bottom-right"
                    ],
                    "default": "bottom-right",
                    "description": "One of top-left, top-center, top-right, middle-left, middle, middle-right, bottom-left, bottom-center, bottom-right."
                  },
                  "scale": {
                    "type": "number",
                    "minimum": 0.05,
                    "maximum": 1,
                    "default": 0.25,
                    "description": "Watermark width as a fraction of video width, from 0.05 to 1.0."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Add Watermark request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "watermark_url": "https://example.com/logo.png",
                    "position": "bottom-right",
                    "scale": 0.2
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/add_subtitles": {
      "post": {
        "operationId": "addSubtitles",
        "tags": [
          "Add"
        ],
        "summary": "Burn ASS subtitles into a video.",
        "description": "Downloads a video and an ASS/SSA subtitle file, then burns the subtitles into the output video.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Add Subtitles completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url",
                  "subtitle_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "subtitle_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "ASS/SSA subtitle file URL."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Add Subtitles request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "subtitle_url": "https://example.com/subtitles.ass"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/split_audio": {
      "post": {
        "operationId": "splitAudio",
        "tags": [
          "Split"
        ],
        "summary": "Split audio into equal parts.",
        "description": "Splits an audio file into a requested number of equal-duration parts.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitAudioPartsResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Audio split into 3 parts successfully",
                      "parts": 3,
                      "audio_parts": [
                        {
                          "part": "part_001.mp3",
                          "download_url": "https://ffmpegapi.net/download/job_abc123/part_001.mp3"
                        },
                        {
                          "part": "part_002.mp3",
                          "download_url": "https://ffmpegapi.net/download/job_abc123/part_002.mp3"
                        },
                        {
                          "part": "part_003.mp3",
                          "download_url": "https://ffmpegapi.net/download/job_abc123/part_003.mp3"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "audio_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "audio_url"
                ],
                "properties": {
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Audio URL."
                  },
                  "parts": {
                    "type": "integer",
                    "minimum": 2,
                    "maximum": 20,
                    "default": 2,
                    "description": "Number of equal parts, from 2 to 20."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Split Audio request",
                  "value": {
                    "audio_url": "https://example.com/podcast.mp3",
                    "parts": 3
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/split_audio_segments": {
      "post": {
        "operationId": "splitAudioSegments",
        "tags": [
          "Split"
        ],
        "summary": "Split audio into fixed-duration segments.",
        "description": "Creates audio segments of a specified length in seconds.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitAudioSegmentsResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Audio split into fixed-duration segments successfully",
                      "segment_duration": 10,
                      "total_segments": 4,
                      "segments": [
                        {
                          "segment": "segment_001.mp3",
                          "download_url": "https://ffmpegapi.net/download/job_abc123/segment_001.mp3"
                        },
                        {
                          "segment": "segment_002.mp3",
                          "download_url": "https://ffmpegapi.net/download/job_abc123/segment_002.mp3"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "audio_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "audio_url"
                ],
                "properties": {
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Audio URL."
                  },
                  "segment_duration": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 3600,
                    "default": 30,
                    "description": "Segment duration in seconds, from 1 to 3600."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Split Audio by Segments request",
                  "value": {
                    "audio_url": "https://example.com/podcast.mp3",
                    "segment_duration": 10
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/split_audio_time": {
      "post": {
        "operationId": "splitAudioTime",
        "tags": [
          "Split"
        ],
        "summary": "Extract one audio range by millisecond timestamps.",
        "description": "Returns the audio between start_time and end_time, both in milliseconds.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Split Audio by Time completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/audio_abc123.mp3",
                      "filename": "audio_abc123.mp3"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "audio_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "audio_url",
                  "start_time",
                  "end_time"
                ],
                "properties": {
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Audio URL."
                  },
                  "start_time": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Start time in milliseconds."
                  },
                  "end_time": {
                    "type": "number",
                    "minimum": 0,
                    "description": "End time in milliseconds. Must be greater than start_time."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Split Audio by Time request",
                  "value": {
                    "audio_url": "https://example.com/audio.mp3",
                    "start_time": 1000,
                    "end_time": 11000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/trim_audio": {
      "post": {
        "operationId": "trimAudio",
        "tags": [
          "Trim"
        ],
        "summary": "Trim audio to a desired length.",
        "description": "Downloads an audio file and trims it to the requested duration, with optional fade-out.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrimAudioResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Trim Audio completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/audio_abc123.mp3",
                      "filename": "audio_abc123.mp3",
                      "trimmed_length": 30
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "audio_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "audio_url",
                  "desired_length"
                ],
                "properties": {
                  "audio_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Audio URL."
                  },
                  "desired_length": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Output length in seconds."
                  },
                  "fade_duration": {
                    "type": "number",
                    "minimum": 0,
                    "default": 0,
                    "description": "Optional fade-out duration in seconds."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Trim Audio request",
                  "value": {
                    "audio_url": "https://example.com/song.mp3",
                    "desired_length": 30,
                    "fade_duration": 2
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/trim_video": {
      "post": {
        "operationId": "trimVideo",
        "tags": [
          "Trim"
        ],
        "summary": "Trim video by start and end timestamps.",
        "description": "Downloads a video and returns the segment between start_time and end_time in seconds.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Trim Video completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url",
                  "start_time",
                  "end_time"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "start_time": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Start time in seconds."
                  },
                  "end_time": {
                    "type": "number",
                    "minimum": 0,
                    "description": "End time in seconds. Must be greater than start_time."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Trim Video request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "start_time": 5,
                    "end_time": 20
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/split_video": {
      "post": {
        "operationId": "splitVideo",
        "tags": [
          "Split"
        ],
        "summary": "Split a video into two parts.",
        "description": "Splits a video at split_at_seconds. If omitted, the split point defaults to half of the video duration.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitVideoResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Video split successfully",
                      "parts": [
                        {
                          "part": 1,
                          "download_url": "https://ffmpegapi.net/api/storage/video_abc123_part1.mp4",
                          "filename": "video_abc123_part1.mp4"
                        },
                        {
                          "part": 2,
                          "download_url": "https://ffmpegapi.net/api/storage/video_abc123_part2.mp4",
                          "filename": "video_abc123_part2.mp4"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "split_at_seconds": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Split point in seconds."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Split Video request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "split_at_seconds": 12.5
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/get_first_frame_image": {
      "post": {
        "operationId": "getFirstFrameImage",
        "tags": [
          "Get"
        ],
        "summary": "Extract the first frame of a video as a JPEG.",
        "description": "Downloads a video and returns an image URL for the first frame.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrameImageResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Frame extracted successfully",
                      "image_url": "https://ffmpegapi.net/api/storage/frame_abc123.jpg",
                      "download_url": "https://ffmpegapi.net/api/storage/frame_abc123.jpg",
                      "filename": "frame_abc123.jpg"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Get First Frame Image request",
                  "value": {
                    "video_url": "https://example.com/video.mp4"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/get_last_frame_image": {
      "post": {
        "operationId": "getLastFrameImage",
        "tags": [
          "Get"
        ],
        "summary": "Extract the last frame of a video as a JPEG.",
        "description": "Downloads a video and returns an image URL for the last frame.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrameImageResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Frame extracted successfully",
                      "image_url": "https://ffmpegapi.net/api/storage/frame_abc123.jpg",
                      "download_url": "https://ffmpegapi.net/api/storage/frame_abc123.jpg",
                      "filename": "frame_abc123.jpg"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Get Last Frame Image request",
                  "value": {
                    "video_url": "https://example.com/video.mp4"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/convert_to_vertical": {
      "post": {
        "operationId": "convertToVertical",
        "tags": [
          "Convert"
        ],
        "summary": "Convert a horizontal video to vertical format.",
        "description": "Creates a mobile-oriented vertical output and can apply an optional watermark.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Convert to Vertical completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional watermark image URL."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Convert to Vertical request",
                  "value": {
                    "video_url": "https://example.com/landscape.mp4",
                    "watermark_url": "https://example.com/logo.png"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/convert_to_tiktok_portrait": {
      "post": {
        "operationId": "convertToTiktokPortrait",
        "tags": [
          "TikTok"
        ],
        "summary": "Convert a video to full-bleed 9:16 TikTok-style portrait.",
        "description": "Crops and scales source video into 1080x1920 portrait format, with optional watermark and outro video.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "TikTok Portrait Converter completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Async job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AsyncJobResponse"
                },
                "examples": {
                  "asyncAccepted": {
                    "summary": "Async job accepted",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "status": "pending",
                      "message": "Job submitted for async processing. Use /api/job/{job_id}/status to check progress.",
                      "status_url": "https://ffmpegapi.net/api/job/job_abc123/status"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "watermark_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional watermark image URL."
                  },
                  "outro_video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional outro video URL to append."
                  },
                  "async": {
                    "type": "boolean",
                    "description": "Return a job_id immediately and process in the background."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "TikTok Portrait Converter request",
                  "value": {
                    "video_url": "https://example.com/landscape.mp4",
                    "outro_video_url": "https://example.com/outro.mp4"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/extract_audio_mp3": {
      "post": {
        "operationId": "extractAudioMp3",
        "tags": [
          "Extract"
        ],
        "summary": "Extract a video's audio track as MP3.",
        "description": "Downloads a video and returns an MP3 audio file.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Extract Audio as MP3 completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/audio_abc123.mp3",
                      "filename": "audio_abc123.mp3"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "bitrate": {
                    "type": "string",
                    "enum": [
                      "96k",
                      "128k",
                      "192k",
                      "256k",
                      "320k"
                    ],
                    "default": "192k",
                    "description": "MP3 bitrate: 96k, 128k, 192k, 256k, or 320k."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Extract Audio as MP3 request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "bitrate": "192k"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/convert_video_to_gif": {
      "post": {
        "operationId": "convertVideoToGif",
        "tags": [
          "Convert"
        ],
        "summary": "Encode a video as an animated GIF.",
        "description": "Downloads a video and creates a GIF. Optional chroma key transparency supports solid-color backgrounds such as green screen.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "Convert Video to GIF completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/clip_abc123.gif",
                      "filename": "clip_abc123.gif"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "transparent_background": {
                    "type": "boolean",
                    "default": false,
                    "description": "Apply chroma key transparency."
                  },
                  "chromakey_color": {
                    "type": "string",
                    "default": "0x00FF00",
                    "description": "Color to key out, such as 0x00FF00 or #00FF00."
                  },
                  "similarity": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 1,
                    "default": 0.2,
                    "description": "Chroma key similarity from 0.01 to 1.0."
                  },
                  "blend": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.05,
                    "description": "Transparency edge softness from 0.0 to 1.0."
                  },
                  "fps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 30,
                    "default": 10,
                    "description": "Output frame rate from 1 to 30."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Convert Video to GIF request",
                  "value": {
                    "video_url": "https://example.com/clip.mp4",
                    "transparent_background": true,
                    "chromakey_color": "0x00FF00",
                    "fps": 10
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/videos/add-tiktok-captions": {
      "post": {
        "operationId": "addTiktokCaptions",
        "tags": [
          "AI"
        ],
        "summary": "Transcribe a video and render TikTok-style captions.",
        "description": "Extracts audio, transcribes it with word timestamps, and renders styled captions into a video. Also returns caption artifact URLs when available.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptionArtifactsResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "download_url": "https://ffmpegapi.net/api/storage/auto-captions/video_abc123.mp4",
                      "captions_json_url": "https://ffmpegapi.net/api/storage/auto-captions/captions_abc123.json",
                      "srt_url": "https://ffmpegapi.net/api/storage/auto-captions/captions_abc123.srt",
                      "vtt_url": "https://ffmpegapi.net/api/storage/auto-captions/captions_abc123.vtt",
                      "word_count": 142,
                      "message": "Video with auto-generated TikTok captions rendered successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "Rendering timeout",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 504 error",
                    "value": {
                      "success": false,
                      "error": "Video rendering timed out. The video may be too long."
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "subtitle_style": {
                    "type": "string",
                    "enum": [
                      "plain-white",
                      "yellow-bg",
                      "pink-bg",
                      "blue-bg",
                      "red-bg"
                    ],
                    "default": "plain-white",
                    "description": "plain-white, yellow-bg, pink-bg, blue-bg, or red-bg."
                  },
                  "language": {
                    "type": "string",
                    "default": "auto",
                    "description": "Language code or auto."
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "16:9",
                      "9:16",
                      "4:3",
                      "3:4"
                    ],
                    "default": "9:16",
                    "description": "16:9, 9:16, 4:3, or 3:4."
                  },
                  "max_chars_per_line": {
                    "type": "integer",
                    "minimum": 5,
                    "maximum": 80,
                    "default": 20,
                    "description": "Caption wrapping limit from 5 to 80."
                  },
                  "max_lines": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4,
                    "default": 1,
                    "description": "Maximum caption lines from 1 to 4."
                  },
                  "position": {
                    "type": "string",
                    "enum": [
                      "top",
                      "center",
                      "bottom"
                    ],
                    "default": "bottom",
                    "description": "top, center, or bottom."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "AI Captions request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "subtitle_style": "yellow-bg",
                    "position": "bottom"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/videos/add-text-overlay-captions": {
      "post": {
        "operationId": "addTextOverlayCaptions",
        "tags": [
          "Text"
        ],
        "summary": "Render supplied text lines as timed caption overlays.",
        "description": "Displays user-provided text lines over a video, one line every duration_per_line seconds.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TextOverlayCaptionResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "download_url": "https://ffmpegapi.net/api/storage/text-overlay/video_abc123.mp4",
                      "line_count": 2,
                      "duration_per_line": 4,
                      "total_duration_seconds": 8,
                      "message": "Video with text overlay captions rendered successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "video_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "Rendering timeout",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 504 error",
                    "value": {
                      "success": false,
                      "error": "Video rendering timed out. The video may be too long."
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "video_url",
                  "text"
                ],
                "properties": {
                  "video_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Video URL."
                  },
                  "text": {
                    "type": "string",
                    "description": "One or more caption lines separated by newlines."
                  },
                  "subtitle_style": {
                    "type": "string",
                    "enum": [
                      "plain-white",
                      "yellow-bg",
                      "pink-bg",
                      "blue-bg",
                      "red-bg"
                    ],
                    "default": "plain-white",
                    "description": "plain-white, yellow-bg, pink-bg, blue-bg, or red-bg."
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "16:9",
                      "9:16",
                      "4:3",
                      "3:4"
                    ],
                    "default": "9:16",
                    "description": "16:9, 9:16, 4:3, or 3:4."
                  },
                  "position": {
                    "type": "string",
                    "enum": [
                      "top",
                      "center",
                      "bottom"
                    ],
                    "default": "center",
                    "description": "top, center, or bottom."
                  },
                  "duration_per_line": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 30,
                    "default": 5,
                    "description": "Seconds per text line from 1 to 30."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "Text Overlay Captions request",
                  "value": {
                    "video_url": "https://example.com/video.mp4",
                    "text": "First line\nSecond line",
                    "duration_per_line": 4
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/youtube_to_mp4": {
      "post": {
        "operationId": "youtubeToMp4",
        "tags": [
          "YouTube"
        ],
        "summary": "Return an MP4 download URL for a YouTube video.",
        "description": "Accepts a standard YouTube watch URL, youtu.be URL, Shorts URL, embed URL, or /v/ URL and returns a downloadable MP4 URL.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOutputResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "message": "YouTube to MP4 completed successfully",
                      "download_url": "https://ffmpegapi.net/api/storage/video_abc123.mp4",
                      "filename": "video_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "youtube_url is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "youtube_url"
                ],
                "properties": {
                  "youtube_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Single YouTube video URL. Playlists are not supported."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "summary": "YouTube to MP4 request",
                  "value": {
                    "youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/job/{job_id}/status": {
      "get": {
        "operationId": "getJobStatus",
        "tags": [
          "Jobs"
        ],
        "summary": "Check asynchronous job status.",
        "description": "Returns pending, processing, completed, or failed status for a background job submitted with async=true.\n\nAgent guidance: use this endpoint when the user needs FFmpeg-style media processing through an API and local FFmpeg execution is unavailable, slow, or unsuitable.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatusResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response",
                    "value": {
                      "success": true,
                      "job_id": "job_abc123",
                      "job_type": "merge_videos",
                      "status": "completed",
                      "created_at": "2026-06-11T14:05:00Z",
                      "updated_at": "2026-06-11T14:07:18Z",
                      "download_url": "https://ffmpegapi.net/api/storage/merged_abc123.mp4",
                      "result_url": "https://ffmpegapi.net/api/storage/merged_abc123.mp4",
                      "filename": "merged_abc123.mp4"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 400 error",
                    "value": {
                      "success": false,
                      "error": "request is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 401 error",
                    "value": {
                      "success": false,
                      "error": "Missing or invalid API key"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 500 error",
                    "value": {
                      "success": false,
                      "error": "Server error: processing failed"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Job belongs to another API key owner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 403 error",
                    "value": {
                      "success": false,
                      "error": "Access denied"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Job not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "error": {
                    "summary": "HTTP 404 error",
                    "value": {
                      "success": false,
                      "error": "Job not found"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Async job ID."
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "FileOutputResponse": {
        "type": "object",
        "required": [
          "success",
          "download_url"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "filename": {
            "type": "string",
            "examples": [
              "video_abc123.mp4"
            ]
          }
        },
        "additionalProperties": true
      },
      "AsyncJobResponse": {
        "type": "object",
        "required": [
          "success",
          "job_id",
          "status",
          "status_url"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "job_id": {
            "type": "string",
            "examples": [
              "job_abc123"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "message": {
            "type": "string"
          },
          "status_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": false
      },
      "JobStatusResponse": {
        "type": "object",
        "required": [
          "success",
          "job_id",
          "job_type",
          "status",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "job_id": {
            "type": "string"
          },
          "job_type": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "result_url": {
            "type": "string",
            "format": "uri"
          },
          "filename": {
            "type": "string",
            "examples": [
              "video_abc123.mp4"
            ]
          },
          "error": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "SplitAudioPartsResponse": {
        "type": "object",
        "required": [
          "success",
          "parts",
          "audio_parts"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "parts": {
            "type": "integer"
          },
          "audio_parts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "part",
                "download_url"
              ],
              "properties": {
                "part": {
                  "type": "string"
                },
                "download_url": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "SplitAudioSegmentsResponse": {
        "type": "object",
        "required": [
          "success",
          "total_segments",
          "segments"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "segment_duration": {
            "type": "number"
          },
          "total_segments": {
            "type": "integer"
          },
          "segments": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "segment",
                "download_url"
              ],
              "properties": {
                "segment": {
                  "type": "string"
                },
                "download_url": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "SplitVideoResponse": {
        "type": "object",
        "required": [
          "success",
          "parts"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "parts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "part",
                "download_url"
              ],
              "properties": {
                "part": {
                  "type": [
                    "integer",
                    "string"
                  ]
                },
                "download_url": {
                  "type": "string",
                  "format": "uri"
                },
                "filename": {
                  "type": "string",
                  "examples": [
                    "video_abc123.mp4"
                  ]
                }
              },
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "FrameImageResponse": {
        "type": "object",
        "required": [
          "success",
          "image_url",
          "download_url",
          "filename"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "image_url": {
            "type": "string",
            "format": "uri"
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "filename": {
            "type": "string",
            "examples": [
              "video_abc123.mp4"
            ]
          }
        },
        "additionalProperties": false
      },
      "CaptionArtifactsResponse": {
        "type": "object",
        "required": [
          "success",
          "download_url",
          "message"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "captions_json_url": {
            "type": "string",
            "format": "uri"
          },
          "srt_url": {
            "type": "string",
            "format": "uri"
          },
          "vtt_url": {
            "type": "string",
            "format": "uri"
          },
          "word_count": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "TextOverlayCaptionResponse": {
        "type": "object",
        "required": [
          "success",
          "download_url",
          "message"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "line_count": {
            "type": "integer"
          },
          "duration_per_line": {
            "type": "integer"
          },
          "total_duration_seconds": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "TrimAudioResponse": {
        "type": "object",
        "required": [
          "success",
          "download_url",
          "filename",
          "trimmed_length"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "message": {
            "type": "string"
          },
          "download_url": {
            "type": "string",
            "format": "uri"
          },
          "filename": {
            "type": "string",
            "examples": [
              "video_abc123.mp4"
            ]
          },
          "trimmed_length": {
            "type": "number"
          }
        },
        "additionalProperties": true
      }
    }
  }
}