Updated October 2026 · Public API v1
XDownload API
Quick answer: XDownload exposes a free, key-less media resolver API at https://xdownload.top. /api/health, /api/config, /api/download and the /s/ link-hack are open; /api/resolve and /api/zip require either a Turnstile token (site frontend) or a developer token (Authorization: Bearer xdv1_…) — the token skips Turnstile and unlocks higher limits. Every endpoint is rate-limited per IP.
Base
| Base URL | https://xdownload.top |
|---|---|
| Auth | None for open endpoints. Protected endpoints (resolve, zip) accept EITHER a Turnstile token (site frontend) OR a developer token (Authorization: Bearer ***). |
| Rate limits | Per IP per minute, anonymous: resolve 20 / 40 (edge KV) · download 45 · zip 10 / 25. With a developer token: resolve 60 / 120 · download 240 · zip 30 / 60 (per token). Exceeding returns 429 with a Retry-After header. |
| Formats | JSON responses; media served as original MP4/JPG streams. MP3 conversion is not offered. |
GET /api/health
Service heartbeat. Open, no token.
curl https://xdownload.top/api/health
# → {
# "ok": true,
# "service": "XDownload",
# "time": "2026-10-01T00:00:00.000Z",
# "features": ["resolve","batch","proxy-download","edge-cache","zip-download",
# "multi-quality","history-client","turnstile","global-rate-limit","pwa"],
# "turnstile": { "enabled": true, "siteKey": "0x4AAA…" }
# }
GET /api/config
Client bootstrap config. Open, no token.
curl https://xdownload.top/api/config
# → {
# "ok": true,
# "turnstileSiteKey": "0x4AAA…",
# "turnstileRequired": true,
# "siteName": "XDownload",
# "siteUrl": "https://xdownload.top",
# "country": "US",
# "features": { "zip": true, "batch": true, "pwa": true },
# "smartLinks": [ … ]
# }
POST /api/resolve
Resolves a public post link into media metadata. Two access paths: ① Turnstile token (body turnstileToken — how this site's own frontend calls it) or ② developer token via Authorization: Bearer *** — skips Turnstile, 3-6x higher limits, per-token rate bucket. Without either: 403 turnstile_failed.
Request body:
{
"url": "https://x.com/user/status/123",
"urls": ["https://x.com/a/status/1", "…"],
"turnstileToken": "XXXX"
}
With a developer token (recommended for bots/scripts):
curl -X POST https://xdownload.top/api/resolve \
-H "Authorization: Bearer xdv1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"url": "https://x.com/user/status/123"}'
Response (single):
{
"ok": true,
"data": {
"id": "123",
"url": "https://x.com/user/status/123",
"text": "post text…",
"author": { "name": "…", "screenName": "…", "avatar": "…" },
"media": [ {
"type": "video",
"url": "https://video.twimg.com/…",
"thumbnail": "…", "width": 1280, "height": 720, "bitrate": 2176000,
"variants": [ { "url": "…", "contentType": "video/mp4", "bitrate": 2176000, "height": 720 } ]
} ]
},
"meta": { "remaining": 19, "batch": false, "scope": "mem" }
}
Response (batch): { "ok": true, "batch": true, "results": [ … ], "meta": { "remaining", "count", "scope" } } — each results[] entry is { "ok": true, "input", "data" } or { "ok": false, "input", "error" }; one broken link does not fail the batch.
GET /api/download
Proxied media download with edge caching. Open — under policies: same-origin or no Referer (typed URL / server-side), no cross-site hotlinking, allowed media hosts only.
curl -OJ "https://xdownload.top/api/download?url=https%3A%2F%2Fvideo.twimg.com%2F…&filename=clip.mp4"
| Param | Notes |
|---|---|
url (required) | Media URL from a supported platform CDN (twimg.com, TikTok CDN, Reddit media, Pinterest CDN…) |
filename | Download filename; .mp3 is rejected with 415 |
inline=1 | Stream inline instead of attachment (used for previews) |
POST /api/zip
Packs multiple media files into a single ZIP (powers the site's "Download All" button). Turnstile-protected like resolve; 10 req/min. Body: { "files": [ { "url": "…", "filename": "…" } ], "zipName": "archive.zip", "turnstileToken": "…" }. Returns application/zip with an X-File-Count header.
Developer tokens
For bots, scripts and third-party apps. A token skips the Turnstile requirement on resolve/zip and gets its own higher rate bucket (resolve 60/min, download 240/min, zip 30/min). Tokens are revocable and tracked per token — abuse kills your token, not the site.
How to get one: email hello@xdownload.top with your project name and expected volume — tokens are issued manually (usually within a day).
Usage: send Authorization: Bearer xdv1_… (or X-API-Key header) on any request. Invalid or revoked tokens get 401 invalid_token.
GET /s/ link-hack
The friendliest integration path: insert xdownload.top/s/ right after the https:// of any supported post URL. The server 302-redirects to the tool with the link pre-filled and auto-parsed — no token, works from any app or browser.
https://xdownload.top/s/https://x.com/user/status/123 # → 302 → https://xdownload.top/?url=https%3A%2F%2Fx.com%2Fuser%2Fstatus%2F123&src=linkhack
Errors
| Code | Meaning |
|---|---|
400 | Bad request — invalid JSON, missing params, or media host not allowed |
401 | invalid_token — developer token missing/expired/revoked |
403 | turnstile_failed (protected endpoints) or hotlink_blocked (cross-site download) |
404 | Post not found, private, or no downloadable media |
415 | MP3 conversion requested — download the original media instead |
429 | Rate limited — honor Retry-After |
502 | Upstream fetch failed — retry with backoff |
Policies
- Free, no key, no account. Attribution appreciated, not required.
- Don't hammer: rate limits are per-IP and shared with the public site.
- Only public posts resolve — private accounts are off-limits by platform design.
- Building something on top? Tell us — custom filenames, batch mode and the QR flow run on the same machinery.