API documentation

Start a download, poll progress with the returned job id, or create subtitle files. The complete OpenAPI files stay available for generated clients.

First request

Replace YOUR_API_KEY, run the command, then poll progress with the returned id.

curl --get "https://p.savenow.to/ajax/download.php" \
    --data-urlencode "url=SOURCE_VIDEO_URL" \
    --data "format=mp44k" \
    --data "apikey=YOUR_API_KEY" \
    --data "add_info=1" \
    --data "allow_extended_duration=1" \
    --data "no_merge=0"

Download endpoint

Submit a video URL and output format. The API accepts the job immediately and returns an id.

Poll /ajax/progress.php with the returned id until progress reaches 1000 and download_url is present.

cURL request

curl --get "https://p.savenow.to/ajax/download.php" \
    --data-urlencode "url=SOURCE_VIDEO_URL" \
    --data "format=mp44k" \
    --data "apikey=YOUR_API_KEY" \
    --data "add_info=1" \
    --data "allow_extended_duration=1" \
    --data "no_merge=0"

JavaScript request

const params = new URLSearchParams({
    url: 'SOURCE_VIDEO_URL',
    format: 'mp44k',
    apikey: 'YOUR_API_KEY',
    add_info: '1',
    allow_extended_duration: '1',
    no_merge: '0',
});

const response = await fetch('https://p.savenow.to/ajax/download.php?' + params);
if (!response.ok) throw new Error(`Download request failed: ${response.status}`);

const { id } = await response.json();
const progressUrl = 'https://p.savenow.to/ajax/progress.php?' + new URLSearchParams({ id });

console.log({ id, progressUrl });

Python request

Requires the requests package: python -m pip install requests

import requests

params = {
    "url": "SOURCE_VIDEO_URL",
    "format": "mp44k",
    "apikey": "YOUR_API_KEY",
    "add_info": "1",
    "allow_extended_duration": "1",
    "no_merge": "0",
}

response = requests.get("https://p.savenow.to/ajax/download.php", params=params, timeout=30)
response.raise_for_status()

download = response.json()
download_id = download["id"]
progress_url = requests.Request(
    "GET",
    "https://p.savenow.to/ajax/progress.php",
    params={"id": download_id},
).prepare().url

print({"id": download_id, "progress_url": progress_url})

Progress endpoint

Poll a download or subtitle job until it finishes.

When progress is 1000, use download_url as the final file URL. Keep polling while progress is below 1000.

cURL request

curl --get "https://p.savenow.to/ajax/progress.php" \
    --data "id=DOWNLOAD_ID"

JavaScript request

const params = new URLSearchParams({ id: 'DOWNLOAD_ID' });
const response = await fetch('https://p.savenow.to/ajax/progress.php?' + params);
if (!response.ok) throw new Error(`Progress request failed: ${response.status}`);

const { progress, download_url: downloadUrl } = await response.json();

console.log({ progress, downloadUrl });

Python request

Requires the requests package: python -m pip install requests

import requests

response = requests.get(
    "https://p.savenow.to/ajax/progress.php",
    params={"id": "DOWNLOAD_ID"},
    timeout=30,
)
response.raise_for_status()

progress = response.json()

print({
    "progress": progress["progress"],
    "download_url": progress.get("download_url"),
})

Subtitles endpoint

Submit a subtitle or transcript job for a video URL.

Poll the returned progress_url until progress reaches 1000 and download_url points to the subtitle file.

cURL request

curl --get "https://p.savenow.to/ajax/subtitles" \
    --data-urlencode "url=SOURCE_VIDEO_URL" \
    --data "api=YOUR_API_KEY" \
    --data "lang=en" \
    --data "format=vtt"

JavaScript request

const params = new URLSearchParams({
    url: 'SOURCE_VIDEO_URL',
    api: 'YOUR_API_KEY',
    lang: 'en',
    format: 'vtt',
});

const response = await fetch('https://p.savenow.to/ajax/subtitles?' + params);
if (!response.ok) throw new Error(`Subtitle request failed: ${response.status}`);

const { id, progress_url: progressUrl } = await response.json();

console.log({ id, progressUrl });

Python request

Requires the requests package: python -m pip install requests

import requests

params = {
    "url": "SOURCE_VIDEO_URL",
    "api": "YOUR_API_KEY",
    "lang": "en",
    "format": "vtt",
}

response = requests.get("https://p.savenow.to/ajax/subtitles", params=params, timeout=30)
response.raise_for_status()

subtitles = response.json()

print({
    "id": subtitles["id"],
    "progress_url": subtitles["progress_url"],
})