Every photo and video from a Threads post
Send a Threads post link from threads.com or threads.net. Posts with many images return them all, in the order they appear.
POST
/v1/download
https://www.threads.com/@user/post/XXXXXXXXX
{
"success": true,
"data": {
"platform": "threads",
"media": [
{ "type": "image", "url": "https://…/1.jpg" },
{ "type": "image", "url": "https://…/2.jpg" },
{ "type": "image", "url": "https://…/3.jpg" },
{ "type": "image", "url": "https://…/4.jpg" }
]
}
}
Photos
Single and multi-image posts
Videos
Videos in posts
Links we accept
- threads.com/@user/post/…
- threads.net/@user/post/…
What to know about Threads
- Multi-image posts can hold many files. Take all of them.
- Text-only posts have no media and return MEDIA_UNAVAILABLE, which is not counted.
- Only public posts work. Errors never use up a download.
curl -s -X POST https://omnimediaapi.com/v1/download \
-H "X-API-Key: $OMNI_API_KEY" \
-H "Content-Type: application/json" \
-H "User-Agent: my-agent/1.0" \
-d '{"url":"https://www.threads.com/@user/post/XXXXXXXXX"}'
import os, requests
UA = {"User-Agent": "my-agent/1.0"} # required: "python" user agents are blocked
r = requests.post(
"https://omnimediaapi.com/v1/download",
json={"url": "https://www.threads.com/@user/post/XXXXXXXXX"},
headers={"X-API-Key": os.environ["OMNI_API_KEY"], **UA},
timeout=120,
)
for i, item in enumerate(r.json().get("data", {}).get("media", [])):
if item.get("type") == "audio" or not item.get("url"):
continue
ext = ".mp4" if item["type"] == "video" else ".jpg"
with open(f"file_{i}{ext}", "wb") as f:
f.write(requests.get(item["url"], headers=UA, timeout=120).content)
const r = await fetch("https://omnimediaapi.com/v1/download", {
method: "POST",
headers: {
"X-API-Key": process.env.OMNI_API_KEY,
"Content-Type": "application/json",
"User-Agent": "my-agent/1.0",
},
body: JSON.stringify({ url: "https://www.threads.com/@user/post/XXXXXXXXX" }),
});
const { data } = await r.json();
console.log(data.media.map((m) => `${m.type} ${m.url}`));
You can download photos and videos from public social media posts with OmniMediaApi.
Call:
POST https://omnimediaapi.com/v1/download
Headers: X-API-Key: $OMNI_API_KEY, Content-Type: application/json,
User-Agent: my-agent/1.0
Body: {"url": ""}
Supported: Instagram (posts, reels, carousels), TikTok (videos, photo posts),
Threads, Facebook (videos only), X/Twitter, Pinterest, Douyin.
The answer has data.media[]: each item has "type" (image, video or audio)
and "url" (a direct CDN link). Rules:
- Download every url right away; links expire within hours.
- Skip "audio" items unless asked for sound.
- TikTok, Douyin, Facebook and Pinterest list the same video in several
qualities: take only the first video whose quality contains "HD", else the
first video.
- Instagram, Threads and X carousels list different files: take all of them.
- An item without "url" has "formats": take its first video, else first image.
- Save files with the extension from the url (.jpg, .mp4 ...).
Errors: 404 MEDIA_UNAVAILABLE (private/deleted, do not retry), 424
PROVIDER_UNAVAILABLE or 503 (retry once after 60 s), 429 (wait Retry-After
seconds; QUOTA_EXCEEDED means no downloads left this month).
Downloads left: GET https://omnimediaapi.com/v1/me (same headers, free to call).
Never print the API key.
Same key, other platforms