Instagram, Meta, Buffer, and TikTok don’t open share links — their crawlers fetch raw bytes. Here’s how every option actually behaves when a platform API comes knocking.
Each of these tools is good at its own job. Only one of those jobs is serving files to platform crawlers.
| Service | Built for | Link type | Max lifespan | Passes Instagram’s crawler? | Setup time |
|---|---|---|---|---|---|
| Google Drive | Human collaboration | HTML viewer page | Permanent | ✕ NoFails crawler validation — error 9004 | ~5 min |
| Dropbox | Human file sync | HTML viewer pagedl=1 workaround blocked by Instagram |
Permanent | ✕ NoFails crawler validation — error 9004 | ~5 min |
| AWS S3 | General cloud storage | Direct bytesonce bucket policy & Content-Type are configured | Permanent | ⚠ Yes, with setupPublic bucket + correct headers required | ~45 minIAM, buckets, policies |
| MoonPush | Instant person→person transfer | E2E-encrypted linkcrawlers get opaque encrypted bytes by default | 30 minutes | ✕ NoExpires before most schedules run | ~10 sec |
| file.io | One-shot secure hand-off | Direct downloadfile deletes after the first download | Until first download | ✕ NoCrawler’s validation fetch deletes the file | ~30 sec |
| CurlyFlies | Serving files to platform APIs | Direct bytescorrect Content-Type, no cookies, no redirects | 24h – 90 daysby plan | ✓ YesBy design — passes the incognito test | ~30 secone curl |
The objective pass/fail standard for any “public URL.” If a URL fails this test, it will fail Instagram’s crawler, Buffer’s validator, and every other platform fetcher — no exceptions.
No cookies, no sessions, no logged-in accounts. This is exactly what a platform crawler sees: a stranger with an HTTP client.
The raw file must load — the actual image or video bytes. Not a preview page, not a download button, not a login prompt, not a redirect chain.
Run curl -I on the URL: status 200, a real Content-Type like image/png, no Location, no Set-Cookie.
$ curl -I https://curlyflies.com/f/x7k2.png HTTP/2 200 content-type: image/png content-length: 204800 # No Location. No Set-Cookie. No HTML. Crawlers accept this.
Seriously. These tools are excellent at their own jobs — just not at this one.
Sending a file to a person right now? MoonPush is the fastest hand-off on the internet — up to 100 GB, E2E-encrypted, no signup, and your friend starts downloading before you finish uploading. That’s its whole job, and it does it brilliantly.
Need a permanent filesystem your agent reads and writes across sessions — memory, workspaces, long-lived project files? Folder.md is agent-native storage from the ground up: REST, MCP, and SDK. Storage is their job; serving is ours.
Already running on AWS with IAM roles, Terraform, and a platform team? S3 absolutely passes platform crawlers once configured, and you keep everything in one cloud. If the 45-minute setup is already done, you may not need us.
Error 9004 (“Media fetch failed”) comes back from the Instagram Graph API when its crawler can’t download the file at the URL you gave it. The URL must serve raw file bytes with a correct Content-Type, publicly, with no login, redirect, or viewer page. Drive and Dropbox share links serve HTML pages, so they fail. Full troubleshooting guide →
A Dropbox share link points to an HTML viewer page, not the file. Instagram’s crawler fetches it, sees text/html instead of an image or video, and rejects the post. The old dl=1 direct-download trick is blocked by Instagram. The fix is to re-host the file somewhere that serves raw bytes.
24 hours on the free plan, up to 30 days on Builder, 60 days on Pro, and 90 days on Scale. Set ttl_seconds per upload. Long enough to outlive any content schedule — then the file vanishes automatically.
Most break structurally. file.io deletes the file after the first download — Instagram’s crawler fetches once during validation, and your actual post then 404s. MoonPush links expire in 30 minutes and are E2E-encrypted by default, so crawlers receive opaque bytes. Scheduling-grade hosting needs direct bytes and a TTL that outlives the schedule.
Upload once, get a URL that passes the incognito test, and ship your schedule.
$ curl -X POST https://curlyflies.com/v1/upload \ -H "Authorization: Bearer $CURLY_KEY" \ -F "[email protected]" → { "url": "https://curlyflies.com/f/x7k2.png", "expires_at": "2026-09-10T09:41Z" }