Easydown API

API ドキュメント

Easydown API は、バックエンド、スクリプト、自動化サービスから公開メディアリンクを統一形式で解析するための API です。

本番 Endpoint

POST https://api.easydown.org/api/v1/parse

認証

Private API token を Bearer token として送信します。ed_live token をブラウザ JavaScript に埋め込まないでください。

Authorization

Bearer ed_live_xxx

Content-Type

application/json

リクエスト形式

curl -X POST https://api.easydown.org/api/v1/parse \
  -H "Authorization: Bearer ed_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://www.instagram.com/reel/..."}'
{
  "url": "https://www.instagram.com/reel/..."
}

Supported URL formats

All platforms use the same parse endpoint. The formats below are recognized as public single-media links; final results still depend on whether the content is public and available.

TikTok

Supports public single videos and photo posts.

tiktok.com/@user/video/{id}tiktok.com/@user/photo/{id}tiktok.com/t/{shortCode}vm.tiktok.com/{code} or other TikTok share links

Profiles, live pages, and TikTok Lite pages are not supported.

Douyin

Supports public videos, image notes, share links, and selected Douyin CDN media URLs.

v.douyin.com/{code}douyin.com/video/{id}douyin.com/share/video/{id}douyin.com/note/{id}douyin.com/share/note/{id}douyin.com/shipin/{id}douyin.com/vsdetail/{id}douyinpic.com / douyinvod.com / douyinstatic.com media URLs

Profiles, search, collections, follow pages, and live pages are not supported.

YouTube

Supports public single video, Shorts, and live replay URLs that resolve to a video id.

youtu.be/{id}youtube.com/watch?v={id}youtube.com/shorts/{id}youtube.com/live/{id}

Playlists, channels, community posts, and private videos are not supported.

X / Twitter

Supports public post URLs with a status id.

x.com/{user}/status/{id}twitter.com/{user}/status/{id}

Profiles, search pages, spaces, and direct media CDN URLs are not treated as posts.

Instagram

Supports public posts, Reels, videos, photos, carousels, embeds, and share redirects.

instagram.com/p/{code}instagram.com/reel/{code}instagram.com/reels/{code}instagram.com/tv/{code}instagram.com/{username}/p/{code}instagram.com/{username}/reel/{code}instagram.com/p/{code}/embedinstagram.com/r/{code}instagram.com/share/...

Stories, Highlights, profiles, direct messages, Explore pages, and private content are not supported.

Xiaohongshu

Supports public notes, including video and image note links.

xhslink.com/{code}xiaohongshu.com/explore/{noteId}xiaohongshu.com/discovery/item/{noteId}Share text containing a Xiaohongshu URL

Profiles, search pages, collections, and private notes are not supported.

Bilibili

Supports public video pages, short links, list pages with bvid, and selected playable pages.

bilibili.com/video/BV...bilibili.com/video/av...b23.tv/{code}bili.im/{code}bilibili.com/list/...?...bvid=BV...bilibili.com/bangumi/play/ep...bilibili.com/bangumi/play/ss...bilibili.com/cheese/play/ss...

Watchlater lists, favorites, profile pages, and list pages without a single video id are not supported.

Kuaishou

Supports public single Kuaishou video links and share text.

kuaishou.com/short-video/{photoId}kuaishou.com/f/{token}v.kuaishou.com/{token}gifshow.com/fw/photo/{photoId}chenzhongtech.com/fw/photo/{photoId}Share text containing a Kuaishou URL

Profiles, search pages, collections, live pages, and private videos are not supported.

Weibo

Supports public Weibo posts with videos, images, or image galleries.

weibo.com/{uid}/{postId}weibo.com/{uid}/{mblogid}m.weibo.cn/status/{id}weibo.com/tv/show/1034:{id}video.weibo.com/show?fid=1034:{id}t.cn/{code}mapp.api.weibo.cn/fx/...Share text containing a Weibo URL

Profiles, search pages, topics, super topics, live pages, articles, and collections are not supported.

API key permissions

API key can be permanent or expire on a selected date. Leaving expiration blank means it never expires. You can limit a key to selected platforms; All platforms allows every supported platform. Edit changes name, expiration, and platform permissions without changing the token value. Reset rotates the token value while keeping permissions.

統一レスポンス

{
  "status": 200,
  "data": {
    "platform": "instagram",
    "title": "Example title",
    "thumbnail": "https://...",
    "duration": 12,
    "images": [
      {
        "url": "https://...",
        "width": 1080,
        "height": 1350
      }
    ],
    "videos": [
      {
        "url": "https://...",
        "quality": "HD",
        "mimeType": "video/mp4",
        "width": 1080,
        "height": 1920,
        "hasAudio": true,
        "source": "direct"
      }
    ],
    "audios": []
  },
  "msg": "success"
}
{
  "status": 401,
  "data": null,
  "msg": "Unauthorized",
  "code": "missing_token"
}

レスポンスフィールド

FieldTypeDescription
platformstringNormalized platform name such as instagram or youtube.
titlestringMedia title or caption when available.
thumbnailstringPreview image URL when available.
durationnumberDuration in seconds. Images and galleries usually return 0.
images[]arrayDownloadable image items with url, width, and height.
videos[]arrayDownloadable video items with url, quality, mimeType, dimensions, hasAudio, and source.
audios[]arrayDownloadable audio items when the platform exposes audio separately.

メディアURLのダウンロード注意点

Easydown API returns media URLs in images[], videos[], and audios[]. These URLs come from the original platform and may be affected by expiration, anti-hotlinking, CORS, cookies, region limits, or split audio/video streams.

Why direct browser downloads fail

Many media CDNs validate Origin, Referer, cookies, IP region, and request headers. A URL may work from your server but fail in browser JavaScript with CORS, CORP, 403, 404, or an empty file.

Recommended backend proxy flow

  1. Call Easydown API from your server and use returned media URLs for short-term downloads.
  2. Send user downloads through your own backend proxy with the media URL and platform.
  3. Stream the media response from your backend with platform-specific headers.
  4. Forward Range requests for large files and resumable downloads.
  5. If a media URL expires, call the parse API again and retry.

General rules

  • Browser-side fetch or download may fail because many media CDNs block cross-origin requests.
  • For stable downloads, fetch media from your backend and set a browser User-Agent plus the platform Referer when needed.
  • Use streaming or Range requests for large files instead of loading the entire file into memory.
  • Media URLs may expire. If a URL stops working, call the parse API again to refresh it.
  • Private, deleted, region-restricted, live, DRM-protected, or copyright-restricted content may not be downloadable.

Platform header requirements

PlatformRecommended headersCookie needed?Special handlingExpiration notes
DouyinReferer: https://www.douyin.com/; browser User-Agent; forward Range when present.Usually noUse server-side streaming for video and image-note media.URLs are short lived. Re-parse when a link returns 403 or 404.
TikTokReferer: https://www.tiktok.com/; browser User-Agent.SometimesSome web media requires a valid access cookie such as tt_chain_token from your own browsing context. Region-restricted links may require an accessible server region.Re-parse and retry when direct access fails.
BilibiliReferer: https://www.bilibili.com/; browser User-Agent; forward Range.For some high-quality or account-limited streamsDASH results can return separate video and audio URLs. Download both and merge with FFmpeg.Re-parse when signed stream URLs expire.
XiaohongshuReferer: https://www.xiaohongshu.com/; browser User-Agent.SometimesImage and video CDNs can enforce strict anti-hotlinking. Download through your backend.Re-parse when the CDN URL becomes invalid.
WeiboReferer: https://weibo.com/ or https://m.weibo.cn/; browser User-Agent.Usually noChoose the quality URL that matches your product needs when multiple URLs are returned.Image and video URLs can expire. Re-parse to refresh.
YouTubeReferer: https://www.youtube.com/; Origin: https://www.youtube.com; browser User-Agent.For protected or age/account-limited contentHigh-quality streams are often split into audio and video. Merge separated streams with FFmpeg.Some streams are bound to region or IP. Use an accessible server region and re-parse when needed.
InstagramReferer: https://www.instagram.com/; browser User-Agent.SometimesBrowser preview can hit CORS or CORP. Use backend proxy downloads for stable delivery.CDN URLs may expire. Re-parse public posts when needed.
KuaishouReferer: https://www.kuaishou.com/; browser User-Agent; forward Range.Usually noUse server-side streaming for large short-video files.Media URLs can expire. Re-parse the public video link.
X / TwitterReferer: https://x.com/; browser User-Agent.Usually noVideo media may include multiple bitrates. Select the quality that fits your use case.Re-parse when selected media variants fail.

Backend streaming examples

Node.js / Next.js proxy route

// app/api/media-proxy/route.js
const PLATFORM_HEADERS = {
  douyin: {
    Referer: 'https://www.douyin.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  tiktok: {
    Referer: 'https://www.tiktok.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  bilibili: {
    Referer: 'https://www.bilibili.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  xiaohongshu: {
    Referer: 'https://www.xiaohongshu.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  weibo: {
    Referer: 'https://weibo.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  youtube: {
    Referer: 'https://www.youtube.com/',
    Origin: 'https://www.youtube.com',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  instagram: {
    Referer: 'https://www.instagram.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  kuaishou: {
    Referer: 'https://www.kuaishou.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
  twitter: {
    Referer: 'https://x.com/',
    'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
  },
};

export async function GET(request) {
  const { searchParams } = new URL(request.url);
  const mediaUrl = searchParams.get('url');
  const platform = searchParams.get('platform');

  if (!mediaUrl || !platform || !PLATFORM_HEADERS[platform]) {
    return Response.json({ error: 'invalid_request' }, { status: 400 });
  }

  const range = request.headers.get('range');
  const headers = { ...PLATFORM_HEADERS[platform] };
  if (range) headers.Range = range;

  const mediaResponse = await fetch(mediaUrl, { headers });
  if (!mediaResponse.ok || !mediaResponse.body) {
    return Response.json(
      { error: 'download_failed', status: mediaResponse.status },
      { status: 502 }
    );
  }

  const responseHeaders = new Headers();
  const contentType = mediaResponse.headers.get('content-type');
  const contentLength = mediaResponse.headers.get('content-length');
  const contentRange = mediaResponse.headers.get('content-range');

  if (contentType) responseHeaders.set('Content-Type', contentType);
  if (contentLength) responseHeaders.set('Content-Length', contentLength);
  if (contentRange) responseHeaders.set('Content-Range', contentRange);
  responseHeaders.set('Accept-Ranges', 'bytes');
  responseHeaders.set('Cache-Control', 'private, max-age=300');

  return new Response(mediaResponse.body, {
    status: mediaResponse.status,
    headers: responseHeaders,
  });
}

Browser usage

// Browser code: call your own backend, not the platform CDN directly.
const downloadUrl = new URL('/api/media-proxy', window.location.origin);
downloadUrl.searchParams.set('platform', media.platform);
downloadUrl.searchParams.set('url', media.videos[0].url);

window.location.href = downloadUrl.toString();

Merging separated audio and video

# When video and audio are returned separately, download both files first.
ffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4

Troubleshooting

  • 403 usually means missing Referer, missing User-Agent, expired URL, required Cookie, or region restriction.
  • 404 often means the media URL expired. Re-parse the original post URL.
  • CORS or CORP errors usually mean the browser should not request the platform CDN directly. Use your backend proxy.
  • Empty or partial files usually mean Range or streaming was not forwarded correctly.

対応プラットフォーム

TikTokDouyinYouTubeX / TwitterInstagramXiaohongshuBilibiliKuaishouWeibo

課金ルール

成功した解析は 1 credit を消費します。失敗、非対応リンク、認証エラー、プラットフォーム側の応答失敗では credits は消費されません。

対応コンテンツ

API は公開された単一投稿メディア向けです。非公開投稿、削除済みコンテンツ、地域制限、ライブ配信、プロフィール、検索ページ、コレクションページは対象外です。

よくあるエラー

HTTPCodeMeaning
401missing_token / invalid_tokenAuthorization header is missing or the token is invalid.
401token_expiredThe API token has passed its expiration date. Edit the key or create a new one.
403platform_not_allowedThe API token is not allowed to access the platform detected from the URL.
402insufficient_creditsThe account does not have enough credits for a successful parse.
400302The URL format is unsupported or not a single supported media post.
200304Easydown could not return downloadable media for this public link.

Need integration help? Join Telegram or Discord support.