On this page
Python Code Examples
Calling the MeowLoad API from Python needs no SDK: every endpoint is an ordinary JSON POST over HTTPS, so requests for scripts and aiohttp for concurrent jobs cover everything (pip install requests aiohttp). This page has two runnable examples against POST /openapi/v1/extract/post — one blocking call that extracts a single link, and a batch that extracts many at once. Both authenticate with a single Authorization: Bearer <your API key> header; replace the placeholder with the key from your Developer Console before running them.
🚀 Using requests
This is the shape you want for a script, a cron job or a one-off notebook cell: one URL in, one parsed result out. Two things bite people here. requests applies no timeout unless you ask for one, so pass timeout=60 unless you are happy for a stalled connection to hang the process indefinitely; and do not treat response.json() as an extraction result before checking status_code, because a failed extraction answers with HTTP 400 and a {message, code, retryable} body instead. To choose a download, walk data["medias"][0]["variants"] and take the entry whose is_default is set — media URLs are short-lived, so fetch them in the same run, and replay any headers the media item carries or the platform will refuse the download.
import requests
api_url = "https://api.meowload.net/openapi/v1/extract/post"
api_key = "<your API key>"
payload = {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}
headers = {"Authorization": f"Bearer {api_key}", "Accept-Language": "en"}
response = requests.post(api_url, json=payload, headers=headers)
if response.status_code == 200:
data = response.json()
# Both title and text are optional: sites with titles return title, others return text
caption = data.get("title") or data.get("text") or "(none)"
print(f"✅ Extraction successful! Site: {data.get('site')}, caption: {caption}")
for media in data["medias"]:
print(f"- {media['media_type']}: {media['resource_url']}")
# Resolutions / audio tracks live in variants; both video_url and audio_url present means a split stream
for variant in media.get("variants", []):
split = " (needs merging)" if variant.get("video_url") and variant.get("audio_url") else ""
print(f" {variant.get('quality_label', 'default')}{split}")
else:
error = response.json()
print(f"❌ Request failed ({response.status_code}): {error['message']}")
if error.get("retryable"):
print(f" Code {error['code']} is transient; retry later")🎯 Using aiohttp for Async Calls
Reach for this when you have a queue of links rather than a single one: the wall-clock cost of a batch is set by the slowest extraction, not by the sum of all of them. asyncio.gather starts every task at once, though, so put an asyncio.Semaphore in front of it (ten to twenty in flight is plenty) before feeding it a few hundred URLs — one key is capped at 1,200 requests per minute, and everything past that gets HTTP 429 for the rest of the window. Failures come back as ordinary dictionaries here rather than raised exceptions, which is what stops one dead link from cancelling the whole batch; queue an item for a second attempt only when its error body says retryable: true, and pass an explicit aiohttp.ClientTimeout so one slow platform cannot pin a worker forever.
import aiohttp
import asyncio
async def extract_async(url, api_key):
api_url = "https://api.meowload.net/openapi/v1/extract/post"
async with aiohttp.ClientSession() as session:
async with session.post(
api_url,
json={"url": url},
headers={"Authorization": f"Bearer {api_key}"}
) as response:
data = await response.json()
if response.status != 200:
# 400 carries code and retryable; retry later when retryable is True
return {"url": url, "error": data}
return {"url": url, "result": data}
# Concurrently extract multiple URLs
async def batch_extract(urls, api_key):
tasks = [extract_async(url, api_key) for url in urls]
return await asyncio.gather(*tasks)
# Run
urls = [
"https://www.youtube.com/watch?v=video1",
"https://www.youtube.com/watch?v=video2",
]
results = asyncio.run(batch_extract(urls, "<your API key>"))
for item in results:
if "error" in item:
error = item["error"]
print(f"❌ {item['url']}: {error['message']} ({error.get('code')}, retryable={error.get('retryable')})")
else:
print(f"✅ {item['url']}: {len(item['result']['medias'])} media item(s)")New to the API? The quickstart walks through getting a key and reading a response field by field, and error codes lists every extraction failure with the retryable value you should expect from it. Every request parameter and response field for the endpoint used above is documented in the single post API and in the API reference, which has a console for trying calls without writing code. To pull a whole channel or profile instead of one link, reuse the same request and error handling against the playlist API, which returns posts[] rather than medias and pages with has_more and next_cursor.