{
    "openapi": "3.0.3",
    "info": {
        "title": "SaveNow Video Download API",
        "version": "1.0.0",
        "description": "REST API for downloading YouTube and other supported videos/audio in many\nformats and qualities.\n\nThe SaveNow Video Download REST API lets you submit a video URL, pick an output\nformat (audio or video), and retrieve a direct download URL. Long jobs return an\n`id` you can poll via the Progress endpoint until the file is ready.\n\n## Authentication\n\nEvery request to the Download endpoint must include your personal `apikey`\nquery parameter. Contact us at `sp_golubev@protonmail.com` or visit\n[video-download-api.com](https://video-download-api.com/) to get one.\nThe Progress endpoint does not require an API key — only the job `id` returned\nfrom a previous download call.\n\n## Pricing model\n\nEvery successful download deducts credits from your account based on the chosen\n`format`. Video formats beyond the \"base duration limit\" (e.g. videos longer than\n90 minutes at 1080p) cost extra if `allow_extended_duration=1` is set; otherwise\nthose jobs are rejected. See the `ExtendedDuration` schema and the hosted\ndocumentation page for the full pricing matrix.\n",
        "contact": {
            "name": "SaveNow API Support",
            "email": "sp_golubev@protonmail.com",
            "url": "https://video-download-api.com/"
        },
        "termsOfService": "https://video-download-api.com/",
        "license": {
            "name": "Proprietary",
            "url": "https://video-download-api.com/"
        }
    },
    "servers": [
        {
            "url": "https://p.savenow.to",
            "description": "Production"
        }
    ],
    "tags": [
        {
            "name": "Download",
            "description": "Submit a new download job and receive a job id."
        },
        {
            "name": "Progress",
            "description": "Poll the status of a download job until it finishes."
        }
    ],
    "security": [
        {
            "ApiKeyAuth": []
        }
    ],
    "paths": {
        "/ajax/download.php": {
            "get": {
                "tags": [
                    "Download"
                ],
                "summary": "Create a download job",
                "operationId": "createDownload",
                "description": "Submits a new download job for the given `url` in the requested `format`.\nReturns a unique `id` you can pass to the Progress endpoint to poll for\ncompletion and retrieve the final download URL.\n",
                "parameters": [
                    {
                        "name": "format",
                        "in": "query",
                        "required": true,
                        "example": "1080",
                        "description": "The output format to download. Accepted values: `mp3`, `m4a`,\n`webm_audio`, `aac`, `flac`, `opus`, `ogg`, `wav`, `mp2`, `144`,\n`240`, `360`, `480`, `720`, `1080`, `1440`, `4k`, `8k`.\n\nAudio formats have a 120-minute base duration limit; video formats\nhave format-specific limits (1080p=90m, 1440p=60m, 4k/8k=15m,\neverything else=120m).\n",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "url",
                        "in": "query",
                        "required": true,
                        "example": "https://www.youtube.com/watch?v=K1Pu75yJUOE",
                        "description": "The URL-encoded URL of the video to download (YouTube and other supported sources).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "apikey",
                        "in": "query",
                        "required": true,
                        "example": "YOUR_API_KEY",
                        "description": "Your personal API key.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "add_info",
                        "in": "query",
                        "required": false,
                        "example": "1",
                        "description": "Set to `1` to include the `info` object (title + thumbnail) in the response. Defaults to `0` when omitted.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "audio_quality",
                        "in": "query",
                        "required": false,
                        "example": "128",
                        "description": "Audio bitrate in kbps. Common values include `128`, `192`, `256`, `320`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "allow_extended_duration",
                        "in": "query",
                        "required": false,
                        "example": "1",
                        "description": "Set to `1` to permit downloads whose video duration exceeds the format's\nbase duration limit. Extended-duration jobs are charged a multiplier of\nthe base price (see the `ExtendedDuration` response object). Defaults to\n`0` when omitted.\n",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "no_merge",
                        "in": "query",
                        "required": false,
                        "example": "0",
                        "description": "If set to `1`, audio and video streams are **not** merged. The client\nreceives a zip file containing the separate streams. Defaults to `0`\n(streams are merged into a single file).\n",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "audio_language",
                        "in": "query",
                        "required": false,
                        "example": "en",
                        "description": "YouTube only. Selects the audio track language by BCP-47 / YouTube\nlanguage code. If the requested track is not available on the video,\nthe default track is used instead. No additional cost.\n\nSupported codes: `af, az, id, ms, bs, ca, cs, da, de, et, en-IN, en-GB,\nen, es, es-419, es-US, eu, fil, fr, fr-CA, gl, hr, zu, is, it, sw, lv,\nlt, hu, nl, no, uz, pl, pt-PT, pt, ro, sq, sk, sl, sr-Latn, fi, sv, vi,\ntr, be, bg, ky, kk, mk, mn, ru, sr, uk, el, hy, iw, ur, ar, fa, ne, mr,\nhi, as, bn, pa, gu, or, ta, te, kn, ml, si, th, lo, my, ka, am, km,\nzh-CN, zh-TW, zh-HK, ja, ko`.\n",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "start_time",
                        "in": "query",
                        "required": false,
                        "example": "30",
                        "description": "Optional. Start time (in seconds) of a cut/segment download. When\n`start_time`/`end_time` are supplied, progress is not reported — the\nProgress endpoint only returns initialization and the final success /\nfailure status.\n",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "end_time",
                        "in": "query",
                        "required": false,
                        "example": "90",
                        "description": "Optional. End time (in seconds) of a cut/segment download.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Job accepted. Use the returned `id` with the Progress endpoint to poll for the final download URL.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DownloadResponse"
                                },
                                "examples": {
                                    "standard": {
                                        "summary": "Standard download",
                                        "value": {
                                            "success": true,
                                            "id": "abc123xyz789",
                                            "content": "PGRpdiBjbGFzcz0iZG93bmxvYWQtY29udGVudCI+Li4uPC9kaXY+",
                                            "info": {
                                                "image": "https://i.ytimg.com/vi/K1Pu75yJUOE/maxresdefault.jpg",
                                                "title": "Amazing Video Title - 4K Quality"
                                            }
                                        }
                                    },
                                    "extended": {
                                        "summary": "Extended-duration download (premium)",
                                        "value": {
                                            "success": true,
                                            "id": "abc123xyz789",
                                            "content": "PGRpdiBjbGFzcz0iZG93bmxvYWQtY29udGVudCI+Li4uPC9kaXY+",
                                            "info": {
                                                "image": "https://i.ytimg.com/vi/K1Pu75yJUOE/maxresdefault.jpg",
                                                "title": "Amazing Video Title - 4K Quality"
                                            },
                                            "extended_duration": {
                                                "multiplier": 3,
                                                "original_price": 0.00025,
                                                "final_price": 0.00075
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing or invalid parameters (for example, missing `url`, unknown `format`, or a video that exceeds the base duration without `allow_extended_duration=1`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Server error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/ajax/progress": {
            "get": {
                "tags": [
                    "Progress"
                ],
                "summary": "Check download progress",
                "operationId": "getProgress",
                "security": [],
                "description": "Polls the status of a previously-submitted download job. Keep polling\nuntil `progress == 1000` (i.e. 100%) and `download_url` is populated.\n",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "required": true,
                        "example": "YOUR_JOB_ID",
                        "description": "The job id returned by the Download endpoint.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Current progress of the download job.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProgressResponse"
                                },
                                "examples": {
                                    "finished": {
                                        "summary": "Download finished",
                                        "value": {
                                            "success": 1,
                                            "progress": 1000,
                                            "download_url": "https://shane45.oceansaver.in/pacific/?riPnIjzRoXKtgjjksZmlvBQ",
                                            "text": "Finished",
                                            "message": "If you want your application to use our API contact us: sp_golubev@protonmail.com or visit https://video-download-api.com/"
                                        }
                                    },
                                    "inProgress": {
                                        "summary": "Still downloading",
                                        "value": {
                                            "success": 1,
                                            "progress": 420,
                                            "text": "Downloading"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Missing or invalid `id`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Server error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "ApiKeyAuth": {
                "type": "apiKey",
                "in": "query",
                "name": "apikey",
                "description": "Pass your API key as the `apikey` query parameter on every Download request."
            }
        },
        "schemas": {
            "DownloadResponse": {
                "type": "object",
                "required": [
                    "success",
                    "id"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "description": "`true` when the job was accepted, `false` on error."
                    },
                    "id": {
                        "type": "string",
                        "description": "Unique identifier for the job. Pass this to the Progress endpoint."
                    },
                    "content": {
                        "type": "string",
                        "description": "Base64-encoded HTML snippet you can render to show a progress/download UI."
                    },
                    "info": {
                        "$ref": "#/components/schemas/InfoObject"
                    },
                    "extended_duration": {
                        "$ref": "#/components/schemas/ExtendedDuration"
                    }
                }
            },
            "InfoObject": {
                "type": "object",
                "description": "Extra metadata about the downloaded content. Only present when `add_info=1`.",
                "properties": {
                    "image": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL of a thumbnail image for the content."
                    },
                    "title": {
                        "type": "string",
                        "description": "Title of the content."
                    }
                }
            },
            "ExtendedDuration": {
                "type": "object",
                "description": "Pricing detail returned when `allow_extended_duration=1` **and** the video\nexceeds the format's base duration limit.\n",
                "properties": {
                    "multiplier": {
                        "type": "integer",
                        "description": "Price multiplier applied because of the video's duration (e.g. `3` means 3x pricing).",
                        "example": 3
                    },
                    "original_price": {
                        "type": "number",
                        "format": "float",
                        "description": "Base per-download price for the selected format, before the multiplier.",
                        "example": 0.00025
                    },
                    "final_price": {
                        "type": "number",
                        "format": "float",
                        "description": "Final per-download price after the multiplier is applied.",
                        "example": 0.00075
                    }
                }
            },
            "ProgressResponse": {
                "type": "object",
                "required": [
                    "success",
                    "progress"
                ],
                "properties": {
                    "success": {
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "description": "`1` on success, `0` on failure."
                    },
                    "progress": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1000,
                        "description": "Progress in thousandths. `1000` means 100% complete."
                    },
                    "download_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Direct download URL. Present once the job has finished successfully."
                    },
                    "text": {
                        "type": "string",
                        "description": "Human-readable status (for example `Downloading`, `Finished`, `Failed`)."
                    },
                    "message": {
                        "type": "string",
                        "description": "Informational message from the API."
                    }
                }
            },
            "ErrorResponse": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "example": false
                    },
                    "error": {
                        "type": "string",
                        "description": "Human-readable error message."
                    }
                }
            }
        }
    }
}