I started building https://instadl.ink — a fast, no-storage media extractor for Instagram & TikTok. Paste a public URL → get direct CDN links. No permanent video storage, just JSON. When I wanted to monetize the API on Apify, every All-in-One downloader there was a yt-dlp wrapper. So I expanded instadl.ink into an 8-platform Enriched Extractor: direct CDN + views/likes for YouTube, TikTok, Instagram, X, Facebook, Reddit, Pinterest, Vimeo — batch 100, 512 MB, $3/1K. No yt-dlp. No ffmpeg. No 4GB RAM.
qbitlabs charges $0.05 per HD video ($50/1K) for 1000+ sites. easyapi does 1 URL/run at $2.99/1K + usage. rover bundles Cobalt + ffmpeg for 21 platforms but needs 4GB and 50 concurrent. We needed the opposite: one run, 100 URLs, enriched stats, no bytes stored.
Live on Apify: lexiie/all-in-one-media-extractor (expanded from instadl.ink) — Build 0.0.11 PPE+Usage $3.00/1,000 failed = free — YT dQw4w9WgXcQ view 1.8B in 366ms, IG reel Dcm8usVMMcG like 0 comment 397 without proxy.
The bill that pushed us off yt-dlp
We started like everyone else: wrapping instadl (IG + TikTok) with yt-dlp for YouTube. Local test was fine. On Apify it wasn’t:
- Build
616MBvs83MB:yt-dlp+ffmpegbase is83MB, but4Kmerge needsffmpeg+4GB RAMfor60svideo. OurNode+undiciBuild 0.0.11is616MBincludingsharpfor logo —yt-dlpversion was~900MBbefore we stripped it. - The math that kills
PPE Only $3:1Kvideos ×50MBavg =50GBexternal transfer $0.2/GB = $10+KVS50GBstore$0.05/1K writes+20 CUffmpeg$4→cost $14→profit = 0.8×$3 - $14 = -$12. That’s whyqbitlabsmust charge+$0.03/GBafter1GBandkhadinakbarcaps at250MB. We didn’t want to charge for bytes we don’t need. - The workaround: Don’t download. Return temporary CDN (
googlevideo expire ~4h,scontent 86.400s,fbcdn,tiktokcdn) and letbrowser → CDNoragent → CDNfetch when needed. ForRAG/UGCyou need theurl+stats, not themp4inKVS.
That decision forced us HTTP-only. No yt-dlp binary, no Cobalt server, no ffmpeg.
What “enriched extractor” actually means (vs URL-only)
URL-only (burbn/easyapi) gives you https://...mp4 and stops. For RAG you then need 3 more scrapers for views/likes to rank, and for UGC you need follower counts to filter influencers.
We return one item with 3 blocks — metadata / stats / media (nested, pruned if undefined):
{
"platform": "tiktok",
"metadata": { "title": "Calm dog...", "uploader": "kings.deals", "duration": 12, "thumbnail": "https://..." },
"stats": { "viewCount": 860465, "likeCount": 5047, "commentCount": 23, "shareCount": 167, "followers": 0 },
"media": [{ "url": "https://v16m.tiktokcdn-us.com/...", "quality": "hd", "mimeType": "video/mp4", "width": 1080, "height": 1920 }]
}
Same shape for all 8:
- YouTube
dQw4w9WgXcQ→8qualities2160p-720p366ms→view 1.8Blike 16MtagschannelId - TikTok
@moh.shofwan 7645528079783267605→view 860K like 5K comment 23 share 167 followers 0+mp4 HD/SD+mp3 - Instagram
Dcm8usVMMcG→like 0 comment 397 view 4+captionpayal_rajput_tv... - X
SpaceX/status/184...→view/like/retweet - Facebook
watch?v=101532...→HD/SD mp4How to share... - Vimeo
22439234The Mountain→progressive mp4ordash+plays/likes - Reddit
r/pics→fallback_url+ups 450num_comments 23 - Pinterest
pin/112426...→origimage +repin
No second call. Dataset views/overview shows inputUrl, platform, type, webpageUrl — fields metadata/stats/media nested.
From instadl.ink to 8 platforms — what broke
I started with instadl.ink — my own fast, no-storage extractor for Instagram & TikTok. To make it monetizable on Apify, I expanded it to 8 platforms. Each new one broke at least once:
- YouTube — lightweight
innertubePOST /youtubei/v1/playerreturnsstreamingDatawithoutsignatureCipher(no decipher).WEBwould needpoToken. - TikTok — returns
gzipwithoutcontent-encodingheader, so manual decompression + retry with new device. - Instagram —
embedlikeCountregex failed because HTML escaped → fix to permissiveedge_liked_bypattern.view 4is real from embed (nullfor many reels is normal). - X —
syndicationtoken.404forNasa 174...because ID doesn’t exist, not code. - Facebook —
loginwallnot logged in→PRIVATE_CONTENTfree. - Vimeo —
player.vimeo.comcert hijack in local ISP →ProxyAgent→origin✅, butprogressiveempty for some (dash only) → fallbackoembed. - Batch —
100vs1(easyapi/qbitlabs1 URL/run) —5 concurrent300mscache5m→100 URLs ≈ 30svs100 runs100×overhead.
Pricing that doesn’t punish batch
PPE+Usage ON → video-extracted $0.003 ($3/1K) event covers extractor, CU/proxy/transfer billed separate to user. failed/private = free (so IG PRIVATE_CONTENT doesn’t cost). PPE Only would be 0.8*3 - costs and we’d be -$12 for bytes.
-
10 URLs→Max $0.03(setMinimum $0.01in StoreMonetization → Additional optionsso user can’tMax $0.001free ride) -
100 URLs720pbest→Max $0.30+~$1compute (5 CU) +0.1GBproxy $0.80(only ifRESIDENTIAL) →$1.30vsqbitlabs $5forHD($0.05perHD=$50/1K) -
Discounts: BRONZE $0.003 → SILVER $0.0025 → GOLD $0.0015— sameeasyapitier, but webatch 100soGOLD100 URLs$0.15cheaper.
Store now single event video-extracted PPE+Usage $3/1K. If you want 2 events basic $1.50 / enriched $3 later, just add enriched flag back.
What we intentionally don’t do (and why that’s a feature)
- No private bypass —
PRIVATE_CONTENTfree, passcookiesonly if you own the content.InstagramPrivSniffer(collab intended) andjatin-dot-py(polaris_timeline_connection28%bypass, patched16 Oct 2025) areToSviolations onApify— Store wouldtakedown. - No bytes —
maxFileSizeMBjust skips>250MBfor agents; we don’t mergeHLS. If you needbytes, use downloader withR2. - No 1000+ sites —
qbitlabs1000+isyt-dlplist, we do8core social +enrichedbatch 100withoutyt-dlp. ForSoundCloud/Twitchwe’ll add HTTP-only next, notyt-dlp.
Try the exact URLs we tested (no proxy needed for 3)
curl -X POST "https://api.apify.com/v2/acts/lexiie~all-in-one-media-extractor/runs?token=TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://www.youtube.com/watch?v=dQw4w9WgXcQ","https://www.tiktok.com/@moh.shofwan/video/7645528079783267605","https://www.instagram.com/reel/Dcm8usVMMcG/"],"quality":"720p","audioOnly":false}'
Dataset 0.0.11 0R4ECgZIOkkdbjVUb SUCCEEDED 512 MB apify/actor-node:20 returns metadata/stats/media nested — overview view shows inputUrl, platform, type, webpageUrl — latencyMs 366ms YT, 852ms IG, 2838ms TT (3 retries).
Storage inputUrl success platform webpageUrl metadata.title stats.viewCount media[0].url latencyMs — flat for dataset but clean for LLM RAG (no KVS file to fetch).
If you need 1000+ sites, use qbitlabs ($0.05 HD = $50/1K). If you need 8 core social + enriched + batch 100 + direct CDN without yt-dlp/ffmpeg/4GB, use this. Build 0.0.11 live at https://console.apify.com/actors/GdXcUau5zytXfvdvS — star it and request SoundCloud/Twitch next — we’ll add without yt-dlp.
Top comments (0)