MeowLoad Docs
On this page

Quickstart

This documentation covers the current version (v1) of the API. If you are still using the legacy, unversioned API (/openapi/…), its documentation is on GitHub at Media-Downloader-API, and the migration guide is Migrating from the legacy API.

v1 is the current version of the developer API. Every endpoint lives under https://api.meowload.net/openapi/v1, and authentication is a single Authorization: Bearer <your API key> header. The full list of endpoints, parameters and response schemas is in the API reference. This page only gets your first request working.

Get an API key

Go to the Developer Console to get your API key. It is an opaque string. Treat it like a password: never ship it in frontend code or commit it to a public repository.

Every <your API key> in the examples below is a placeholder that you must replace with your own key.

Your first request

Extracting a single post:

curl -X POST https://api.meowload.net/openapi/v1/extract/post \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your API key>" \
  -H "Accept-Language: en" \
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'

What the three headers do:

HeaderRequiredDescription
Content-TypeYesAlways application/json
AuthorizationYesBearer <your API key>, with one space between Bearer and the key
Accept-LanguageNoLanguage of error messages. Defaults to en; zh, ja, es, de and more are supported.

Read the response

A successful call returns HTTP 200, and the body is the extraction result itself:

{
  "site": "youtube",
  "id": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video)",
  "text": "The official video for “Never Gonna Give You Up” by Rick Astley.",
  "medias": [
    {
      "media_type": "video",
      "resource_url": "https://rr3---sn-example.googlevideo.com/videoplayback?expire=1757300000&id=o-AbC",
      "preview_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
      "duration": 213,
      "variants": [
        {
          "quality": 1080,
          "quality_label": "1080p",
          "video_url": "https://rr3---sn-example.googlevideo.com/videoplayback?itag=137&expire=1757300000",
          "video_ext": "mp4",
          "video_filesize": 58203122,
          "audio_url": "https://rr3---sn-example.googlevideo.com/videoplayback?itag=140&expire=1757300000",
          "audio_ext": "m4a",
          "audio_filesize": 3451212,
          "is_default": true
        },
        {
          "quality": 720,
          "quality_label": "720p",
          "video_url": "https://rr3---sn-example.googlevideo.com/videoplayback?itag=22&expire=1757300000",
          "video_ext": "mp4",
          "video_filesize": 31776500
        }
      ]
    }
  ],
  "author": {
    "username": "RickAstleyVEVO",
    "display_name": "Rick Astley",
    "avatar_url": "https://yt3.ggpht.com/example=s176-c-k-c0x00ffffff-no-rj"
  },
  "stats": {
    "view_count": 1600000000,
    "like_count": 18000000
  },
  "created_at": "2009-10-25T06:57:33Z",
  "post_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}

A few things to keep in mind:

  • Both title and text are optional. Sites with titles (YouTube, Bilibili, Xiaohongshu, Reddit, and so on) may return both; sites without titles (Twitter, Instagram, Douyin, TikTok, and so on) only return text. For a display caption, use title || text.
  • Missing values are omitted entirely, never sent as null or an empty string. Read every optional field with a fallback.
  • medias[].variants[] lists the resolutions or audio tracks of one media item. quality is the height in pixels (9999 means original quality) and quality_label is the display label. When there are several variants, the one with is_default: true is the recommended pick. A variant that has both video_url and audio_url is a split stream: download both and merge them.
  • Media URLs are short-lived. Download promptly; do not store them or embed them in a page.
  • When a media item carries headers, send those headers as-is when downloading, or the platform will reject the request.
  • site is the platform id the link belongs to (for example youtube or tiktok). It is omitted when the link cannot be classified.

The response shapes for profile batch extraction (/extract/playlist) and subtitles (/extract/subtitles) are in the API reference.

Handle failures

Every non-200 response has the same body shape:

{
  "message": "The content has been deleted or does not exist",
  "code": "content_deleted",
  "retryable": false
}
  • message is human-readable and localized by Accept-Language. Do not branch on it.
  • code is the machine-readable error code. Every 400 carries one, and 429 is always too_many_requests.
  • retryable tells you whether retrying the same URL later might succeed.

Branch on the status code:

StatusMeaningWhat to do
400Extraction failedRead code and retryable: true means retry after a delay, false is final, use another URL
401Invalid API keyCheck that the Authorization header is Bearer <your API key>
402Out of creditsTop up in the Developer Console
422Invalid request bodyFor example a missing url or non-JSON body; detail lists the validation issues
429Rate limited1,200 requests per minute per key; code is too_many_requests; back off and retry
500Server errorRetry later; contact us if it persists

Extraction failures (400) are not charged. All 18 error codes are listed in Errors.

Billing and credits

Only 200 responses are charged. The amount depends on the endpoint and the platform; the rules are listed under "Billing rules" in the Developer Console. Checking your credits is free.

Check your remaining credits at any time:

curl https://api.meowload.net/openapi/v1/credits \
  -H "Authorization: Bearer <your API key>"
{ "availableCredits": 282539 }

We send email and SMS alerts when your balance drops below 10,000, 2,000, 300, 100 and 0. You can also build your own monitoring on this endpoint.

Next steps