API & MCP

Extract and download Twitter / Xmedia programmatically. There's a JSON REST API and a Model Context Protocol (MCP) server so AI agents can do it directly.

One-click bookmarklet

Prefer a button over an API? A bookmarklet skips the copy-paste. It opens the post you're viewing straight in the downloader, with no extension to install.

Make a new bookmark, name it something like “Save video”, and paste this as the URL. Click it while viewing any Twitter / X post to open it here with the link already filled in.

javascript:(function(){window.open('https://download-twitter-video.drummerduck.com/?url='+encodeURIComponent(location.href),'_blank')})();

Authentication & rate limits

Auth is optional. Without a key you get 30 requests/hour and 100/day per IP. Send an API key for higher limits (300/hour, 2000/day on the free tier). Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; exceeding the limit returns 429 with a Retry-After header.

Header
Authorization: Bearer YOUR_API_KEY
# or
X-API-Key: YOUR_API_KEY

Get a free API key (no signup)

Mint a key with a single request — no account, no dashboard. The key is returned once, so store it. An agent can do this itself, either over REST or via the get_free_api_key MCP tool below. Key creation is rate-limited per IP.

cURL
curl -X POST "https://download-twitter-video.drummerduck.com/api/keys" \
  -H "content-type: application/json" \
  -d '{"label":"my-bot"}'
# → { "ok": true, "data": { "apiKey": "dtv_live_…", "tier": "free",
#       "limits": { "perHour": 300, "perDay": 2000 } } }

Check a key's tier and limits any time by sending it to the same endpoint with GET.

cURL
curl "https://download-twitter-video.drummerduck.com/api/keys" -H "Authorization: Bearer YOUR_API_KEY"

Extract media

Returns author, text, thumbnail, and every media variant with direct URLs.

cURL
curl "https://download-twitter-video.drummerduck.com/api/extract?url=https://x.com/SpaceX/status/1919172303709184350"
JavaScript
const res = await fetch("https://download-twitter-video.drummerduck.com/api/extract", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ url: "https://x.com/SpaceX/status/1919172303709184350" }),
});
const { ok, data } = await res.json();
const best = data.media[0].variants[0]; // highest quality
console.log(best.quality, best.url);
Response (trimmed)
{
  "ok": true,
  "data": {
    "source": "twitter",
    "url": "https://x.com/SpaceX/status/1919172303709184350",
    "author": { "name": "…", "handle": "…", "avatar": "https://…" },
    "text": "…",
    "thumbnail": "https://…",
    "media": [
      {
        "type": "video",
        "durationMs": 30000,
        "variants": [
          { "quality": "1080p", "width": 1920, "height": 1080,
            "container": "mp4", "url": "https://…1920x1080….mp4" },
          { "quality": "720p", "container": "mp4", "url": "https://…" }
        ]
      }
    ]
  }
}

Download a file

Streams the chosen variant as an attachment (correct filename + Content-Disposition). Use quality to pick a resolution and n for the media index.

cURL
curl -L -o video.mp4 \
  "https://download-twitter-video.drummerduck.com/api/download?url=https://x.com/SpaceX/status/1919172303709184350&quality=1080p"

MCP server (for AI agents)

A Streamable-HTTP MCP endpoint. Point any MCP client at it to give your assistant three tools: extract_twitter_video, get_tweet_info, and get_free_api_key (so the agent can raise its own limits).

Endpoint
https://download-twitter-video.drummerduck.com/api/mcp
Client config (Claude Desktop, Cursor, …)
{
  "mcpServers": {
    "twitter-video": {
      "url": "https://download-twitter-video.drummerduck.com/api/mcp"
    }
  }
}
stdio-only clients (via mcp-remote)
{
  "mcpServers": {
    "twitter-video": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://download-twitter-video.drummerduck.com/api/mcp"]
    }
  }
}

Errors

Failures return { "ok": false, "error": { "code", "message" } }. Codes: INVALID_URL, NOT_FOUND, NO_MEDIA, PROTECTED, RATE_LIMITED, UPSTREAM_ERROR.