Scraper API
Live scrape status available at /status

Scraper API

Learn how to query real-time Instagram, TikTok, Facebook, X and YouTube data through one clean, developer-first HTTP endpoint.

Refetch(er) provides a single unified scrape entry point for Instagram, TikTok, Facebook, and X posts and profiles, YouTube video metrics, recent YouTube comments, and YouTube channel data. Your request body tells the API what resource you want, and the gateway routes it to the correct scraper internally.

New to Refetch(er)? All new accounts receive $10 of free trial credit instantly upon signup. Prepay only for what you run — and remember, failed requests are never billed.

Authentication

All scrape requests require an API key generated from your user dashboard. Public status and health routes are readable without a key.

Pass your API key in either of the following HTTP headers:

Header Value Format Description
X-API-Key pc_live_... The preferred header format for custom requests.
Authorization Bearer pc_live_... Alternative standard authentication header.
Keep your key secure. Never expose your API keys in frontend client code (browsers, client-side scripts). Always proxy requests to Refetch(er) through your own backend server.

Endpoints

Refetch(er) serves all live scrape requests from a single endpoint, accepting POST JSON payloads to determine which platform and resource to fetch.

POST https://api.refetcher.com/

Alternatively, the route alias POST https://api.refetcher.com/v1/scrape is fully supported for compatibility but we recommend calling the root path directly.

GET https://api.refetcher.com/ and GET https://api.refetcher.com/status return the public API status page. GET https://api.refetcher.com/health returns a lightweight JSON health response.

Supported Resources

Each live scraper uses the same endpoint. The API detects the target from fields such as url, profileUrl, username, channelUrl, or handle.

Live

Instagram Post/Reel

Fetch metrics, caption, hashtags, dimensions, duration, thumbnails, and public media source URLs for Instagram posts and reels.

url
Live

Instagram Profile

Fetch public profile metadata and up to 50 recent timeline items with browserless cursor pagination.

username profileUrl
Live

Facebook Post/Reel

Fetch public reactions, comments, shares, views for videos/Reels, and photo or carousel media children when exposed.

url
Live

Facebook Profile

Fetch public profile metadata and up to 50 recent timeline items with cursor pagination.

username profileUrl
Live

TikTok Video

Fetch views, likes, comments, shares, saves, author data, and video metadata for public TikTok videos.

url
Live

TikTok Profile

Fetch creator metadata, audience counts, total likes, verification, and recent public videos.

username profileUrl
Live

X Post

Fetch views, likes, retweets, replies, and tweet media attachments for public X posts.

url
Live

X Profile

Fetch public profile metadata including followers, following, and tweet counts.

username profileUrl
Live

YouTube Video

Fetch views, likes, comments, video metadata, and optional newest public top-level comments for videos or Shorts.

url includeRecentComments
Live

YouTube Channel

Fetch channel subscribers, total views, video count, thumbnails, and optional recent uploads with metrics.

channelUrl handle

Instagram Post/Reel

To request metrics for a single public Instagram post or reel, send a url string in the body:

Request JSON
{
  "url": "https://www.instagram.com/reel/C8xExampleAbc/"
}

The response returns metrics, post, author, and a media object. Media fields include thumbnail/video/audio source URLs, duration, dimensions, separate play/view counts, music attribution, and carousel children when Instagram exposes them. Instagram shares and saves remain null when they are not publicly available.

Media URL lifetime: Instagram CDN URLs are source URLs and may expire. Store the file in your own infrastructure when you need a durable asset.

Instagram Profile

To request public profile metadata, send either a username or a profile URL. Use includeRecentPosts when you also want lightweight recent media returned with the profile. Instagram profile requests support 1-50 recent timeline items without a browser or login.

Request JSON
{
  "username": "nasa",
  "includeRecentPosts": true,
  "recentPostsLimit": 36
}
Profile URL Alias
{
  "profileUrl": "https://www.instagram.com/nasa/",
  "includeRecentPosts": false
}

The response returns type: "profile", a profile object, and optional recentPosts or recentVideos arrays when recent media is requested. Results beyond the first 12 are fetched with Instagram's timeline cursor in additional 12-item pages.

Profile Result Shape
{
  "url": "https://www.instagram.com/nasa/",
  "platform": "instagram",
  "type": "profile",
  "success": true,
  "profile": {
    "id": "528817151456180",
    "handle": "nasa",
    "name": "NASA",
    "biography": "Exploring the universe and our home planet.",
    "followers": 97400000,
    "following": 78,
    "totalPosts": 4123,
    "totalVideos": 171,
    "totalLikes": null,
    "highlightReelCount": 42,
    "isPrivate": false,
    "isVerified": true,
    "isBusinessAccount": false,
    "isProfessionalAccount": true,
    "categoryName": "Science, Technology & Engineering",
    "externalUrl": "https://www.nasa.gov/",
    "profilePicUrl": "https://...",
    "profilePicUrlHd": "https://..."
  },
  "recentPosts": [],
  "pageInfo": {
    "recentPosts": {
      "hasNextPage": true,
      "endCursor": "...",
      "requestedLimit": 36,
      "returnedCount": 36
    }
  },
  "scrapedAt": "2026-06-05T10:15:30.000Z",
  "source": "direct"
}

The normalized Instagram/TikTok/Facebook profile schema always contains id, handle, name, biography, followers, following, totalPosts, totalVideos, totalLikes, highlightReelCount, isPrivate, isVerified, isBusinessAccount, isProfessionalAccount, categoryName, externalUrl, profilePicUrl, and profilePicUrlHd. Fields not exposed by a platform return null or false.

Facebook Post/Reel

To request metrics for a public Facebook Reel, video, post, photo, or carousel, send the canonical Facebook URL in the body. Video/Reel results include public view counts when available. Image, photo, carousel, and text posts return views: null with metricAvailability.views: "not_applicable".

Request JSON
{
  "url": "https://www.facebook.com/reel/2781078362247521/"
}

Supported URL shapes include /reel/..., /videos/..., /watch/?v=..., /posts/..., /photo.php, /permalink.php, and fb.watch links. Facebook saves are not publicly exposed and return null. Carousel and photo items are normalized under media.children.

Post Result Shape
{
  "url": "https://www.facebook.com/reel/2781078362247521/",
  "platform": "facebook",
  "success": true,
  "metrics": {
    "views": 3400,
    "likes": 31,
    "comments": 1,
    "shares": 28,
    "saves": null
  },
  "metricAvailability": {
    "views": "available",
    "likes": "available",
    "comments": "available",
    "shares": "available",
    "saves": "unavailable"
  },
  "post": {
    "id": "2781078362247521",
    "shortcode": null,
    "normalizedUrl": "https://www.facebook.com/reel/2781078362247521/",
    "publishedAt": null,
    "caption": "Public caption",
    "type": "reel",
    "productType": "reel",
    "hashtags": [],
    "mentions": [],
    "location": null,
    "commentsDisabled": null,
    "isPinned": null,
    "isSponsored": null
  },
  "author": {
    "id": null,
    "handle": "Meta",
    "name": "Meta",
    "followers": null,
    "isVerified": null,
    "profilePicUrl": null
  },
  "media": {
    "thumbnailUrl": "https://...",
    "videoUrl": "https://...",
    "durationSeconds": 30,
    "width": null,
    "height": null,
    "altText": null,
    "children": []
  },
  "scrapedAt": "2026-06-10T10:15:30.000Z",
  "source": "direct"
}

Facebook Profile

Send a Facebook username or profile URL. Enable includeRecentPosts to request recent public timeline items. Facebook profile requests support the same 1-50 default recent-post range as Instagram.

Request JSON
{
  "type": "profile",
  "platform": "facebook",
  "username": "Meta",
  "includeRecentPosts": true,
  "recentPostsLimit": 25
}
Profile Result Shape
{
  "url": "https://www.facebook.com/Meta/",
  "platform": "facebook",
  "type": "profile",
  "success": true,
  "profile": {
    "id": "100080376596424",
    "handle": "Meta",
    "name": "Meta",
    "biography": "Connect with what you love.",
    "followers": 106677848,
    "following": null,
    "totalPosts": null,
    "totalVideos": null,
    "totalLikes": 106000000,
    "highlightReelCount": null,
    "isPrivate": false,
    "isVerified": true,
    "isBusinessAccount": false,
    "isProfessionalAccount": false,
    "categoryName": null,
    "externalUrl": null,
    "profilePicUrl": "https://...",
    "profilePicUrlHd": "https://..."
  },
  "recentPosts": [
    {
      "id": "1032807172741826",
      "shortcode": "1032807172741826",
      "url": "https://www.facebook.com/Meta/posts/1032807172741826/",
      "type": "carousel",
      "isVideo": false,
      "views": null,
      "likes": 29000,
      "comments": 7100,
      "shares": 1800,
      "saves": null,
      "publishedAt": "2026-06-01T00:00:00.000Z",
      "caption": "Public post caption",
      "displayUrl": "https://...",
      "media": {
        "thumbnailUrl": "https://...",
        "videoUrl": null,
        "durationSeconds": null,
        "width": null,
        "height": null,
        "altText": null,
        "children": []
      },
      "dimensions": null
    }
  ],
  "pageInfo": {
    "recentPosts": {
      "hasNextPage": true,
      "endCursor": "...",
      "requestedLimit": 25,
      "returnedCount": 1,
      "incomplete": false
    },
    "recentVideos": {
      "hasNextPage": true,
      "endCursor": "...",
      "requestedLimit": 25,
      "returnedCount": 0,
      "incomplete": false
    }
  },
  "limitations": [],
  "scrapedAt": "2026-06-10T10:15:30.000Z",
  "source": "direct"
}

Facebook can throttle timeline pagination independently of profile metadata. In that case the profile result can still be successful while pageInfo.recentPosts.incomplete is true and limitations explains the partial timeline.

TikTok Video

To request metrics for a single public TikTok video, send its canonical tiktok.com/@username/video/... URL in the body. Redirect-only short links such as vm.tiktok.com are not accepted.

Request JSON
{
  "url": "https://www.tiktok.com/@creator/video/7398210000000000000"
}

TikTok video responses populate views, likes, comments, shares, and saves when those fields are available.

Video Result Shape
{
  "url": "https://www.tiktok.com/@creator/video/7398210000000000000",
  "platform": "tiktok",
  "success": true,
  "metrics": {
    "views": 2400000,
    "likes": 98400,
    "comments": 3210,
    "shares": 12200,
    "saves": 18400
  },
  "metricAvailability": {
    "views": "available",
    "likes": "available",
    "comments": "available",
    "shares": "available",
    "saves": "available"
  },
  "post": {
    "id": "7398210000000000000",
    "shortcode": null,
    "normalizedUrl": "https://www.tiktok.com/@creator/video/7398210000000000000",
    "publishedAt": "2026-06-01T08:30:00.000Z",
    "caption": "Example video caption",
    "type": "video",
    "productType": null,
    "hashtags": [],
    "mentions": [],
    "location": null,
    "commentsDisabled": false,
    "isPinned": false,
    "isSponsored": false
  },
  "author": {
    "id": "123456789",
    "handle": "creator",
    "name": "Creator Name",
    "followers": 312000,
    "isVerified": false,
    "profilePicUrl": "https://..."
  },
  "scrapedAt": "2026-06-09T10:15:30.000Z",
  "source": "direct"
}

TikTok Profile

Send a TikTok username or profile URL. Enable recent posts to receive the public videos exposed by TikTok's creator embed.

Request JSON
{
  "type": "profile",
  "platform": "tiktok",
  "username": "nba",
  "includeRecentPosts": true,
  "recentPostsLimit": 12
}
Profile Result Shape
{
  "url": "https://www.tiktok.com/@nba",
  "platform": "tiktok",
  "type": "profile",
  "success": true,
  "profile": {
    "id": "6749213842887734277",
    "handle": "nba",
    "name": "NBA",
    "biography": "The official NBA account.",
    "followers": 26800000,
    "following": 266,
    "totalPosts": null,
    "totalVideos": 12,
    "totalLikes": 1100000000,
    "highlightReelCount": null,
    "isPrivate": false,
    "isVerified": true,
    "isBusinessAccount": false,
    "isProfessionalAccount": false,
    "categoryName": null,
    "externalUrl": null,
    "profilePicUrl": "https://...",
    "profilePicUrlHd": null
  },
  "recentVideos": [
    {
      "id": "7648122936318020894",
      "url": "https://www.tiktok.com/@nba/video/7648122936318020894",
      "views": 2700000,
      "publishedAt": "2026-06-06T03:43:06.000Z"
    }
  ],
  "source": "direct"
}

Recent profile videos include links, captions, cover images, timestamps, and play counts. Use the TikTok Video scraper when you need likes, comments, shares, and saves for a specific video.

X Post

To request metrics for a single public X post (tweet), send its URL in the body. X post scraping returns views, likes, replies, retweets, and any attached media elements.

Request JSON
{
  "url": "https://x.com/SpaceX/status/1779119982"
}

Supported URL shapes include x.com/username/status/... and twitter.com/username/status/.... In the returned metrics, replies are mapped to comments, retweets to shares, and bookmarks to saves.

Post Result Shape
{
  "url": "https://x.com/SpaceX/status/1779119982",
  "platform": "x",
  "success": true,
  "metrics": {
    "views": 5350265,
    "likes": 148761,
    "comments": 3441,
    "shares": 21255,
    "saves": 3469
  },
  "metricAvailability": {
    "views": "available",
    "likes": "available",
    "comments": "available",
    "shares": "available",
    "saves": "available"
  },
  "post": {
    "id": "1779119982",
    "shortcode": "1779119982",
    "normalizedUrl": "https://x.com/SpaceX/status/1779119982",
    "publishedAt": "2026-06-10T19:28:28.000Z",
    "caption": "Launch update: …",
    "type": "text",
    "productType": "tweet",
    "hashtags": [],
    "mentions": []
  },
  "author": {
    "id": "34713599",
    "handle": "SpaceX",
    "name": null,
    "followers": 41700000,
    "isVerified": true,
    "profilePicUrl": null
  },
  "media": {
    "thumbnailUrl": null,
    "videoUrl": null,
    "durationSeconds": null,
    "width": null,
    "height": null,
    "altText": null,
    "items": []
  },
  "scrapedAt": "2026-06-10T10:15:30.000Z",
  "source": "direct"
}
All five core metrics are available for X posts: views, likes, comments (replies), shares (retweets), and saves (bookmarks). Quote tweets are returned separately in the raw response but are not included in the normalized metrics object.

X Profile

To request public X profile metadata, send an X username or profile URL. Enable recent posts to return a list of recent public posts exposed by the profile timeline.

Request JSON
{
  "type": "profile",
  "platform": "x",
  "username": "SpaceX",
  "includeRecentPosts": true,
  "recentPostsLimit": 12
}
Profile Result Shape
{
  "url": "https://x.com/SpaceX",
  "platform": "x",
  "type": "profile",
  "success": true,
  "profile": {
    "id": "34713599",
    "handle": "SpaceX",
    "name": "SpaceX",
    "biography": "SpaceX designs, manufactures and launches advanced rockets and spacecraft.",
    "followers": 41700000,
    "following": 123,
    "totalPosts": 11400,
    "isPrivate": false,
    "isVerified": true,
    "profilePicUrl": "https://..."
  },
  "recentPosts": [],
  "scrapedAt": "2026-06-10T10:15:30.000Z",
  "source": "direct"
}

YouTube Video

To request metrics for a public YouTube video or Short, send a YouTube URL in the body. Enable includeRecentComments when you want newest public top-level comments returned with the same response.

Request JSON
{
  "url": "https://www.youtube.com/watch?v=8jPQjjsBbIc",
  "includeRecentComments": true,
  "recentCommentsLimit": 20
}

Supported video URL formats include standard watch URLs, Shorts URLs, embeds, live URLs, and youtu.be links. YouTube does not expose shares or saves through this API, so those metrics return null.

Video Result Shape
{
  "url": "https://www.youtube.com/watch?v=8jPQjjsBbIc",
  "platform": "youtube",
  "success": true,
  "metrics": {
    "views": 1650000,
    "likes": 42000,
    "comments": 1800,
    "shares": null,
    "saves": null
  },
  "post": {
    "id": "8jPQjjsBbIc",
    "normalizedUrl": "https://www.youtube.com/watch?v=8jPQjjsBbIc",
    "publishedAt": "2026-06-01T08:30:00.000Z",
    "caption": "Example video title",
    "description": "Example video description"
  },
  "author": {
    "handle": "UCAuUUnT6oDeKwE6v1NGQxug",
    "name": "TED",
    "followers": null
  },
  "recentComments": [
    {
      "id": "comment-id",
      "authorName": "Viewer",
      "authorChannelId": "UC...",
      "authorChannelUrl": "https://www.youtube.com/channel/UC...",
      "text": "Example comment",
      "likes": 12,
      "publishedAt": "2026-06-09T09:00:00.000Z",
      "updatedAt": "2026-06-09T09:00:00.000Z",
      "replyCount": 1
    }
  ],
  "scrapedAt": "2026-06-09T10:15:30.000Z",
  "source": "youtube-data-api-v3"
}
YouTube video results use a smaller platform-specific post/author schema and currently do not include metricAvailability. recentComments is present only when requested; if comment retrieval fails, the response includes an empty array and recentCommentsError.

YouTube Channel

To request YouTube channel data, set type to "channel" or "channelVideos". You can pass a channel URL, raw channel ID, or @handle.

Channel Profile
{
  "type": "channel",
  "platform": "youtube",
  "channelUrl": "https://www.youtube.com/@TED",
  "includeRecentVideos": true,
  "recentVideosLimit": 12
}
Channel Videos
{
  "type": "channelVideos",
  "platform": "youtube",
  "handle": "@TED",
  "recentVideosLimit": 12
}

Channel profile responses return type: "channel" and a profile object. Channel-video responses return type: "channelVideos", a lightweight channel object, and results/videos arrays.

Batch Scrape

You can query multiple targets concurrently in a single API call by passing an array of strings under the urls, profileUrls, or compatible URL fields. Optionally, supply requiredFields to enforce metric presence.

Request JSON
{
  "urls": [
    "https://www.instagram.com/reel/C8xExampleAbc/",
    "https://www.tiktok.com/@creator/video/7398210000000000000",
    "https://www.facebook.com/reel/2781078362247521/",
    "https://www.youtube.com/watch?v=8jPQjjsBbIc"
  ],
  "requiredFields": ["views", "likes", "comments"]
}
The default batch limit is 10 targets and the service hard limit is 50. Your API key may have a lower or higher configured limit within that range. Instagram images/carousels and Facebook image/photo/carousel/text posts do not have an aggregate views metric. They still succeed with views: null and metricAvailability.views: "not_applicable". Views remain required for videos and Reels. Include "shares" or "saves" only when every target can return them.

Parameters

Field Type Default Description
urlOptional string null URL of a single Instagram post/profile, TikTok video/profile, Facebook post/profile, YouTube video, or YouTube channel. Must provide one target field.
urlsOptional array of strings [] List of Instagram post/profile URLs, TikTok video/profile URLs, Facebook post/profile URLs, YouTube video URLs, or YouTube channel URLs to scrape in parallel. The default limit is 10 and the hard limit is 50; your key's configured limit is enforced.
typeOptional string null Use "channel" for YouTube channel profile data or "channelVideos" for latest uploads. Video/post metrics are inferred from the URL by default.
platformOptional string null Optional platform hint. Use "facebook", "tiktok", or "youtube" when sending a username/handle rather than a full URL.
usernameOptional string null Instagram, TikTok, or Facebook username for a profile scrape. Set platform when the username is not Instagram.
usernamesOptional array of strings [] Instagram, TikTok, or Facebook usernames for batch profile scraping. A batch uses one platform hint.
profileUrlOptional string null Instagram, TikTok, or Facebook profile URL for a single profile scrape.
profileUrlsOptional array of strings [] Instagram, TikTok, or Facebook profile URLs for batch profile scraping.
channelUrlOptional string null YouTube channel URL, @handle, legacy /user/ URL, or /channel/ ID URL.
channelUrlsOptional array of strings [] Batch YouTube channel targets.
channelIdOptional string null Raw YouTube channel ID such as UC....
handleOptional string null YouTube @handle when platform is "youtube" or type is "channel"/"channelVideos".
includeRecentPostsOptional boolean false When scraping Instagram, TikTok, or Facebook profiles, include lightweight recent public media.
recentPostsLimitOptional integer 12 Maximum recent media items to request. Instagram and Facebook accept 1-50 with cursor pagination. TikTok returns up to the fixed selection available in its creator embed.
includeRecentCommentsOptional boolean false When scraping a YouTube video, include newest public top-level comments.
recentCommentsLimitOptional integer 20 Maximum YouTube comments to request. Accepted range: 1-100.
includeRecentVideosOptional boolean true when type is "channel"; otherwise false When scraping a YouTube channel profile, include latest uploads with video metrics. Set this explicitly when the channel is inferred from channelUrl without a type field.
recentVideosLimitOptional integer 12 Maximum YouTube uploads to request. Accepted range: 1-50.
requiredFieldsOptional array of strings ["views", "likes", "comments"] Enforces validation on applicable returned metrics. Instagram image/carousel views are automatically treated as not applicable. Accepted values: "views", "likes", "comments", "shares", "saves".

Apify Compatibility

If you are migrating from existing Apify integrations, Refetch(er) accepts the common direct URL fields used by Apify-style inputs. It does not expose the full Apify actor option surface; search crawling, platform-native comment crawlers beyond optional recent YouTube comments, and related-video crawling are outside this scraper API. Instagram responses can include temporary public media source URLs, but Refetch(er) does not host permanent media downloads.

Instagram Scraper Format

Instagram Payload
{
  "directUrls": [
    "https://www.instagram.com/reel/C8xExampleAbc/"
  ],
  "resultsType": "posts",
  "resultsLimit": 1
}

YouTube Channel Format

YouTube Payload
{
  "type": "channel",
  "platform": "youtube",
  "channelUrl": "https://www.youtube.com/@TED",
  "includeRecentVideos": true
}

TikTok Scraper Format

TikTok Payload
{
  "postURLs": [
    "https://www.tiktok.com/@creator/video/7398210000000000000"
  ],
  "scrapeRelatedVideos": false
}

Success Response

A successful request returns a 200 OK status code, listing summaries and detailed records for each scraped target under the results array. Media targets return metrics, post, and author; Instagram and Facebook media targets also return media. Profile/channel targets return a type and profile/channel object.

Response JSON
{
  "success": true,
  "requestId": "aws-request-id-12345",
  "summary": {
    "total": 1,
    "succeeded": 1,
    "failed": 0,
    "errors": {}
  },
  "results": [
    {
      "url": "https://www.instagram.com/reel/C8xExampleAbc/",
      "platform": "instagram",
      "success": true,
      "metrics": {
        "views": 1284203,
        "likes": 48211,
        "comments": 1903,
        "shares": null,
        "saves": null
      },
      "metricAvailability": {
        "views": "available",
        "likes": "available",
        "comments": "available",
        "shares": "unavailable",
        "saves": "unavailable"
      },
      "post": {
        "id": "C8xExampleAbc",
        "shortcode": "C8xExampleAbc",
        "normalizedUrl": "https://www.instagram.com/reel/C8xExampleAbc/",
        "publishedAt": "2026-06-01T08:30:00.000Z",
        "caption": "Check out our new release! #refetcher #api",
        "type": "video",
        "productType": "clips",
        "hashtags": ["refetcher", "api"],
        "mentions": [],
        "location": null,
        "commentsDisabled": false,
        "isPinned": false,
        "isSponsored": false
      },
      "author": {
        "id": "123456789",
        "handle": "creators_hub",
        "name": "Creators Hub",
        "followers": 94200,
        "isVerified": false,
        "profilePicUrl": "https://..."
      },
      "media": {
        "thumbnailUrl": "https://...",
        "videoUrl": "https://...",
        "audioUrl": "https://...",
        "durationSeconds": 21.4,
        "width": 1080,
        "height": 1920,
        "playCount": 1284203,
        "viewCount": null,
        "altText": null,
        "music": {
          "id": "987654321",
          "title": "Original audio",
          "artist": "creators_hub",
          "isOriginalAudio": true
        },
        "children": []
      },
      "scrapedAt": "2026-06-05T10:15:30.000Z",
      "source": "direct"
    }
  ],
  "totalMs": 1150
}
Metric availability: Instagram, TikTok, and Facebook post results include metricAvailability with exactly five keys: views, likes, comments, shares, and saves. Each value is "available", "unavailable", or "not_applicable". Instagram, Facebook, and YouTube media responses return unavailable metrics as null; YouTube video results currently omit the availability object.

Partial Failure Response

If you query a batch of URLs, the HTTP status is still 200 OK if at least one URL is scraped successfully. The overall success flag is set to false, and failed items will contain error details explaining the failure:

Billing is per target result. In a partial batch, only successful items are charged; failed items do not reduce your balance.
Response JSON
{
  "success": false,
  "requestId": "aws-request-id-67890",
  "summary": {
    "total": 2,
    "succeeded": 1,
    "failed": 1,
    "errors": {
      "private_or_removed": 1
    }
  },
  "results": [
    {
      "url": "https://www.instagram.com/reel/VALID_URL/",
      "platform": "instagram",
      "success": true,
      "metrics": {
        "views": 4900,
        "likes": 210,
        "comments": 15,
        "shares": null,
        "saves": null
      },
      "post": {
        "id": "VALID_URL",
        "normalizedUrl": "https://www.instagram.com/reel/VALID_URL/",
        "publishedAt": null,
        "caption": null
      },
      "author": { "handle": "creator_name", "name": null, "followers": null },
      "scrapedAt": "2026-06-05T10:16:00.000Z",
      "source": "direct"
    },
    {
      "url": "https://www.instagram.com/reel/PRIVATE_URL/",
      "platform": "instagram",
      "success": false,
      "error": {
        "category": "private_or_removed",
        "message": "The post could not be accessed. It may be private, removed, or unavailable."
      },
      "scrapedAt": "2026-06-05T10:16:01.000Z"
    }
  ],
  "totalMs": 1420
}

Full Failure Response

If all requested targets fail after scraper retries and failover, the API returns a 502 Bad Gateway with per-target errors. Unexpected gateway exceptions return 500 Internal Server Error with a top-level error object.

Response JSON
{
  "success": false,
  "requestId": "aws-request-id-99999",
  "summary": {
    "total": 1,
    "succeeded": 0,
    "failed": 1,
    "errors": {
      "missing_metrics": 1
    }
  },
  "results": [
    {
      "url": "https://www.instagram.com/reel/SHORTCODE/",
      "platform": "instagram",
      "success": false,
      "error": {
        "category": "missing_metrics",
        "message": "The scraper could not read the required public metrics for this post."
      },
      "scrapedAt": "2026-06-05T10:17:00.000Z"
    }
  ],
  "totalMs": 1380
}

HTTP Status Codes

Request-level failures use a top-level error object. Scrape-level failures appear inside results.

Status Category Meaning
200 Success or partial success At least one target succeeded. Check the top-level success flag and each item in results.
400 bad_request Malformed JSON, no target, too many targets, or an unsupported target format.
401 unauthorized The API key is missing or invalid.
402 insufficient_balance The account cannot reserve enough balance for every target in the request.
405 method_not_allowed The scrape endpoint was called with a method other than POST.
500 Gateway error category An unexpected dispatcher exception prevented a normal per-target response.
502 Full scrape failure Every target failed. Inspect each result's error category.
503 billing_unavailable The service could not reserve account balance before scraping.

Error Categories

Per-target scraper failures are normalized into stable category keys:

Error Category Description
bad_url The provided URL format is invalid or cannot be parsed.
unsupported_platform The target platform is not supported by Refetch(er).
private_or_removed The target is private, was deleted, or restricted public visibility.
missing_metrics The scraper accessed the target but could not extract the required public metrics.
timeout The worker exceeded its maximum execution time.
rate_limited The platform rate limited the request. When failover is available, the dispatcher retries during the same API request.
blocked_or_challenge The scraper encountered an upstream access challenge or block.
upstream_error A scraper worker or social platform returned an unusable server response.
configuration_error A system configuration issue prevented the scrape.
unknown_error An unclassified system exception occurred.

Retry & Failover

Refetch(er) is built to maximize scrape consistency. When a scrape request arrives, our dispatcher orchestrates multi-region failover behind the scenes:

  1. The dispatcher forwards your query to the primary scraper worker.
  2. If the primary worker returns a retryable failure, the dispatcher can retry only the failed targets on a backup worker during the same request.
  3. If every route fails for a target, the API returns the final normalized error payload for that target.

This entire retry lifecycle is fully transparent to your API client. You make a single request to api.refetcher.com, and we handle the network recovery logic, returning the data inside our standard response shape.

Code Examples

Quick start templates in multiple languages. Toggle tabs to see cURL, Node.js, and Python integration templates:

curl -X POST https://api.refetcher.com/ \
  -H "X-API-Key: pc_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.instagram.com/reel/C8xExampleAbc/"
  }'
const apiKey = 'pc_live_your_key_here';
const urlToScrape = 'https://www.instagram.com/reel/C8xExampleAbc/';

fetch('https://api.refetcher.com/', {
  method: 'POST',
  headers: {
    'X-API-Key': apiKey,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: urlToScrape
  })
})
  .then(res => res.json())
  .then(data => {
    if (data.success && data.results[0].success) {
      const metrics = data.results[0].metrics;
      console.log(`Views: ${metrics.views}, Likes: ${metrics.likes}`);
    } else {
      console.error('Scrape failed:', data.results[0].error || 'Unknown error');
    }
  })
  .catch(err => console.error('Request error:', err));
import requests
import json

api_key = "pc_live_your_key_here"
url_to_scrape = "https://www.instagram.com/reel/C8xExampleAbc/"

response = requests.post(
    "https://api.refetcher.com/",
    headers={
        "X-API-Key": api_key,
        "Content-Type": "application/json"
    },
    json={
        "url": url_to_scrape
    }
)

if response.status_code == 200:
    data = response.json()
    if data.get("success") and data["results"][0]["success"]:
        metrics = data["results"][0]["metrics"]
        print(f"Views: {metrics['views']}, Likes: {metrics['likes']}")
    else:
        print("Scrape failed:", data["results"][0].get("error", "Unknown error"))
else:
    print(f"Server error: {response.status_code}", response.text)