@scrapecreators/cli 1.0.27 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,11 +3,23 @@ import { tiktokShopApis } from "./tiktok-shop-apis.js";
3
3
  import { instagramBaseApis } from "./instagram-apis.js";
4
4
  import { githubApis } from "./github-apis.js";
5
5
  import { kwaiApis } from "./kwai-apis.js";
6
+ import { telegramApis } from "./telegram-apis.js";
7
+
8
+ const withPostVariant = (endpoint) => [
9
+ endpoint,
10
+ {
11
+ ...endpoint,
12
+ method: "POST",
13
+ docsPath: `${endpoint.path}/post`,
14
+ postParamsInBody: true,
15
+ },
16
+ ];
6
17
 
7
18
  export const apis = [
8
19
  tiktokBaseApis,
9
20
  tiktokShopApis,
10
21
  instagramBaseApis,
22
+ telegramApis,
11
23
  {
12
24
  id: "youtube",
13
25
  name: "YouTube",
@@ -19,7 +31,7 @@ export const apis = [
19
31
  description:
20
32
  "Get comprehensive channel information including stats and metadata. Can pass channelId, handle, or url.",
21
33
  fullDescription:
22
- "Retrieves comprehensive YouTube channel profile data including name, avatar images, subscriber count (subscribers), total video and view counts, join date, tags, and linked social accounts like Twitter and Instagram. Accepts a channelId, handle, or full channel URL as input. Returns channel metadata such as country, email, and external store links when available.",
34
+ "Retrieves comprehensive YouTube channel profile data including name, avatar images, subscriber count (subscribers), total video and view counts, join date, tags, and linked social accounts like Twitter and Instagram. Accepts a channelId, handle, or full channel URL as input. Returns channel metadata such as country, email, and external store links when available. Contact fields come from the submitted public profile. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL.",
23
35
  path: "/v1/youtube/channel",
24
36
  sampleResponse: {
25
37
  channelId: "UCxcTeAKWJca6XyJ37_ZoKIQ",
@@ -576,10 +588,41 @@ export const apis = [
576
588
  name: "Video/Short Details",
577
589
  method: "GET",
578
590
  description:
579
- "Get complete information about a video or short.",
591
+ "Get complete information about a video or short. isPaidPromotion tells you whether YouTube marks the video as including paid promotion. Also includes YouTube's most-replayed heatmap when YouTube exposes it. most_replayed is null when the graph is not available. Age-restricted videos return 403 because we only use the public logged-out YouTube source.",
580
592
  fullDescription:
581
- "Fetches full details for a YouTube video or short, including title, description, thumbnail, view count (views), like count (likes), comment count, publish date, duration, genre, keywords, chapters, collaborators, and available caption tracks (subtitles/captions). Also returns related recommended videos in watchNextVideos and channel info for the uploader.",
593
+ "Fetches full details for a YouTube video or short, including title, description, thumbnail, view count (views), like count (likes), comment count, publish date, duration, genre, keywords, chapters, collaborators, and available caption tracks (subtitles/captions). isPaidPromotion is true when YouTube marks the video as including paid promotion and false when it does not. Also returns related recommended videos in watchNextVideos and channel info for the uploader. When YouTube exposes its public Most replayed graph, most_replayed contains normalized graph buckets in markers and YouTube's highlighted ranges in ranges. The field is null when the graph is not available. YouTube says the graph may be unavailable when the channel has active strikes, the content is potentially inappropriate, the video is too new or has too few views, or its systems deem the video ineligible for another reason. YouTube does not publish fixed age or view-count thresholds. Age-restricted videos return 403 with message: \"This video is age restricted\" because Scrape Creators only uses the public logged-out YouTube source.",
582
594
  path: "/v1/youtube/video",
595
+ errorResponseExamples: {
596
+ 403: {
597
+ success: false,
598
+ credits_remaining: 100,
599
+ error: "forbidden",
600
+ errorStatus: 403,
601
+ message: "This video is age restricted",
602
+ },
603
+ },
604
+ responseFields: [
605
+ {
606
+ path: "isPaidPromotion",
607
+ description:
608
+ "Boolean. True when YouTube marks the video as including paid promotion; otherwise false.",
609
+ },
610
+ {
611
+ path: "most_replayed",
612
+ description:
613
+ "YouTube's public Most replayed heatmap, or null when YouTube does not show the graph for this video.",
614
+ },
615
+ {
616
+ path: "most_replayed.markers",
617
+ description:
618
+ "Graph buckets with startMillis, durationMillis, and intensityScoreNormalized.",
619
+ },
620
+ {
621
+ path: "most_replayed.ranges",
622
+ description:
623
+ "YouTube-highlighted replay ranges with visibleTimeRangeStartMillis, visibleTimeRangeEndMillis, decorationTimeMillis, and the localized label.",
624
+ },
625
+ ],
583
626
  sampleResponse: {
584
627
  success: true,
585
628
  credits_remaining: 33851527,
@@ -655,6 +698,8 @@ export const apis = [
655
698
  genre: "People & Blogs",
656
699
  durationMs: 348000,
657
700
  durationFormatted: "00:05:48",
701
+ isPaidPromotion: false,
702
+ most_replayed: null,
658
703
  captionTracks: [
659
704
  {
660
705
  baseUrl:
@@ -679,7 +724,7 @@ export const apis = [
679
724
  type: "string",
680
725
  required: true,
681
726
  description: "YouTube video or short URL",
682
- placeholder: "https://www.youtube.com/watch?v=Y2Ah_DFr8cw",
727
+ placeholder: "https://youtu.be/gTCi7PaOPLY",
683
728
  },
684
729
  {
685
730
  name: "language",
@@ -693,9 +738,9 @@ export const apis = [
693
738
  {
694
739
  name: "Transcript",
695
740
  method: "GET",
696
- description: "Get transcript of a video or short",
741
+ description: "Get publicly available captions or a transcript from a YouTube video or Short",
697
742
  fullDescription:
698
- "Retrieves the captions, subtitles, or transcript of a YouTube video or short. Returns both a timestamped transcript array with start/end times and a plain-text version in transcript_only_text. Supports specifying a language code. Note: the video must be under 2 minutes for transcript extraction to work.",
743
+ "Retrieves the captions, subtitles, or transcript of a YouTube video or Short. Returns both a timestamped transcript array with start/end times and a plain-text version in transcript_only_text. Supports specifying a language code. There is no two-minute limit for YouTube. Long videos, including podcasts, work when YouTube exposes public captions. If no matching caption track is available, the transcript fields return null.",
699
744
  path: "/v1/youtube/video/transcript",
700
745
  params: [
701
746
  {
@@ -1103,7 +1148,8 @@ export const apis = [
1103
1148
  name: "query",
1104
1149
  type: "string",
1105
1150
  required: true,
1106
- description: "Search query",
1151
+ description:
1152
+ 'Search query. For stricter title matching, use YouTube\'s intitle: operator, for example intitle:"Foursquare Swarm". Quoted queries by themselves may still be broadened by YouTube when no fresh exact matches are available.',
1107
1153
  },
1108
1154
  {
1109
1155
  name: "uploadDate",
@@ -1166,6 +1212,52 @@ export const apis = [
1166
1212
  },
1167
1213
  ],
1168
1214
  },
1215
+ {
1216
+ name: "Search Typeahead",
1217
+ method: "GET",
1218
+ description:
1219
+ "Get the live autocomplete suggestions shown in YouTube's search dropdown.",
1220
+ fullDescription:
1221
+ "Returns the live search suggestions YouTube displays while a user types. Each result includes the suggested text and whether it is a normal query or a channel. When YouTube returns a channel suggestion, the response also includes its public channel ID, handle, name, and thumbnail.",
1222
+ path: "/v1/youtube/search/typeahead",
1223
+ sampleResponse: {
1224
+ success: true,
1225
+ credits_remaining: 100,
1226
+ data: {
1227
+ query: "mr beast",
1228
+ suggestions: [
1229
+ {
1230
+ text: "mrbeast",
1231
+ type: "channel",
1232
+ channel: {
1233
+ id: "UCX6OQ3DkcsbYNE6H8uQQuVA",
1234
+ handle: "@MrBeast",
1235
+ name: "MrBeast",
1236
+ thumbnailUrl:
1237
+ "https://yt3.googleusercontent.com/example=s88-c-k-c0x00ffffff-no-rj",
1238
+ },
1239
+ },
1240
+ {
1241
+ text: "mr beast give me some money",
1242
+ type: "query",
1243
+ },
1244
+ {
1245
+ text: "mrbeast gaming",
1246
+ type: "query",
1247
+ },
1248
+ ],
1249
+ },
1250
+ },
1251
+ params: [
1252
+ {
1253
+ name: "query",
1254
+ type: "string",
1255
+ required: true,
1256
+ description: "Partial or complete YouTube search query",
1257
+ placeholder: "mr beast",
1258
+ },
1259
+ ],
1260
+ },
1169
1261
  {
1170
1262
  name: "Search by Hashtag",
1171
1263
  method: "GET",
@@ -2643,7 +2735,7 @@ export const apis = [
2643
2735
  description:
2644
2736
  "Search for public LinkedIn posts by keyword. Uses Google Search to find indexed posts, then scrapes the public LinkedIn pages.",
2645
2737
  fullDescription:
2646
- "Finds public LinkedIn posts, feed updates, and Pulse articles by keyword using Google Search, then returns post details such as description, author, media, images, like count, comment count, and published date when LinkedIn exposes them publicly. Results depend on what Google has indexed, so this is best-effort and not a complete LinkedIn-native search. Use date_posted for recent posts and pass the returned cursor to fetch the next page.",
2738
+ "Finds public LinkedIn posts, feed updates, and Pulse articles by keyword using Google Search, then returns post details such as description, author, media, images, like count, comment count, and published date when LinkedIn exposes them publicly. Results depend on what Google has indexed, so this is best-effort and not a complete LinkedIn-native search. Use date_posted for recent posts and pass the returned cursor to fetch the next page. Cursors are limited to pages 1 through 11; cursor 12 or greater returns a 400 response.",
2647
2739
  path: "/v1/linkedin/search/posts",
2648
2740
  paginationField: "cursor",
2649
2741
  params: [
@@ -2666,7 +2758,7 @@ export const apis = [
2666
2758
  name: "cursor",
2667
2759
  type: "string",
2668
2760
  required: false,
2669
- description: "The cursor returned from the previous response",
2761
+ description: "The cursor returned from the previous response. The maximum cursor is 11; cursor 12 or greater returns a 400 response.",
2670
2762
  placeholder: "2",
2671
2763
  },
2672
2764
  ],
@@ -2949,7 +3041,7 @@ export const apis = [
2949
3041
  method: "GET",
2950
3042
  description: "Get public Facebook profile information",
2951
3043
  fullDescription:
2952
- "Retrieves public Facebook page details including category, address, email, phone, website, services, priceRange, rating, likeCount, and followerCount. Also returns adLibrary status with the page's ad activity and pageId. Optionally includes businessHours when get_business_hours is set to true.",
3044
+ "Retrieves public Facebook page details including category, address, email, phone, website, services, priceRange, rating, likeCount, talkingAboutCount, and followerCount. talkingAboutCount is nullable and only returned when Facebook exposes it publicly. Also returns adLibrary status with the page's ad activity and pageId. Optionally includes businessHours when get_business_hours is set to true. Contact fields come from the submitted public profile. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL. If Facebook shows an 18+ content gate, the response is still 200 with account_status: \"age-restricted\" and isPrivate: true. If Facebook shows a private content gate, the response is still 200 with account_status: \"private\" and isPrivate: true. If the page is not found, the response is 404 with accountDoesNotExist: true and isPrivate: false. Set include_gated_profile=true to also return limited public fields (such as id, name, category, likeCount, profilePicSmall, and links) when a profile is gated or age-restricted. This option only affects gated/age-restricted profiles — public profiles still return the normal full response.",
2953
3045
  path: "/v1/facebook/profile",
2954
3046
  sampleResponse: {
2955
3047
  success: true,
@@ -3072,6 +3164,7 @@ export const apis = [
3072
3164
  },
3073
3165
  ],
3074
3166
  id: "100088017857524",
3167
+ isPrivate: false,
3075
3168
  name: "Mantraindian",
3076
3169
  url: "https://www.facebook.com/mantraindianfolsom",
3077
3170
  gender: "UNKNOWN",
@@ -3127,8 +3220,56 @@ export const apis = [
3127
3220
  rating: "Not yet rated (1 review)",
3128
3221
  ratingCount: null,
3129
3222
  likeCount: 3224,
3223
+ talkingAboutCount: 418,
3130
3224
  followerCount: 3200,
3131
3225
  },
3226
+ privateResponse: {
3227
+ success: true,
3228
+ credits_remaining: 100,
3229
+ url: "https://www.facebook.com/VinnysDriveBar/",
3230
+ account_status: "private",
3231
+ isPrivate: true,
3232
+ message: "Profile is private",
3233
+ },
3234
+ ageRestrictedResponse: {
3235
+ success: true,
3236
+ credits_remaining: 100,
3237
+ url: "https://www.facebook.com/profile.php?id=999244349946937",
3238
+ account_status: "age-restricted",
3239
+ isPrivate: true,
3240
+ message: "Profile is age restricted",
3241
+ },
3242
+ gatedProfileResponse: {
3243
+ success: true,
3244
+ credits_remaining: 298984,
3245
+ id: "1581499185460975",
3246
+ name: "Galopim Livros",
3247
+ url: "https://www.facebook.com/livrosgalopim/",
3248
+ profilePicSmall:
3249
+ "https://scontent-phl2-1.xx.fbcdn.net/v/t39.30808-1/459791315_1253431156111407_5370275117423562096_n.jpg?stp=dst-jpg_p200x200_tt6&_nc_cat=110&ccb=1-7&_nc_sid=418b77&_nc_ohc=Pi3YpShkQiYQ7kNvwEYPNxb&_nc_oc=AdrjmBEW-EsVxhFGkvcfpAoKyqM65UHc9gnY6PsWlNZdu2_nIx1mc6tK9SAVVvNgUYg&_nc_zt=24&_nc_ht=scontent-phl2-1.xx&_nc_gid=aEVhmS9KLeHxBKf28_0baA&_nc_ss=7f289&oh=00_AQBmzIQzEFDGjobJ0GwIzhko6nFrshbjeDFEUKLwK_bQIg&oe=6A652D51",
3250
+ category: "Bookstore",
3251
+ links: ["https://www.instagram.com/livros_galopim/"],
3252
+ likeCount: 16576,
3253
+ pageAlias: "livrosgalopim",
3254
+ verification: "NOT_VERIFIED",
3255
+ entityType: "PERSON_PROFILE",
3256
+ igUsername: "livros_galopim",
3257
+ igFollowerCount: 657,
3258
+ igVerification: false,
3259
+ pageIsDeleted: false,
3260
+ },
3261
+ errorResponseExamples: {
3262
+ 404: {
3263
+ success: true,
3264
+ credits_remaining: 100,
3265
+ data: {
3266
+ url: "https://www.facebook.com/TatnuckDrivingRangeandIceCream/",
3267
+ accountDoesNotExist: true,
3268
+ isPrivate: false,
3269
+ message: "Account doesn't exist",
3270
+ },
3271
+ },
3272
+ },
3132
3273
  params: [
3133
3274
  {
3134
3275
  name: "url",
@@ -3144,6 +3285,14 @@ export const apis = [
3144
3285
  description: "Get the business's hours",
3145
3286
  placeholder: "true",
3146
3287
  },
3288
+ {
3289
+ name: "include_gated_profile",
3290
+ type: "string",
3291
+ required: false,
3292
+ description:
3293
+ "When true, returns limited public fields for gated or age-restricted profiles. Ignored for normal public profiles — those still return the full response.",
3294
+ placeholder: "true",
3295
+ },
3147
3296
  ],
3148
3297
  },
3149
3298
  {
@@ -4578,13 +4727,92 @@ export const apis = [
4578
4727
  "has_next_page": true
4579
4728
  },
4580
4729
  },
4730
+ {
4731
+ name: "Facebook Group Info",
4732
+ method: "GET",
4733
+ description: "Get the public About-page information for a Facebook group.",
4734
+ fullDescription:
4735
+ "Fetches the public information shown on a Facebook group's About page, including its description, privacy and visibility, member and activity counts, categories, administrators and moderators when Facebook exposes them, group history, and rules. Provide either url or group_id.",
4736
+ path: "/v1/facebook/group",
4737
+ params: [
4738
+ {
4739
+ name: "url",
4740
+ type: "string",
4741
+ description: "The Facebook group URL. Group sub-page URLs such as /about work too.",
4742
+ required: false,
4743
+ placeholder: "https://www.facebook.com/groups/366190054572553/about",
4744
+ },
4745
+ {
4746
+ name: "group_id",
4747
+ type: "string",
4748
+ description: "The numeric Facebook group ID. Provide this instead of url if you already have it.",
4749
+ required: false,
4750
+ placeholder: "366190054572553",
4751
+ },
4752
+ ],
4753
+ sampleResponse: {
4754
+ success: true,
4755
+ credits_remaining: 49999999999,
4756
+ credits_charged: 1,
4757
+ id: "366190054572553",
4758
+ url: "https://www.facebook.com/groups/366190054572553",
4759
+ name: "Python Programming",
4760
+ description: "Let's share our knowledge on Python Programming",
4761
+ privacy: {
4762
+ label: "Public",
4763
+ description: "Anyone can see who's in the group and what they post.",
4764
+ },
4765
+ visibility: {
4766
+ label: "Visible",
4767
+ description: "Anyone can find this group.",
4768
+ },
4769
+ categories: [
4770
+ { id: "242504017103922", name: "Software & tech" },
4771
+ { id: "202183377053878", name: "Engineering" },
4772
+ ],
4773
+ created_at: "2020-10-14T15:45:03.000Z",
4774
+ history_summary: "Group created on October 14, 2020. Name last changed on October 16, 2020.",
4775
+ member_count: 710386,
4776
+ member_count_text: "710,386 total members",
4777
+ administrator_count: 3,
4778
+ moderator_count: 0,
4779
+ administrators: [
4780
+ {
4781
+ id: "pfbid029b9bjf9rZfL4v9EHdxt1uxng857G4UqwpZjbCHySg88UYWu2XL5ivSixWhXBnZMnl",
4782
+ name: "Nusrat Jahan",
4783
+ url: "https://www.facebook.com/people/Nusrat-Jahan/pfbid029b9bjf9rZfL4v9EHdxt1uxng857G4UqwpZjbCHySg88UYWu2XL5ivSixWhXBnZMnl/",
4784
+ profile_picture_url: "https://scontent.xx.fbcdn.net/example.jpg",
4785
+ },
4786
+ ],
4787
+ moderators: [],
4788
+ activity: {
4789
+ posts_last_day: 16,
4790
+ posts_last_month: 512,
4791
+ new_members_text: "No new members in the last week",
4792
+ },
4793
+ rules: [
4794
+ {
4795
+ id: "366191957905696",
4796
+ title: "Be Kind and Courteous",
4797
+ description: "We're all in this together to create a welcoming environment. Let's treat everyone with respect.",
4798
+ },
4799
+ ],
4800
+ about_info: [
4801
+ {
4802
+ type: "XFBPrivacyGroupsAboutInfoItem",
4803
+ label: "Public",
4804
+ description: "Anyone can see who's in the group and what they post.",
4805
+ },
4806
+ ],
4807
+ },
4808
+ },
4581
4809
  {
4582
4810
  name: "Facebook Group Posts",
4583
4811
  method: "GET",
4584
4812
  description:
4585
4813
  "Get a public Facebook groups posts. Only can get 3 posts at a time :( (Facebook API limit)",
4586
4814
  fullDescription:
4587
- "Fetches posts from a public Facebook group, limited to 3 posts per page due to API limitations. Each post includes id, text, url, reactionCount, commentCount, publishTime, videoDetails, and topComments. Supports sorting by TOP_POSTS, RECENT_ACTIVITY, CHRONOLOGICAL, or CHRONOLOGICAL_LISTINGS, with cursor-based pagination.",
4815
+ "Fetches posts from a public Facebook group, limited to 3 posts per page due to API limitations. Each post includes id, text, url, reactionCount, commentCount, publishTime, videoDetails, and topComments. Results are chronological by default. Supports TOP_POSTS, RECENT_ACTIVITY, CHRONOLOGICAL, and CHRONOLOGICAL_LISTINGS with cursor-based pagination.",
4588
4816
  path: "/v1/facebook/group/posts",
4589
4817
  params: [
4590
4818
  {
@@ -4604,9 +4832,9 @@ export const apis = [
4604
4832
  {
4605
4833
  name: "sort_by",
4606
4834
  type: "select",
4607
- description: "How to sort the posts",
4835
+ description: "How to sort the posts. Defaults to CHRONOLOGICAL.",
4608
4836
  required: false,
4609
- placeholder: "TOP_POSTS",
4837
+ placeholder: "CHRONOLOGICAL",
4610
4838
  options: [
4611
4839
  "TOP_POSTS",
4612
4840
  "RECENT_ACTIVITY",
@@ -4842,7 +5070,7 @@ export const apis = [
4842
5070
  method: "GET",
4843
5071
  description: "Search Facebook Marketplace listings",
4844
5072
  fullDescription:
4845
- "Searches Facebook Marketplace listings by keyword and lat/lng. Supports pagination with the returned cursor. Pass the cursor value back as-is. When sort_by is creation_time_descend, Facebook can still return slightly different ordering between identical requests. For alerting/new-item workflows, scrape multiple pages and dedupe by listing id instead of relying on page 1 item order being identical every run.",
5073
+ "Searches Facebook Marketplace listings by keyword and lat/lng. Pass category_id to restrict results to the numeric Facebook Marketplace category ID returned on listing results. Supports pagination with the returned cursor. Pass the cursor value back as-is. When sort_by is creation_time_descend, Facebook can still return slightly different ordering between identical requests. For alerting/new-item workflows, scrape multiple pages and dedupe by listing id instead of relying on page 1 item order being identical every run.",
4846
5074
  path: "/v1/facebook/marketplace/search",
4847
5075
  params: [
4848
5076
  {
@@ -4852,6 +5080,13 @@ export const apis = [
4852
5080
  required: true,
4853
5081
  placeholder: "bike",
4854
5082
  },
5083
+ {
5084
+ name: "category_id",
5085
+ type: "string",
5086
+ description: "Numeric Facebook Marketplace category ID. Listing results include this value as category_id.",
5087
+ required: false,
5088
+ placeholder: "1658310421102081",
5089
+ },
4855
5090
  {
4856
5091
  name: "lat",
4857
5092
  type: "number",
@@ -5081,9 +5316,9 @@ export const apis = [
5081
5316
  {
5082
5317
  name: "Marketplace Item",
5083
5318
  method: "GET",
5084
- description: "Get a Facebook Marketplace item",
5319
+ description: "Get a Facebook Marketplace item, including rental listing_date_text and availability_text when Facebook exposes them.",
5085
5320
  fullDescription:
5086
- "Fetches details for a Facebook Marketplace item by item id or Marketplace item URL, including title, description, price, location, condition, photos, seller, and availability flags.",
5321
+ "Fetches details for a Facebook Marketplace item by item id or Marketplace item URL, including title, description, price, location, condition, photos, seller, and availability flags. Rental listings can include listing_date_text and availability_text from Facebook's Marketplace GraphQL response, for example 'Listed over a week ago' and 'Available now'. creation_time can still be null when Facebook does not expose an exact timestamp.",
5087
5322
  path: "/v1/facebook/marketplace/item",
5088
5323
  params: [
5089
5324
  {
@@ -5109,6 +5344,8 @@ export const apis = [
5109
5344
  "title": "Specialized Hardrock GSX - Super Clean Vintage Restomod - INCLUDES FREE TUNE UP",
5110
5345
  "description": "Was going to hang on to this one bc I absolutely love how it looks, but the 20” frame is just bit too large for me. Riders over 6’ would be comfy on this one. Currently in a 3x7 set up with an XT derailleur at the rear. Looks great in person. Come ride it! These never last long. \n\nCASH ONLY, PLEASE. NEAR 183/BRAKER. \n\n$380 OBO. \n\nKey points:\n\n- Maxxis DTH tires (26”)\n- Shimano Deore XT rear derailleur \n- Shimano front derailleur\n- vintage Specialized steel frame (20”)\n- vintage Sakae triple crankset (170mm)\n- vintage Sakae SR Custom handlebar\n- vintage Suntour stem shifter\n- vintage Shimano brakes\n- Specialized Avatar 143 saddle\n- new chain\n- fresh cables\n- fresh housing\n- fresh grease and lube\n- fresh lube in cable housings\n- fresh handlebar tape\n- drive train cleaned and lubed\n- derailluers adjusted and fine tuned\n- brakes adjusted and fine tuned\n- deep cleaning/detail\n- frame polished\n- frame waxed\n- INCLUDES ONE FREE TUNE UP\n",
5111
5346
  "creation_time": "2026-05-15T16:57:39.000Z",
5347
+ "listing_date_text": null,
5348
+ "availability_text": null,
5112
5349
  "location_text": "Austin, TX",
5113
5350
  "location": {
5114
5351
  "latitude": 30.401916503906,
@@ -5719,7 +5956,7 @@ export const apis = [
5719
5956
  description:
5720
5957
  "Pass the Ad ID and get back details about the ad. Be careful that if an ad has multiple versions, you're actually going to want to get the title from the 'cards' object.",
5721
5958
  fullDescription:
5722
- "Retrieves detailed information about a specific Facebook ad by its ID or URL. Returns adArchiveID, pageName, isActive, startDate, endDate, and a snapshot containing body, images, videos, display_format, link_url, and cta_text. For ads with multiple versions, the ad creative is found in the snapshot.cards array rather than snapshot.body.",
5959
+ "Retrieves detailed information about a specific Facebook ad by its ID or URL. Returns adArchiveID, pageName, isActive, startDate, endDate, and a snapshot containing body, images, videos, display_format, link_url, and cta_text. Regulated ads may also include source-dependent aaa_info using the structure shown below. Political and social issue delivery data is normalized to location_audience and age_country_gender_reach_breakdown. Political location_audience rows include reach, and political delivery values are fractional shares, so 0.08 means 8%. Regional transparency data may use absolute reach counts. For ads with multiple versions, the ad creative is found in the snapshot.cards array rather than snapshot.body.",
5723
5960
  path: "/v1/facebook/adLibrary/ad",
5724
5961
  sampleResponse: {
5725
5962
  adid: 0,
@@ -6104,13 +6341,13 @@ export const apis = [
6104
6341
  },
6105
6342
  ],
6106
6343
  },
6107
- {
6344
+ ...withPostVariant({
6108
6345
  name: "Search",
6109
6346
  method: "GET",
6110
6347
  description:
6111
- "Search the Facebook (Meta) Ad Library By Keyword. This endpoint will tap out around 1,500 results, beacuse the cursor becomes too big for a GET request. If you need more results, call this endpoint as a POST, and pass the query params in the body.",
6348
+ "Search the Facebook (Meta) Ad Library by keyword. Use GET for normal requests. If the cursor becomes too large after extensive pagination, use POST and send the same parameters in the JSON body.",
6112
6349
  fullDescription:
6113
- "Searches the Meta Ad Library by keyword and returns matching ads. Each result includes ad_archive_id, page_name, is_active, publisher_platform, and a snapshot with body text, images, videos, and cta_text. Results cap around 1,500 via GET due to cursor size limits; switch to POST method with body params for larger result sets.",
6350
+ "Searches the Meta Ad Library by keyword and returns matching ads. Supports filtering by language with a 2-letter code such as EN or ES. Each result includes ad_archive_id, page_name, is_active, publisher_platform, and a snapshot with body text, images, videos, and cta_text. Both GET and POST are supported. Use GET for normal requests. If the cursor becomes too large after extensive pagination, use POST and send the same parameters in the JSON body.",
6114
6351
  path: "/v1/facebook/adLibrary/search/ads",
6115
6352
  sampleResponse: {
6116
6353
  searchResults: [
@@ -6366,6 +6603,14 @@ export const apis = [
6366
6603
  "This can only be one country. It has to be the 2 letter code for the country. It defaults to ALL.",
6367
6604
  placeholder: "ALL",
6368
6605
  },
6606
+ {
6607
+ name: "language",
6608
+ type: "string",
6609
+ required: false,
6610
+ description:
6611
+ "Language to filter ads on. Needs to be a 2 letter language code, such as EN, ES, or FR.",
6612
+ placeholder: "EN",
6613
+ },
6369
6614
  {
6370
6615
  name: "status",
6371
6616
  type: "select",
@@ -6423,15 +6668,15 @@ export const apis = [
6423
6668
  placeholder: "false",
6424
6669
  },
6425
6670
  ],
6426
- },
6427
- {
6671
+ }),
6672
+ ...withPostVariant({
6428
6673
  name: "Company Ads",
6429
6674
  method: "GET",
6430
6675
  paginationField: "cursor",
6431
6676
  description:
6432
- "Get all the ads a company has running. If params become too large, make this a POST request and pass the params in the body.",
6677
+ "Get all the ads a company has running. Use GET for normal requests. If the cursor becomes too large after extensive pagination, use POST and send the same parameters in the JSON body.",
6433
6678
  fullDescription:
6434
- "Fetches all ads currently running for a specific company from the Meta Ad Library. Each ad includes ad_archive_id, page_name, is_active, publisher_platform, and a snapshot with body, images, videos, and display_format. Supports filtering by country, media_type, date range, and language with cursor-based pagination.",
6679
+ "Fetches all ads currently running for a specific company from the Meta Ad Library. Each ad includes ad_archive_id, page_name, is_active, publisher_platform, and a snapshot with body, images, videos, and display_format. Supports filtering by country, media_type, date range, and language with cursor-based pagination. Both GET and POST are supported. If the cursor becomes too large after extensive pagination, use POST and send the same parameters in the JSON body.",
6435
6680
  path: "/v1/facebook/adLibrary/company/ads",
6436
6681
  youtubeId: "M_wgqCtznjM",
6437
6682
  codeExample:
@@ -6757,7 +7002,7 @@ export const apis = [
6757
7002
  placeholder: "false",
6758
7003
  },
6759
7004
  ],
6760
- },
7005
+ }),
6761
7006
  {
6762
7007
  name: "Search for Companies",
6763
7008
  method: "GET",
@@ -6825,187 +7070,95 @@ export const apis = [
6825
7070
  {
6826
7071
  name: "Ad Library Search",
6827
7072
  method: "GET",
6828
- description: "Search TikTok Creative Center Top Ads by region, period, and keyword.",
7073
+ description: "Search TikTok's public Ads Library by general query or advertiser name.",
6829
7074
  fullDescription:
6830
- "Searches TikTok Creative Center Top Ads, the ad library page at ads.tiktok.com/business/creativecenter/inspiration/topads. Supports US and other 2-letter regions, period filters, sorting, keyword search, and cursor pagination. Returns TikTok's public top ad material objects, including ad title, metrics, video info, landing page, and pagination.",
7075
+ "Searches TikTok's public Ads Library using either query for a general search or advertiser_name for advertiser-specific results. Advertiser-name searches resolve the name through TikTok's advertiser typeahead first, then search the selected advertiser entity. If TikTok has no matching entity, the API falls back to TikTok's name search so inputs such as The Creator Loop still return matching ads. Provide exactly one of query or advertiser_name. Results are global, sorted by the latest shown date, support cursor pagination, and include a public TikTok Ads Library URL for each ad.",
6831
7076
  path: "/v1/tiktok/ad-library/search",
6832
7077
  params: [
6833
- {
6834
- name: "region",
6835
- type: "select",
6836
- required: false,
6837
- description: "Country code. Defaults to US.",
6838
- options: ["DZ", "AR", "AU", "AT", "AZ", "BH", "BD", "BY", "BE", "BO", "BR", "BG", "KH", "CA", "CL", "CO", "CR", "HR", "CY", "CZ", "DK", "DO", "EC", "EG", "EE", "FI", "FR", "DE", "GR", "GT", "JO", "HU", "ID", "IQ", "IE", "IL", "IT", "JP", "KZ", "KE", "KW", "LV", "LB", "MY", "MX", "MA", "NL", "NZ", "NG", "NO", "OM", "PK", "PA", "PY", "PE", "PH", "PL", "PT", "PR", "QA", "LT", "RO", "SA", "RS", "SG", "SK", "SI", "ZA", "KR", "ES", "LK", "SE", "CH", "TW", "TH", "TR", "AE", "GB", "US", "UY", "VN"],
6839
- placeholder: "US",
6840
- },
6841
- {
6842
- name: "period",
6843
- type: "select",
6844
- required: false,
6845
- description: "Time window for Top Ads.",
6846
- options: ["7", "30", "180"],
6847
- placeholder: "30",
6848
- },
6849
7078
  {
6850
7079
  name: "query",
6851
7080
  type: "string",
6852
7081
  required: false,
6853
- description: "Optional keyword to search ad titles/content.",
6854
- placeholder: "spotify",
6855
- },
6856
- {
6857
- name: "order_by",
6858
- type: "select",
6859
- required: false,
6860
- description: "Sort metric. Defaults to for_you.",
6861
- options: ["for_you", "impression", "play_2s_rate", "play_6s_rate", "cvr", "ctr", "like"],
6862
- placeholder: "for_you",
6863
- },
6864
- {
6865
- name: "industry",
6866
- type: "select",
6867
- required: false,
6868
- description: "Industry filter.",
6869
- options: ["apparel_accessories", "appliances", "apps", "baby_kids_maternity", "beauty_personal_care", "business_services", "ecommerce_non_app", "education", "financial_services", "food_beverage", "games", "health", "home_improvement", "household_products", "life_services", "news_entertainment", "pets", "sports_outdoor", "tech_electronics", "travel", "vehicle_transportation"],
6870
- placeholder: "beauty_personal_care",
6871
- },
6872
- {
6873
- name: "objective",
6874
- type: "select",
6875
- required: false,
6876
- description: "Campaign objective filter.",
6877
- options: ["app_installs", "conversions", "lead_generation", "product_sales", "reach", "traffic", "video_views"],
6878
- placeholder: "traffic",
6879
- },
6880
- {
6881
- name: "duration",
6882
- type: "select",
6883
- required: false,
6884
- description: "Video duration filter.",
6885
- options: ["under_10s", "10_20s", "20_30s", "30_40s", "40_50s", "over_50s"],
6886
- placeholder: "under_10s",
6887
- },
6888
- {
6889
- name: "likes",
6890
- type: "select",
6891
- required: false,
6892
- description: "Likes percentile filter.",
6893
- options: ["top_1_20", "top_21_40", "top_41_60", "top_61_80", "top_81_100"],
6894
- placeholder: "top_1_20",
6895
- },
6896
- {
6897
- name: "ad_format",
6898
- type: "select",
6899
- required: false,
6900
- description: "Ad format filter.",
6901
- options: ["spark_ads", "non_spark_ads"],
6902
- placeholder: "spark_ads",
7082
+ description: "General ad search. Provide either query or advertiser_name, not both.",
7083
+ placeholder: "The Creator Loop",
6903
7084
  },
6904
7085
  {
6905
- name: "ad_language",
6906
- type: "select",
7086
+ name: "advertiser_name",
7087
+ type: "string",
6907
7088
  required: false,
6908
- description: "Ad language filter.",
6909
- options: ["en", "es", "ar", "vi", "th", "de", "id", "pt", "fr", "ms", "nl", "ja", "it", "ro", "zh-Hant", "ko"],
6910
- placeholder: "en",
7089
+ description: "Advertiser name to resolve through TikTok's typeahead and search by advertiser entity. Falls back to TikTok's name search when no entity matches. Provide either advertiser_name or query, not both.",
7090
+ placeholder: "Gymshark",
6911
7091
  },
6912
7092
  {
6913
7093
  name: "cursor",
6914
- type: "number",
6915
- required: false,
6916
- description: "Page number to fetch. Use the cursor returned from the previous response, like 3 for page 3.",
6917
- placeholder: "3",
6918
- },
6919
- {
6920
- name: "limit",
6921
- type: "number",
7094
+ type: "string",
6922
7095
  required: false,
6923
- description: "Number of ads to return, max 50. Defaults to 20.",
6924
- placeholder: "20",
7096
+ description: "Opaque cursor returned from the previous response.",
7097
+ placeholder: "cursor from previous response",
6925
7098
  },
6926
7099
  ],
6927
7100
  sampleResponse: {
6928
- "success": true,
6929
- "credits_remaining": 49996315011,
6930
- "query": "",
6931
- "region": "US",
6932
- "period": 30,
6933
- "ads": [
7101
+ success: true,
7102
+ credits_remaining: 100,
7103
+ credits_charged: 1,
7104
+ source: "tiktok_public_ads_library",
7105
+ advertiser_name: "Gymshark",
7106
+ resolved_advertiser_name: "GYMSHARK LTD",
7107
+ advertiser_matches: [
6934
7108
  {
6935
- "ad_title": "I thought this was a gimmick until I tried it! A wrinkled shirt, one button, and a few minutes later... ready to wear. Tap the link in bio and see why everyone’s talking about Bellairon before it sells out. @Bellairon LLC ",
6936
- "brand_name": "",
6937
- "cost": 1,
6938
- "ctr": 0.5,
6939
- "favorite": false,
6940
- "id": "7646829987799334920",
6941
- "industry_key": "label_22108000000",
6942
- "is_search": true,
6943
- "like": 92,
6944
- "objective_key": "campaign_objective_reach",
6945
- "video_info": {
6946
- "vid": "v12044gd0000d8erq07og65h1cq991gg",
6947
- "duration": 89.767,
6948
- "cover": "https://p16-common-sign.tiktokcdn.com/tos-maliva-p-0068c799-us/oIbqBdvfEAiFpgvAOgrQHCF5R0mkDDLiEfvQDS~tplv-noop.image?dr=18692&refresh_token=2ac068a9&x-expires=1781231816&x-signature=hLbBkguntM4oX9tgdnKMMDYixAA%3D&t=9276707c&ps=14f1eb3e&shp=9e36835a&shcp=317596d8&idc=my2&VideoID=v12044gd0000d8erq07og65h1cq991gg",
6949
- "video_url": {
6950
- "540p": "https://v16m-default.tiktokcdn.com/64e64ad32f68588eee511da0114f0f2e/6a2b70c8/video/tos/maliva/tos-maliva-ve-0068c799-us/oIN2GPIRgHAUBHOeNfLk2HBSERoJeIALGC3jAE/?a=0&bti=NTU4QDM1NGA%3D&&bt=315&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=Omk6ZWQ7Nzc7OGY8PGVnOkBpajQ8Zms5cjN1OzMzZzczNEBgNDAzXl9hXjMxLzEvXjFiYSNkNm4uMmQ0bmJhLS1kMS9zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00090000",
6951
- "720p": "https://v16m-default.tiktokcdn.com/4ee4e5763b088d7d77e4a9f4fce502b6/6a2b70c8/video/tos/maliva/tos-maliva-ve-0068c799-us/ooEipQa9HbhJ4ChzASIngUPhBAdXiABIvxU2E/?a=0&bti=NTU4QDM1NGA%3D&&bt=877&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=ZTg3OTQ0NTQzZGVpNWg6NkBpajQ8Zms5cjN1OzMzZzczNEBhNC0yMDViNi8xLV9hX2AuYSNkNm4uMmQ0bmJhLS1kMS9zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00090000"
6952
- },
6953
- "width": 720,
6954
- "height": 1280
6955
- }
7109
+ name: "GYMSHARK LTD",
7110
+ ids: "7078923208527618049",
6956
7111
  },
7112
+ ],
7113
+ ads: [
6957
7114
  {
6958
- "ad_title": "True Heroes go ALL IN or nothing. See yourself at the top!",
6959
- "brand_name": "",
6960
- "cost": 0,
6961
- "ctr": 0.29,
6962
- "favorite": false,
6963
- "id": "7640089122220736530",
6964
- "industry_key": "label_25100000000",
6965
- "is_search": true,
6966
- "like": 1115,
6967
- "objective_key": "campaign_objective_conversion",
6968
- "video_info": {
6969
- "vid": "v10033g50000d8jbia7og65q0198frmg",
6970
- "duration": 105.003,
6971
- "cover": "https://p16-common-sign.tiktokcdn.com/tos-alisg-p-0051c001-sg/o8jPFEKAAIYhaBUQ6CM5tAZiBiKaaAuSi7Hzm~tplv-noop.image?dr=18692&refresh_token=3750a204&x-expires=1781231832&x-signature=RfXRGuG8N6d69HxYz2Z9XUKgdWU%3D&t=9276707c&ps=14f1eb3e&shp=9e36835a&shcp=317596d8&idc=my2&VideoID=v10033g50000d8jbia7og65q0198frmg",
6972
- "video_url": {
6973
- "1080p": "https://v16m-default.tiktokcdn.com/3dad0efc22921436631456d0eb262abc/6a2b70d8/video/tos/alisg/tos-alisg-ve-0051c001-sg/oEPIgOBQUJpQBtqKOFyFDfEMODsYfUAzNhBAIQ/?a=0&bti=NTU4QDM1NGA%3D&&bt=2989&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=OzU3NTU5ZTxlaDs0NmRoaEBpanU7NHQ5cmRlOzMzODYzNEBjMjBhYl5eXy0xMjY0L2MtYSNqYzYtMmQ0ZmdhLS1kMC1zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00088000",
6974
- "360p": "https://v16m-default.tiktokcdn.com/6c204fed990c1083f8bbd68b500b660e/6a2b70d8/video/tos/alisg/tos-alisg-ve-0051c001-sg/oUYBAIDIFOzFBQOkIN1KABPDUsJQIQgfgqyOeE/?a=0&bti=NTU4QDM1NGA%3D&&bt=551&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=aDs3ZDRmNzM5OGg3NWZmOEBpanU7NHQ5cmRlOzMzODYzNEBgMS80NTAuXjQxXmBeYmNhYSNqYzYtMmQ0ZmdhLS1kMC1zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00088000",
6975
- "480p": "https://v16m-default.tiktokcdn.com/c4a6191ed579f76eaf7b6a6611966b3b/6a2b70d8/video/tos/alisg/tos-alisg-ve-0051c001-sg/okAEI5qKBEgFlH2AAniQo8mC5AfH1KAIiAwHBA/?a=0&bti=NTU4QDM1NGA%3D&&bt=780&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=ODRmZWk6NzU1NDU4OWQ3NUBpanU7NHQ5cmRlOzMzODYzNEAwNDAwNS4xXl8xMDZiYTMyYSNqYzYtMmQ0ZmdhLS1kMC1zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00088000",
6976
- "540p": "https://v16m-default.tiktokcdn.com/07591ee6ce0fc4ca315a41f1d87ee420/6a2b70d8/video/tos/alisg/tos-alisg-ve-0051c001-sg/oI2EoHAi5CI5ANF1AKQEmIHiqfs8qZBoABlAwn/?a=0&bti=NTU4QDM1NGA%3D&&bt=1063&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=ODZmPDQ5ZjY2NTw7NzQzOkBpanU7NHQ5cmRlOzMzODYzNEAuXmFjX2NhNjAxM140MzRiYSNqYzYtMmQ0ZmdhLS1kMC1zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00088000",
6977
- "720p": "https://v16m-default.tiktokcdn.com/1404645b61626339c2e1d4c6df4ebb12/6a2b70d8/video/tos/alisg/tos-alisg-ve-0051c001-sg/okYmBiwEIK1QnHBHEAHu5oiSHAlWIAf52RAxAC/?a=0&bti=NTU4QDM1NGA%3D&&bt=1460&ft=cApXJCz7ThWHK-z9LGZmo0P&mime_type=video_mp4&rc=aDs5O2lpNTg0Mzc2NGc8N0BpanU7NHQ5cmRlOzMzODYzNEA2YGNhYmMuXjIxLWBfMV9eYSNqYzYtMmQ0ZmdhLS1kMC1zcw%3D%3D&vvpl=1&l=20260612043527C18C959B9A8CF584D398&btag=e00088000"
7115
+ id: "1871655924410641",
7116
+ url: "https://library.tiktok.com/ads/detail/?ad_id=1871655924410641",
7117
+ name: "GYMSHARK LTD",
7118
+ audit_status: "1",
7119
+ type: "2",
7120
+ first_shown_date: 1784937600000,
7121
+ last_shown_date: 1785024000000,
7122
+ videos: [
7123
+ {
7124
+ video_url: "https://library.tiktok.com/api/v1/cdn/...",
7125
+ cover_img: "https://p16-common-sign.tiktokcdn.com/...",
6978
7126
  },
6979
- "width": 720,
6980
- "height": 1280
6981
- }
7127
+ ],
7128
+ estimated_audience: "1K-10K",
7129
+ spent: "",
7130
+ impression: 0,
7131
+ show_mode: 1,
7132
+ image_urls: [],
7133
+ rejection_info: null,
7134
+ sor_audit_status: "1",
6982
7135
  },
6983
7136
  ],
6984
- "pagination": {
6985
- "has_more": true,
6986
- "page": 1,
6987
- "size": 20,
6988
- "total_count": 326
6989
- },
6990
- "total": 326,
6991
- "has_more": true,
6992
- "cursor": 2
7137
+ total: 62344,
7138
+ has_more: true,
7139
+ cursor: "opaque cursor for the next page",
6993
7140
  },
7141
+ responseFields: [
7142
+ {
7143
+ path: "ads[].url",
7144
+ description: "Public TikTok Ads Library detail page for the ad.",
7145
+ },
7146
+ ],
6994
7147
  },
6995
7148
  {
6996
7149
  name: "Ad Library Ad",
6997
7150
  method: "GET",
6998
- description: "Gets details for a TikTok Creative Center Top Ad.",
7151
+ description: "Gets details for a TikTok ad from either Creative Center Top Ads or TikTok's public Ads Library.",
6999
7152
  fullDescription:
7000
- "Fetches one TikTok Creative Center Top Ad by material/ad ID or URL. Uses the same Creative Center data behind pages like ads.tiktok.com/business/creativecenter/topads/{id}/pc/en, including title, metrics, video info, landing page, country codes, objective, industry, source, the Creative Center URL, summary/analysis, interactive time analysis graph data, and recommended-for-you ads when TikTok provides them.",
7153
+ "Fetches one TikTok ad by ID or URL. It first checks Creative Center Top Ads (ads.tiktok.com), then TikTok's public transparency Ads Library (library.tiktok.com) when the ID is not a Top Ads material. Both sources return the same response shape. Fields TikTok does not expose for a public Ads Library ad are null, empty, or false as appropriate.",
7001
7154
  path: "/v1/tiktok/ad-library/ad",
7002
7155
  params: [
7003
7156
  {
7004
7157
  name: "ad_id",
7005
7158
  type: "string",
7006
7159
  required: true,
7007
- description: "TikTok Top Ads material/ad ID, or a Top Ads detail URL.",
7008
- placeholder: "7642386438915309575",
7160
+ description: "Creative Center Top Ads material ID or URL, or a public Ads Library ad ID or library.tiktok.com detail URL.",
7161
+ placeholder: "1869335220395266",
7009
7162
  },
7010
7163
  ],
7011
7164
  sampleResponse: {
@@ -9130,119 +9283,43 @@ export const apis = [
9130
9283
  description:
9131
9284
  "Get recent posts from a subreddit with engagement metrics",
9132
9285
  fullDescription:
9133
- "Fetches posts from a subreddit with sorting and filtering options. Each post includes title, author, selftext, score, ups, upvote_ratio, num_comments, created_utc, url, permalink, subreddit_subscribers, and is_video. Supports sort (best, hot, new, top, rising), timeframe filtering, pagination via the after token, and a trim parameter for lighter responses.",
9286
+ "Fetches posts from a subreddit with sorting and filtering options. Each post includes title, author, link_flair_text when Reddit exposes it, selftext, score, ups, upvote_ratio, num_comments, created_utc, url, permalink, subreddit_subscribers, and is_video. Supports sort (best, hot, new, top, rising), timeframe filtering, pagination via the after token, and a trim parameter for lighter responses.",
9134
9287
  path: "/v1/reddit/subreddit",
9135
9288
  paginationField: "after",
9136
9289
  sampleResponse: {
9137
9290
  posts: [
9138
9291
  {
9139
- approved_at_utc: null,
9292
+ id: "1lfbo7u",
9293
+ author: "Vetro_Nodulare2",
9294
+ author_fullname: "t2_16syu27ar1",
9140
9295
  subreddit: "AskReddit",
9296
+ title: "What is a thing you love that lots of people hate?",
9297
+ link_flair_text: null,
9141
9298
  selftext: "",
9142
- author_fullname: "t2_aelahp9al",
9143
- saved: false,
9144
- mod_reason_title: null,
9145
- gilded: 0,
9146
- clicked: false,
9147
- title:
9148
- "What are your thoughts on California’s bill that would ban most law enforcement officers from wearing face masks while on duty?",
9149
- link_flair_richtext: [],
9150
- subreddit_name_prefixed: "r/AskReddit",
9151
- hidden: false,
9152
- pwls: 6,
9153
- link_flair_css_class: null,
9299
+ selftext_html: "",
9154
9300
  downs: 0,
9155
- top_awarded_type: null,
9156
- hide_score: false,
9157
- name: "t3_1ldr6b9",
9158
- quarantine: false,
9159
- link_flair_text_color: "dark",
9160
- upvote_ratio: 0.93,
9161
- author_flair_background_color: null,
9162
- subreddit_type: "public",
9163
- ups: 12606,
9301
+ name: "t3_1lfbo7u",
9302
+ upvote_ratio: 0.9,
9303
+ ups: 45,
9164
9304
  total_awards_received: 0,
9165
- media_embed: {},
9166
- author_flair_template_id: null,
9167
- is_original_content: false,
9168
- user_reports: [],
9169
- secure_media: null,
9170
- is_reddit_media_domain: false,
9171
- is_meta: false,
9172
- category: null,
9173
- secure_media_embed: {},
9174
- link_flair_text: null,
9175
- can_mod_post: false,
9176
- score: 12606,
9177
- approved_by: null,
9178
- is_created_from_ads_ui: false,
9179
- author_premium: false,
9180
- thumbnail: "",
9181
- edited: false,
9182
- author_flair_css_class: null,
9183
- author_flair_richtext: [],
9184
- gildings: {},
9185
- content_categories: null,
9186
- is_self: true,
9187
- mod_note: null,
9188
- created: 1750176516,
9189
- link_flair_type: "text",
9190
- wls: 6,
9191
- removed_by_category: null,
9192
- banned_by: null,
9193
- author_flair_type: "text",
9194
- domain: "self.AskReddit",
9195
- allow_live_comments: false,
9196
- selftext_html: null,
9197
- likes: null,
9198
- suggested_sort: null,
9199
- banned_at_utc: null,
9200
- view_count: null,
9201
- archived: false,
9202
- no_follow: false,
9203
- is_crosspostable: false,
9204
- pinned: false,
9305
+ score: 45,
9306
+ created: 1750341959,
9307
+ created_utc: 1750341959,
9308
+ created_at_iso: "2025-06-19T16:45:59.000Z",
9309
+ num_comments: 349,
9310
+ url: "https://www.reddit.com/r/AskReddit/comments/1lfbo7u/what_is_a_thing_you_love_that_lots_of_people_hate/",
9311
+ permalink:
9312
+ "/r/AskReddit/comments/1lfbo7u/what_is_a_thing_you_love_that_lots_of_people_hate/",
9313
+ subreddit_subscribers: null,
9314
+ is_video: false,
9205
9315
  over_18: false,
9206
- all_awardings: [],
9207
- awarders: [],
9208
- media_only: false,
9209
- can_gild: false,
9210
9316
  spoiler: false,
9211
- locked: false,
9212
- author_flair_text: null,
9213
- treatment_tags: [],
9214
- visited: false,
9215
- removed_by: null,
9216
- num_reports: null,
9217
- distinguished: null,
9317
+ domain: "self.AskReddit",
9218
9318
  subreddit_id: "t5_2qh1i",
9219
- author_is_blocked: false,
9220
- mod_reason_by: null,
9221
- removal_reason: null,
9222
- link_flair_background_color: "",
9223
- id: "1ldr6b9",
9224
- is_robot_indexable: true,
9225
- report_reasons: null,
9226
- author: "Ecstatic-Medium-6320",
9227
- discussion_type: null,
9228
- num_comments: 1921,
9229
- send_replies: false,
9230
- contest_mode: false,
9231
- mod_reports: [],
9232
- author_patreon_flair: false,
9233
- author_flair_text_color: null,
9234
- permalink:
9235
- "/r/AskReddit/comments/1ldr6b9/what_are_your_thoughts_on_californias_bill_that/",
9236
- stickied: false,
9237
- url: "https://www.reddit.com/r/AskReddit/comments/1ldr6b9/what_are_your_thoughts_on_californias_bill_that/",
9238
- subreddit_subscribers: 56098571,
9239
- created_utc: 1750176516,
9240
- num_crossposts: 1,
9241
- media: null,
9242
- is_video: false,
9319
+ post_hint: "text",
9243
9320
  },
9244
9321
  ],
9245
- after: "t3_1ld8q7h",
9322
+ after: "t3_1lfogps",
9246
9323
  },
9247
9324
  trimmedResponse: {
9248
9325
  posts: [
@@ -9252,6 +9329,9 @@ export const apis = [
9252
9329
  author_fullname: "t2_16syu27ar1",
9253
9330
  subreddit: "AskReddit",
9254
9331
  title: "What is a thing you love that lots of people hate?",
9332
+ link_flair_text: null,
9333
+ selftext: "",
9334
+ selftext_html: "",
9255
9335
  downs: 0,
9256
9336
  name: "t3_1lfbo7u",
9257
9337
  upvote_ratio: 0.9,
@@ -9272,6 +9352,9 @@ export const apis = [
9272
9352
  subreddit: "AskReddit",
9273
9353
  title:
9274
9354
  "What's the best physical pleasure you have ever experienced?",
9355
+ link_flair_text: null,
9356
+ selftext: "",
9357
+ selftext_html: "",
9275
9358
  downs: 0,
9276
9359
  name: "t3_1leoazg",
9277
9360
  upvote_ratio: 0.91,
@@ -9493,11 +9576,58 @@ export const apis = [
9493
9576
  },
9494
9577
  },
9495
9578
  {
9579
+ name: "Post",
9580
+ method: "GET",
9581
+ description: "Get information from a Reddit post without comments",
9582
+ fullDescription:
9583
+ "Retrieves public Reddit post details by URL without fetching or returning comments. Returns the text post body in selftext when present, plus the title, author, subreddit, score, upvote ratio, comment count, timestamps, permalink, and post flags. Accepts canonical Reddit post URLs and Reddit mobile share URLs.",
9584
+ path: "/v1/reddit/post",
9585
+ params: [
9586
+ {
9587
+ name: "url",
9588
+ type: "string",
9589
+ required: true,
9590
+ description: "Reddit post URL",
9591
+ placeholder:
9592
+ "https://www.reddit.com/r/webscraping/comments/1q6pxwn/just_started_web_scraping_is_this_a_good_start/",
9593
+ },
9594
+ ],
9595
+ sampleResponse: {
9596
+ id: "1q6pxwn",
9597
+ author: "franik33",
9598
+ author_fullname: "t2_16xbknfp71",
9599
+ subreddit: "webscraping",
9600
+ title: "Just Started Web Scraping — Is This a Good Start?",
9601
+ selftext:
9602
+ "Hi everyone, I started getting into web scraping about 3–4 days ago. I already have some solid experience with Python, and my first scraping project was a public website. I managed to collect around 7,000 records and everything worked as expected. I’m curious whether this is considered a decent start for someone new to scraping, or if it’s fairly basic stuff.Also, I’d like to hear honest opinions: is web scraping still worth investing time in today (for projects, automation, or monetization), or is it becoming a waste of time due to market saturation and restrictions? Any real-world experiences or insights would be appreciated. Thanks in advance.",
9603
+ downs: 0,
9604
+ name: "t3_1q6pxwn",
9605
+ upvote_ratio: 0.9230769230769231,
9606
+ ups: 33,
9607
+ total_awards_received: 0,
9608
+ score: 33,
9609
+ created: 1767816090,
9610
+ created_utc: 1767816090,
9611
+ created_at_iso: "2026-01-07T20:01:30.000Z",
9612
+ num_comments: 53,
9613
+ url: "https://www.reddit.com/r/webscraping/comments/1q6pxwn/just_started_web_scraping_is_this_a_good_start/",
9614
+ permalink:
9615
+ "/r/webscraping/comments/1q6pxwn/just_started_web_scraping_is_this_a_good_start/",
9616
+ subreddit_subscribers: null,
9617
+ is_video: false,
9618
+ archived: true,
9619
+ locked: false,
9620
+ over_18: false,
9621
+ spoiler: false,
9622
+ },
9623
+ },
9624
+ ...withPostVariant({
9496
9625
  name: "Post Comments",
9497
9626
  method: "GET",
9498
- description: "Get comments + post information from a Reddit post",
9627
+ description:
9628
+ "Get comments and post information from a Reddit post. Pass one opaque cursor returned by the previous response to get the next page. Cursor batching is not supported. Use POST with the same JSON-body parameters if a cursor becomes too large for a GET URL.",
9499
9629
  fullDescription:
9500
- "Retrieves comments and post details from a Reddit post by URL. Returns the post with title, author, score, ups, upvote_ratio, num_comments, and created_utc, plus a comments array where each comment includes author, body, body_html, score, created_utc, parent_id, permalink, and nested replies. Supports cursor-based pagination for loading more comments and a trim parameter for lighter responses.",
9630
+ "Retrieves comments and post details from a Reddit post by URL. Returns the post with title, author, score, ups, upvote_ratio, num_comments, and created_utc, plus a comments array where each comment includes author, body, body_html, score, created_utc, parent_id, permalink, and nested replies. Both GET and POST are supported. Use GET for normal requests. Pass one opaque cursor exactly as returned by more.cursor or replies.more.cursor to load the next page. Cursor batching and comma-separated cursor values are not supported. If an opaque cursor becomes too large after extensive pagination, use POST and send the same parameters in the JSON body. Supports cursor-based pagination for loading more comments and a trim parameter for lighter responses.",
9501
9631
  path: "/v1/reddit/post/comments",
9502
9632
  params: [
9503
9633
  {
@@ -9512,8 +9642,8 @@ export const apis = [
9512
9642
  name: "cursor",
9513
9643
  type: "string",
9514
9644
  required: false,
9515
- description: "Cursor to get more comments, or replies.",
9516
- placeholder: "ed1lvsa,ed3fnpq,ed25l2w",
9645
+ description: "One opaque cursor returned by the previous response to get more comments or replies. Do not combine multiple cursors.",
9646
+ placeholder: "opaque_cursor_returned_by_previous_response",
9517
9647
  },
9518
9648
  {
9519
9649
  name: "trim",
@@ -10671,10 +10801,10 @@ export const apis = [
10671
10801
  ],
10672
10802
  more: {
10673
10803
  has_more: true,
10674
- cursor: "ed1jhoi,ed1f3kw,ed1qgjh,ed1e4vd,ed1benx",
10804
+ cursor: "opaque_cursor_returned_by_previous_response",
10675
10805
  },
10676
10806
  },
10677
- },
10807
+ }),
10678
10808
  // {
10679
10809
  // name: "Simple Comments",
10680
10810
  // method: "GET",
@@ -10857,9 +10987,9 @@ export const apis = [
10857
10987
  {
10858
10988
  name: "Search",
10859
10989
  method: "GET",
10860
- description: "Search Reddit for posts",
10990
+ description: "Search Reddit for posts or comments",
10861
10991
  fullDescription:
10862
- "Searches across all of Reddit for posts matching a query. Each post includes title, author, selftext, subreddit, score, ups, upvote_ratio, num_comments, created_utc, url, permalink, and is_video. Supports sort (relevance, new, top, comment_count), timeframe filtering, pagination via the after token, and a trim parameter for lighter responses.",
10992
+ "Searches across all of Reddit for posts or comments matching a query. Set filter to posts (the default) or comments. Post results include title, author, selftext, subreddit, score, ups, upvote_ratio, num_comments, created_utc, url, permalink, and is_video. Comment results include the matching body, author, votes, timestamps, comment URL, parent relationship, and post/subreddit context. Comment searches support relevance, new, and top sorting. Timeframe filtering applies to post searches. Pagination uses the after token, and trim returns a lighter response.",
10863
10993
  path: "/v1/reddit/search",
10864
10994
  paginationField: "after",
10865
10995
  params: [
@@ -10869,11 +10999,20 @@ export const apis = [
10869
10999
  required: true,
10870
11000
  description: "Search query",
10871
11001
  },
11002
+ {
11003
+ name: "filter",
11004
+ type: "select",
11005
+ required: false,
11006
+ description: "Search posts or comments",
11007
+ placeholder: "posts",
11008
+ options: ["posts", "comments"],
11009
+ },
10872
11010
  {
10873
11011
  name: "sort",
10874
11012
  type: "select",
10875
11013
  required: false,
10876
- description: "Sort by",
11014
+ description:
11015
+ "Sort by. Comment search supports relevance, new, and top; comment_count is for post search only.",
10877
11016
  placeholder: "relevance",
10878
11017
  options: ["relevance", "new", "top", "comment_count"],
10879
11018
  },
@@ -10881,7 +11020,7 @@ export const apis = [
10881
11020
  name: "timeframe",
10882
11021
  type: "select",
10883
11022
  required: false,
10884
- description: "Timeframe",
11023
+ description: "Post search timeframe",
10885
11024
  placeholder: "all",
10886
11025
  options: ["all", "day", "week", "month", "year"],
10887
11026
  },
@@ -11829,7 +11968,7 @@ export const apis = [
11829
11968
  method: "GET",
11830
11969
  description: "Get Truth Social post",
11831
11970
  fullDescription:
11832
- "Fetches a single Truth Social post by URL, returning text, id, created_at, url, content, account details, media_attachments, card link previews, replies_count, reblogs_count, and favourites_count. Only posts from prominent public figures (e.g., Trump, Vance) are accessible without authentication.",
11971
+ "Fetches a single Truth Social post by URL, returning text, id, created_at, url, content, account details, media_attachments, card link previews, replies_count, reblogs_count, and favourites_count. Set download_media=true to download attached images or video and return permanent Supabase URLs. Only posts from prominent public figures (e.g., Trump, Vance) are accessible without authentication.",
11833
11972
  path: "/v1/truthsocial/post",
11834
11973
  params: [
11835
11974
  {
@@ -11840,6 +11979,15 @@ export const apis = [
11840
11979
  placeholder:
11841
11980
  "https://truthsocial.com/@realDonaldTrump/posts/114315219437063160",
11842
11981
  },
11982
+ {
11983
+ name: "download_media",
11984
+ type: "boolean",
11985
+ required: false,
11986
+ description:
11987
+ "Set to true to download the attached video/images and get back permanent Supabase URLs. Costs 10 credits if media is found, 1 credit otherwise.",
11988
+ placeholder: false,
11989
+ credits: 10,
11990
+ },
11843
11991
  ],
11844
11992
  sampleResponse: {
11845
11993
  success: true,
@@ -14645,7 +14793,7 @@ export const apis = [
14645
14793
  method: "GET",
14646
14794
  description: "Search Google",
14647
14795
  fullDescription:
14648
- "Performs a Google search and returns organic results with url, title, and description for each result. Supports an optional region parameter (2-letter country code) to get localized results from a specific country.",
14796
+ "Performs a Google search and returns organic results with url, title, and description for each result. Supports an optional region parameter (2-letter country code) to get localized results from a specific country. Pages 1 through 11 are supported; requests for page 12 or greater return a 400 response.",
14649
14797
  path: "/v1/google/search",
14650
14798
  params: [
14651
14799
  {
@@ -14675,7 +14823,7 @@ export const apis = [
14675
14823
  name: "page",
14676
14824
  type: "number",
14677
14825
  required: false,
14678
- description: "Page number to retrieve",
14826
+ description: "Page number to retrieve. Must be between 1 and 11; page 12 or greater returns a 400 response.",
14679
14827
  placeholder: "1",
14680
14828
  }
14681
14829
  ],
@@ -17662,10 +17810,206 @@ export const apis = [
17662
17810
  },
17663
17811
  ],
17664
17812
  },
17813
+ {
17814
+ id: "apple-music",
17815
+ name: "Apple Music",
17816
+ description: "Scrape Apple Music artists, songs, albums, and search results",
17817
+ endpoints: [
17818
+ {
17819
+ name: "Artist",
17820
+ method: "GET",
17821
+ description: "Get Apple Music artist",
17822
+ fullDescription:
17823
+ "Retrieves public Apple Music artist details, including artwork, editorial notes, top songs, albums, music videos, playlists, and related sections.",
17824
+ path: "/v1/apple-music/artist",
17825
+ params: [
17826
+ {
17827
+ name: "id",
17828
+ type: "string",
17829
+ required: false,
17830
+ description: "Apple Music artist id. If you'd prefer to use the URL instead, you can use the url parameter instead.",
17831
+ placeholder: "159260351",
17832
+ },
17833
+ {
17834
+ name: "url",
17835
+ type: "string",
17836
+ required: false,
17837
+ description: "Apple Music artist URL. If you'd prefer to use the id instead, you can use the id parameter instead.",
17838
+ placeholder: "https://music.apple.com/us/artist/taylor-swift/159260351",
17839
+ },
17840
+ ],
17841
+ sampleResponse: {
17842
+ success: true,
17843
+ credits_remaining: 49996588524,
17844
+ data: {
17845
+ id: "159260351",
17846
+ kind: "artist",
17847
+ name: "Taylor Swift",
17848
+ url: "https://music.apple.com/us/artist/taylor-swift/159260351",
17849
+ artwork: {
17850
+ url: "https://is1-ssl.mzstatic.com/image/thumb/AMCArtistImages221/v4/70/30/3b/example/1200x1200bb.jpg",
17851
+ width: 5998,
17852
+ height: 5998,
17853
+ },
17854
+ editorial_notes: "The country world feigned surprise when Taylor Swift formally embraced pop...",
17855
+ top_songs: [
17856
+ {
17857
+ id: "1833328840",
17858
+ kind: "song",
17859
+ title: "The Fate of Ophelia",
17860
+ artist_name: "Taylor Swift",
17861
+ url: "https://music.apple.com/us/album/the-fate-of-ophelia/1833328839?i=1833328840",
17862
+ duration_ms: 226000,
17863
+ },
17864
+ ],
17865
+ albums: [
17866
+ {
17867
+ id: "1468058165",
17868
+ kind: "album",
17869
+ title: "Lover",
17870
+ subtitle: "Taylor Swift",
17871
+ track_count: 18,
17872
+ url: "https://music.apple.com/us/album/lover/1468058165",
17873
+ },
17874
+ ],
17875
+ },
17876
+ },
17877
+ },
17878
+ {
17879
+ name: "Album",
17880
+ method: "GET",
17881
+ description: "Get Apple Music album",
17882
+ fullDescription:
17883
+ "Retrieves public Apple Music album details, including title, artist, artwork, release info, tracks, and more by the artist.",
17884
+ path: "/v1/apple-music/album",
17885
+ params: [
17886
+ {
17887
+ name: "id",
17888
+ type: "string",
17889
+ required: false,
17890
+ description: "Apple Music album id. If you'd prefer to use the URL instead, you can use the url parameter instead.",
17891
+ placeholder: "1468058165",
17892
+ },
17893
+ {
17894
+ name: "url",
17895
+ type: "string",
17896
+ required: false,
17897
+ description: "Apple Music album URL. If you'd prefer to use the id instead, you can use the id parameter instead.",
17898
+ placeholder: "https://music.apple.com/us/album/lover/1468058165",
17899
+ },
17900
+ ],
17901
+ sampleResponse: {
17902
+ success: true,
17903
+ credits_remaining: 49996588523,
17904
+ data: {
17905
+ id: "1468058165",
17906
+ kind: "album",
17907
+ title: "Lover",
17908
+ artist_name: "Taylor Swift",
17909
+ artist_url: "https://music.apple.com/us/artist/taylor-swift/159260351",
17910
+ url: "https://music.apple.com/us/album/lover/1468058165",
17911
+ track_count: 18,
17912
+ release_info: "August 23, 2019\n18 songs, 1 hour 1 minute\n℗ 2019 Taylor Swift",
17913
+ tracks: [
17914
+ {
17915
+ id: "1468058169",
17916
+ kind: "song",
17917
+ title: "I Forgot That You Existed",
17918
+ duration_ms: 170651,
17919
+ track_number: 1,
17920
+ album_id: "1468058165",
17921
+ },
17922
+ ],
17923
+ },
17924
+ },
17925
+ },
17926
+ {
17927
+ name: "Track",
17928
+ method: "GET",
17929
+ description: "Get Apple Music track",
17930
+ fullDescription:
17931
+ "Retrieves public Apple Music song details by id or URL. Album track URLs with an i= song id are supported.",
17932
+ path: "/v1/apple-music/track",
17933
+ params: [
17934
+ {
17935
+ name: "id",
17936
+ type: "string",
17937
+ required: false,
17938
+ description: "Apple Music song id. Some songs have standalone song URLs; for album tracks, use the url parameter.",
17939
+ placeholder: "1833328840",
17940
+ },
17941
+ {
17942
+ name: "url",
17943
+ type: "string",
17944
+ required: false,
17945
+ description: "Apple Music song URL or album track URL.",
17946
+ placeholder: "https://music.apple.com/us/album/lover/1468058165?i=1468058169",
17947
+ },
17948
+ ],
17949
+ sampleResponse: {
17950
+ success: true,
17951
+ credits_remaining: 49996588522,
17952
+ data: {
17953
+ id: "1468058169",
17954
+ kind: "song",
17955
+ title: "I Forgot That You Existed",
17956
+ album: null,
17957
+ url: "https://music.apple.com/us/album/i-forgot-that-you-existed/1468058165?i=1468058169",
17958
+ duration_ms: 170651,
17959
+ track_number: 1,
17960
+ artist_name: null,
17961
+ explicit: false,
17962
+ },
17963
+ },
17964
+ },
17965
+ {
17966
+ name: "Search",
17967
+ method: "GET",
17968
+ description: "Search Apple Music",
17969
+ fullDescription:
17970
+ "Searches Apple Music and returns public result sections for artists, albums, songs, playlists, stations, and music videos. Use type=song, album, artist, playlist, or all.",
17971
+ path: "/v1/apple-music/search",
17972
+ params: [
17973
+ {
17974
+ name: "query",
17975
+ type: "string",
17976
+ required: true,
17977
+ description: "Search query",
17978
+ placeholder: "taylor swift",
17979
+ },
17980
+ {
17981
+ name: "type",
17982
+ type: "string",
17983
+ required: false,
17984
+ description: "Result type to return. Use all, song, album, artist, playlist, station, music_video, or radio_episode.",
17985
+ placeholder: "song",
17986
+ },
17987
+ ],
17988
+ sampleResponse: {
17989
+ success: true,
17990
+ credits_remaining: 49996588521,
17991
+ data: {
17992
+ query: "taylor swift",
17993
+ type: "song",
17994
+ results: [
17995
+ {
17996
+ id: "1833328840",
17997
+ kind: "song",
17998
+ title: "The Fate of Ophelia",
17999
+ artist_name: "Taylor Swift",
18000
+ url: "https://music.apple.com/us/album/the-fate-of-ophelia/1833328839?i=1833328840",
18001
+ duration_ms: 226000,
18002
+ },
18003
+ ],
18004
+ },
18005
+ },
18006
+ },
18007
+ ],
18008
+ },
17665
18009
  {
17666
18010
  id: "spotify",
17667
18011
  name: "Spotify",
17668
- description: "Scrape Spotify artists, songs, and albums",
18012
+ description: "Scrape Spotify artists, songs, albums, playlists, and podcasts",
17669
18013
  endpoints: [
17670
18014
  {
17671
18015
  name: "Artist",
@@ -29686,6 +30030,89 @@ export const apis = [
29686
30030
  ]
29687
30031
  },
29688
30032
  },
30033
+ {
30034
+ name: "Playlist",
30035
+ method: "GET",
30036
+ description: "Get a Spotify playlist and its tracks",
30037
+ fullDescription:
30038
+ "Retrieves public Spotify playlist metadata and up to 50 tracks by playlist id or URL. For playlists with more tracks, pass the returned cursor into the next request until cursor is null.",
30039
+ path: "/v1/spotify/playlist",
30040
+ params: [
30041
+ {
30042
+ name: "id",
30043
+ type: "string",
30044
+ required: false,
30045
+ description: "Spotify playlist id. If you'd prefer to use the URL instead, you can use the url parameter instead.",
30046
+ placeholder: "37i9dQZF1DX4UtSsGT1Sbe",
30047
+ },
30048
+ {
30049
+ name: "url",
30050
+ type: "string",
30051
+ required: false,
30052
+ description: "Spotify playlist URL. If you'd prefer to use the id instead, you can use the id parameter instead.",
30053
+ placeholder: "https://open.spotify.com/playlist/37i9dQZF1DX4UtSsGT1Sbe",
30054
+ },
30055
+ {
30056
+ name: "cursor",
30057
+ type: "string",
30058
+ required: false,
30059
+ description: "Cursor returned by the previous response. Omit it for the first page.",
30060
+ placeholder: "50",
30061
+ },
30062
+ ],
30063
+ sampleResponse: {
30064
+ "success": true,
30065
+ "credits_remaining": 100,
30066
+ "id": "37i9dQZF1DX4UtSsGT1Sbe",
30067
+ "uri": "spotify:playlist:37i9dQZF1DX4UtSsGT1Sbe",
30068
+ "__typename": "Playlist",
30069
+ "description": "The biggest songs of the 1980s. Cover: Madonna",
30070
+ "followers": 12016730,
30071
+ "images": [
30072
+ {
30073
+ "sources": [
30074
+ {
30075
+ "height": null,
30076
+ "url": "https://i.scdn.co/image/ab67706f00000002fb8e01f2c022ab1a32e2c5a0",
30077
+ "width": null,
30078
+ },
30079
+ ],
30080
+ },
30081
+ ],
30082
+ "name": "All Out 80s",
30083
+ "ownerV2": {
30084
+ "__typename": "User",
30085
+ "name": "Spotify",
30086
+ "uri": "spotify:user:spotify",
30087
+ "username": "spotify",
30088
+ },
30089
+ "tracks": [
30090
+ {
30091
+ "id": "6r8k1vznHrzlEKYxL4dZEe",
30092
+ "uri": "spotify:track:6r8k1vznHrzlEKYxL4dZEe",
30093
+ "name": "La Isla Bonita",
30094
+ "albumOfTrack": {
30095
+ "name": "True Blue",
30096
+ "uri": "spotify:album:6fmnT17jc2Sc69q3nza1eD",
30097
+ },
30098
+ "artists": [
30099
+ {
30100
+ "profile": {
30101
+ "name": "Madonna",
30102
+ },
30103
+ "uri": "spotify:artist:6tbjWDEIzxoDsBA1FuhfPW",
30104
+ },
30105
+ ],
30106
+ "duration": {
30107
+ "totalMilliseconds": 242733,
30108
+ },
30109
+ "playcount": 785646615,
30110
+ },
30111
+ ],
30112
+ "cursor": 50,
30113
+ "totalCount": 150,
30114
+ },
30115
+ },
29689
30116
  {
29690
30117
  name: "Search",
29691
30118
  method: "GET",
@@ -32487,7 +32914,7 @@ export const apis = [
32487
32914
  {
32488
32915
  id: "snapchat",
32489
32916
  name: "Snapchat",
32490
- description: "Scrape Snapchat user profiles and thier stories",
32917
+ description: "Scrape Snapchat user profiles and their stories",
32491
32918
  endpoints: [
32492
32919
  {
32493
32920
  name: "User Profile",
@@ -32845,6 +33272,267 @@ export const apis = [
32845
33272
  },
32846
33273
  ],
32847
33274
  },
33275
+ {
33276
+ name: "Spotlight by Link",
33277
+ method: "GET",
33278
+ description: "Get Snapchat Spotlight video data by URL",
33279
+ fullDescription:
33280
+ "Fetches public data for a Snapchat Spotlight video by URL. Returns the snap id, description, creator, engagement counts, thumbnail, and content URL when Snapchat exposes them publicly.",
33281
+ path: "/v1/snapchat/spotlight",
33282
+ sampleResponse: {
33283
+ success: true,
33284
+ credits_remaining: 49997863208,
33285
+ spotlight: {
33286
+ snapId:
33287
+ "W7_EDlXWTBiXAEEniNoMPwAAYY2pvZnd0ZXVmAZ8fgG8pAZ8ff-_IAAAAAQ",
33288
+ storyId:
33289
+ "W7_EDlXWTBiXAEEniNoMPwAAYY2pvZnd0ZXVmAZ8fgG8pAZ8ff-_IAAAAAQ",
33290
+ description:
33291
+ "This is genuinely heartbreaking 💔 #relationship#funny#brainrot",
33292
+ llmTitle: null,
33293
+ llmDescription: null,
33294
+ viewCount: 251845,
33295
+ shareCount: 3807,
33296
+ commentCount: 803,
33297
+ engagementStats: {
33298
+ viewCount: 251845,
33299
+ shareCount: 3807,
33300
+ commentCount: 803,
33301
+ boostCount: 16203,
33302
+ recommendCount: 2670,
33303
+ },
33304
+ creator: {
33305
+ $case: "personCreator",
33306
+ personCreator: {
33307
+ username: "lilah4823",
33308
+ url: "https://www.snapchat.com/@lilah4823",
33309
+ name: "lilah",
33310
+ followerCount: "0",
33311
+ websiteUrl: "",
33312
+ },
33313
+ },
33314
+ durationMs: 56939,
33315
+ width: 540,
33316
+ height: 960,
33317
+ uploadDateMs: 1782915537473,
33318
+ thumbnailUrl:
33319
+ "https://cf-st.sc-cdn.net/d/TXqor3n6nwYvf2nDyAVlN.256.IRZXSOY?mo=GkcaDRoAGgAyAQRIA1AuYAFaEERmTGFyZ2VUaHVtYm5haWyiARAIgAIiCxIAKgdJUlpYU09ZogEQCJoKIgsSACoHSVJaWFNPWQ%3D%3D&uc=46",
33320
+ contentUrl:
33321
+ "https://cf-st.sc-cdn.net/d/TXqor3n6nwYvf2nDyAVlN.1034.IRZXSOY?mo=GkAaDRoAGgAyAQRIA1AuYAGiAS4IiggSHAoaIAFKEQoMY0Y9R0RFR0M5OU8uEPQDWgMQsz8iCxIAKgdJUlpYU09Z&uc=46",
33322
+ raw: {},
33323
+ },
33324
+ linkPreview: {},
33325
+ pageMetadata: {},
33326
+ videoMetadata: {},
33327
+ },
33328
+ params: [
33329
+ {
33330
+ name: "url",
33331
+ type: "string",
33332
+ required: true,
33333
+ description: "Snapchat Spotlight URL.",
33334
+ placeholder:
33335
+ "https://www.snapchat.com/@lilah4823/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYY2pvZnd0ZXVmAZ8fgG8pAZ8ff-_IAAAAAQ",
33336
+ },
33337
+ ],
33338
+ },
33339
+ {
33340
+ name: "Spotlight Comments by Link",
33341
+ method: "GET",
33342
+ description: "Get comments from a Snapchat Spotlight URL",
33343
+ fullDescription:
33344
+ "Fetches public comments from Snapchat's Spotlight comments API by URL. Returns the snap id, comments, a cursor for the next page, and hasMore. Pass the returned cursor back as the cursor param to load more comments.",
33345
+ path: "/v1/snapchat/spotlight/comments",
33346
+ sampleResponse: {
33347
+ success: true,
33348
+ credits_remaining: 49997863207,
33349
+ snapId:
33350
+ "W7_EDlXWTBiXAEEniNoMPwAAYY2pvZnd0ZXVmAZ8fgG8pAZ8ff-_IAAAAAQ",
33351
+ comments: [
33352
+ {
33353
+ replyText:
33354
+ "Guys who can't even read a paragraph are hilarious 😭 get yourself a better man",
33355
+ replyPosterDisplayName: "🎸Callie✌️",
33356
+ replyTimestampMs: "1782948905027",
33357
+ threadedReplyCount: 152,
33358
+ reactCounts: [
33359
+ {
33360
+ reactTypeId: 1,
33361
+ reactCount: 829,
33362
+ },
33363
+ ],
33364
+ },
33365
+ ],
33366
+ cursor:
33367
+ "CpMCEpACQ3NjQkNnZ0tBbkp6RWdJSUJBb05DZ0owY3hJSENLZjA1TW55TXhLbkFXb1hjMzVrWld4MFlTMW1iM0pqWlMxdVlXMDFMWEJ5YjJSeWl3RUxFaEJUY0c5MGJHbG5hSFJTWlhCc2FXVnpJanRYTjE5RlJHeFlWMVJDYVZoQlJVVnVhVTV2VFZCM1FVRlpXVEp3ZGxwdVpEQmFXRlp0UVZvNFptZEhPSEJCV2pobVppMWZTVUZCUVVGQlVRd0xFaEJUY0c5MGJHbG5hSFJTWlhCc2FXVnpJaVJpWkRKaU1XSTNNeTAzWkRCa0xUUXlOV010T0dKbU1DMDBNVFU1T0RneU1XSTRNekVNR0FBZ0FRPT0SgwISgAJDcjBCQ2cwS0FuUnpFZ2NJNi1LODhmUXpFcWNCYWhkemZtUmxiSFJoTFdadmNtTmxMVzVoYlRVdGNISnZaSEtMQVFzU0VGTndiM1JzYVdkb2RGSmxjR3hwWlhNaU8xYzNYMFZFYkZoWFZFSnBXRUZGUlc1cFRtOU5VSGRCUVZsWk1uQjJXbTVrTUZwWVZtMUJXamhtWjBjNGNFRmFPR1ptTFY5SlFVRkJRVUZSREFzU0VGTndiM1JzYVdkb2RGSmxjR3hwWlhNaUpEYzFNbVZqWWpObUxUSmhZMkV0TkdVM1l5MDVaakF6TFdZNFpUVm1ZVEZrTmpVNVlnd1lBQ0FC",
33368
+ hasMore: true,
33369
+ },
33370
+ params: [
33371
+ {
33372
+ name: "url",
33373
+ type: "string",
33374
+ required: true,
33375
+ description: "Snapchat Spotlight URL.",
33376
+ placeholder:
33377
+ "https://www.snapchat.com/@lilah4823/spotlight/W7_EDlXWTBiXAEEniNoMPwAAYY2pvZnd0ZXVmAZ8fgG8pAZ8ff-_IAAAAAQ",
33378
+ },
33379
+ {
33380
+ name: "cursor",
33381
+ type: "string",
33382
+ required: false,
33383
+ description: "Pagination cursor from the previous response.",
33384
+ placeholder:
33385
+ "CpMCEpACQ3NjQkNnZ0tBbkp6RWdJSUJBb05DZ0owY3hJSENLZjA1TW55...",
33386
+ },
33387
+ ],
33388
+ },
33389
+ ],
33390
+ },
33391
+ {
33392
+ id: "creator-tools",
33393
+ name: "Creator Tools",
33394
+ description: "Tools for finding and analyzing creator profiles",
33395
+ endpoints: [
33396
+ {
33397
+ name: "Find Social Profiles",
33398
+ method: "GET",
33399
+ description:
33400
+ "Enter a creator's handle from one social media platform and get all of their social profiles.",
33401
+ fullDescription:
33402
+ "Accepts a supported platform and creator handle, validates both using platform-specific rules, and constructs the canonical source profile URL internally. URLs are not accepted as handles. Supported platforms are Instagram, TikTok, YouTube, X/Twitter, and Facebook; X is accepted as an alias for Twitter. YouTube accepts handles and 24-character channel IDs. The endpoint returns social profiles explicitly linked from the source profile and expands recognized link-in-bio pages. It also re-scrapes up to three supported profiles explicitly linked by the source and follows up to three unique public website URLs declared by the source or those trusted profiles for one page, while preserving each declared path and query. Generic service-provider landing pages reached through parked or unconfigured branded-domain redirects are ignored so the provider's own footer links are not attributed to the creator. It also checks whether the same handle exists on the other supported platforms. All attempted same-handle URLs are returned in same_handle_candidate_urls even when they cannot be verified strongly enough for profiles. Same-handle accounts are included in profiles only when corroborated by a shared owner-controlled website or a reciprocal profile link; matching handles and display names alone are not identity proof. same_handle_match records supporting name evidence at 0.75 confidence, while shared_website and website_link use 0.9. A bounded Google search discovers alternate handles, but Google results are never returned without verification. At most two candidates per other supported platform, up to four total, are re-scraped through that platform's profile scraper. The endpoint may also follow up to two unique recognized link-in-bio URLs declared by the re-scraped Google candidates. The global two-page cap is applied after candidates whose returned handles do not match their Google URLs are rejected. Optional profile probes and page fetches make one attempt and receive the shared enrichment abort signal. A reciprocal source-profile link found there verifies the candidate, and the page's explicit cross-platform profiles can then expand the verified identity graph. Google URLs that re-scrape to the same returned platform handle are deduplicated. A different-handle candidate is accepted only when it links back to the source profile, or when its normalized display name matches and it declares the same owner-controlled public website; common multi-tenant profile and storefront hosts are excluded from shared-website identity evidence. Google discovery uses google_search_match at 0.6, exact names use display_name_match at 0.75, reciprocal links use 0.95, and cross-platform social links explicitly declared by a verified candidate use verified_profile_link at 0.95. Source-linked URLs and failures are returned in source_linked_profile_urls and failed_source_linked_profile_urls. Google candidate URLs, candidate-declared link-in-bio URLs, verified URLs, and failures are returned in google_candidate_urls, google_candidate_link_in_bio_urls, verified_google_candidate_urls, failed_google_candidate_urls, and failed_google_candidate_link_in_bio_urls. Results are deterministic and do not use AI. Mixed or unreachable enrichment results are reported through partial and the matching failure fields. If every declared link-in-bio page fails and no other enrichment finds a profile, the request returns an uncharged 503. A successful live lookup costs 10 credits.",
33403
+ path: "/v1/find-social-profiles",
33404
+ credits: 10,
33405
+ params: [
33406
+ {
33407
+ name: "platform",
33408
+ type: "select",
33409
+ required: true,
33410
+ description: "Source social platform",
33411
+ options: [
33412
+ "instagram",
33413
+ "tiktok",
33414
+ "youtube",
33415
+ "x",
33416
+ "twitter",
33417
+ "facebook",
33418
+ ],
33419
+ placeholder: "instagram",
33420
+ },
33421
+ {
33422
+ name: "handle",
33423
+ type: "string",
33424
+ required: true,
33425
+ description:
33426
+ "Creator handle without a profile URL. A leading @ is optional.",
33427
+ placeholder: "creator",
33428
+ },
33429
+ ],
33430
+ sampleResponse: {
33431
+ source: {
33432
+ platform: "instagram",
33433
+ handle: "creator",
33434
+ url: "https://www.instagram.com/creator",
33435
+ },
33436
+ profiles: [
33437
+ {
33438
+ platform: "instagram",
33439
+ handle: "creator",
33440
+ url: "https://www.instagram.com/creator",
33441
+ confidence: 1,
33442
+ evidence: [
33443
+ "source_profile",
33444
+ "link_in_bio",
33445
+ "verified_profile_link",
33446
+ ],
33447
+ },
33448
+ {
33449
+ platform: "youtube",
33450
+ handle: "creator",
33451
+ url: "https://www.youtube.com/@creator",
33452
+ confidence: 0.9,
33453
+ evidence: [
33454
+ "same_handle_match",
33455
+ "shared_website",
33456
+ "website_link",
33457
+ ],
33458
+ },
33459
+ {
33460
+ platform: "tiktok",
33461
+ handle: "creator",
33462
+ url: "https://www.tiktok.com/@creator",
33463
+ confidence: 1,
33464
+ evidence: ["link_in_bio"],
33465
+ },
33466
+ {
33467
+ platform: "facebook",
33468
+ handle: "creator-page",
33469
+ url: "https://www.facebook.com/creator-page",
33470
+ confidence: 0.95,
33471
+ evidence: [
33472
+ "google_search_match",
33473
+ "display_name_match",
33474
+ "reciprocal_profile_link",
33475
+ ],
33476
+ },
33477
+ {
33478
+ platform: "linkedin",
33479
+ handle: "creator",
33480
+ url: "https://www.linkedin.com/in/creator",
33481
+ confidence: 0.95,
33482
+ evidence: ["verified_profile_link"],
33483
+ },
33484
+ ],
33485
+ link_in_bio_urls: ["https://linktr.ee/creator"],
33486
+ expanded_website_urls: ["https://creator.com/"],
33487
+ source_linked_profile_urls: ["https://x.com/creator"],
33488
+ failed_source_linked_profile_urls: [],
33489
+ same_handle_candidate_urls: [
33490
+ "https://www.tiktok.com/@creator",
33491
+ "https://www.youtube.com/@creator",
33492
+ ],
33493
+ partial: false,
33494
+ failed_link_in_bio_urls: [],
33495
+ failed_website_urls: [],
33496
+ same_handle_search_partial: false,
33497
+ google_search_used: true,
33498
+ google_search_failed: false,
33499
+ google_candidate_urls: [
33500
+ "https://www.facebook.com/creator-page",
33501
+ ],
33502
+ google_candidate_link_in_bio_urls: [
33503
+ "https://linktr.ee/creator",
33504
+ ],
33505
+ failed_google_candidate_link_in_bio_urls: [],
33506
+ verified_google_candidate_urls: [
33507
+ "https://www.facebook.com/creator-page",
33508
+ ],
33509
+ failed_google_candidate_urls: [],
33510
+ google_verification_partial: false,
33511
+ },
33512
+ },
33513
+ {
33514
+ name: "Get Age and Gender",
33515
+ method: "GET",
33516
+ description:
33517
+ "Get age and gender of creator. This uses AI to analyze the profile image. *The profile photo must have a clear face to get an accurate result.*",
33518
+ fullDescription:
33519
+ "Uses AI to analyze a creator's profile photo and estimate their age and gender. Returns ageRange with low and high bounds, gender, and a confidence score for the gender prediction. The profile photo must contain a clear, visible face for accurate results.",
33520
+ path: "/v1/detect-age-gender",
33521
+ sampleResponse: {
33522
+ ageRange: { low: 23, high: 29 },
33523
+ gender: "Male",
33524
+ confidence: { gender: 82.51082611083984 },
33525
+ },
33526
+ params: [
33527
+ {
33528
+ name: "url",
33529
+ type: "string",
33530
+ required: true,
33531
+ description: "URL to users social profile",
33532
+ placeholder: "https://twitter.com/levelsio",
33533
+ },
33534
+ ],
33535
+ },
32848
33536
  ],
32849
33537
  },
32850
33538
  {
@@ -32857,7 +33545,7 @@ export const apis = [
32857
33545
  method: "GET",
32858
33546
  description: "Linktree page",
32859
33547
  fullDescription:
32860
- "Scrapes a Linktree page by URL, extracting the creator's profile and all their links. Returns id, username, profilePictureUrl, description, verticals, timezone, and links — an array of link objects each with id, type, title, and url. Also includes detected social accounts (instagram, tiktok, spotify, youtube, soundcloud, apple_music) and email_address.",
33548
+ "Scrapes a Linktree page by URL, extracting the creator's profile and all their links. Returns id, username, profilePictureUrl, description, verticals, timezone, and links — an array of link objects each with id, type, title, and url. Also includes detected social accounts (instagram, tiktok, spotify, youtube, soundcloud, apple_music) and email_address. Contact fields come from the submitted public Linktree page. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL.",
32861
33549
  path: "/v1/linktree",
32862
33550
  params: [
32863
33551
  {
@@ -33022,7 +33710,7 @@ export const apis = [
33022
33710
  method: "GET",
33023
33711
  description: "Pillar page",
33024
33712
  fullDescription:
33025
- "Scrapes a Pillar page by URL, extracting the creator's profile, social links, and products. Returns id, first_name, last_name, email, location, and social accounts (tiktok, spotify, twitter, youtube, facebook, linkedin, instagram, and more). Also includes links with click counts and products with title, price, description, and image.",
33713
+ "Scrapes a Pillar page by URL, extracting the creator's profile, social links, and products. Returns id, first_name, last_name, email, location, and social accounts (tiktok, spotify, twitter, youtube, facebook, linkedin, instagram, and more). Also includes links with click counts and products with title, price, description, and image. Contact fields come from the submitted public Pillar page. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL.",
33026
33714
  path: "/v1/pillar",
33027
33715
  params: [
33028
33716
  {
@@ -33102,7 +33790,7 @@ export const apis = [
33102
33790
  method: "GET",
33103
33791
  description: "Linkbio (lnk.bio) page",
33104
33792
  fullDescription:
33105
- "Scrapes a Linkbio (lnk.bio) page by URL, extracting the creator's profile and all their links. Returns handle, id, social accounts (instagram, tiktok, youtube, twitter, whatsapp), email, website, and links — an array of link objects each with url and text.",
33793
+ "Scrapes a Linkbio (lnk.bio) page by URL, extracting the creator's profile and all their links. Returns handle, id, social accounts (instagram, tiktok, youtube, twitter, whatsapp), email, website, and links — an array of link objects each with url and text. Contact fields come from the submitted public Linkbio page. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL.",
33106
33794
  path: "/v1/linkbio",
33107
33795
  params: [
33108
33796
  {
@@ -33189,7 +33877,7 @@ export const apis = [
33189
33877
  description:
33190
33878
  "Get products and other details from a creator's Amazon Shop page",
33191
33879
  fullDescription:
33192
- "Scrapes a creator's Amazon Shop page by URL, returning their storefront profile and product collections. Returns avatar, name, description, socials, and lists with title and itemCount. Also includes trendingPicks with price and discount, curations with title and postCount, and a pageToken for pagination.",
33880
+ "Scrapes a creator's Amazon Shop page by URL, returning their storefront profile and product collections. Returns avatar, name, description, socials, and lists with title and itemCount. Also includes trendingPicks with price and discount, curations with title and postCount, and a pageToken. Pass that pageToken back with the same URL to retrieve the next page; video pages return videos with an id, title, thumbnail, and attached ASINs.",
33193
33881
  path: "/v1/amazon/shop",
33194
33882
  params: [
33195
33883
  {
@@ -33199,6 +33887,14 @@ export const apis = [
33199
33887
  description: "URL to Amazon Shop page",
33200
33888
  placeholder: "https://www.amazon.com/shop/sydneydelrey",
33201
33889
  },
33890
+ {
33891
+ name: "pageToken",
33892
+ type: "string",
33893
+ required: false,
33894
+ description:
33895
+ "Page token returned by a previous response for the same shop URL",
33896
+ placeholder: "amzn1.vse.video...",
33897
+ },
33202
33898
  ],
33203
33899
  sampleResponse: {
33204
33900
  success: true,
@@ -33315,36 +34011,6 @@ export const apis = [
33315
34011
  },
33316
34012
  ],
33317
34013
  },
33318
- {
33319
- id: "age-and-gender",
33320
- name: "Age and Gender",
33321
- description: "Get age and gender of creator",
33322
- endpoints: [
33323
- {
33324
- name: "Get Age and Gender",
33325
- method: "GET",
33326
- description:
33327
- "Get age and gender of creator. This uses AI to analyze the profile image. *The profile photo must have a clear face to get an accurate result.*",
33328
- fullDescription:
33329
- "Uses AI to analyze a creator's profile photo and estimate their age and gender. Returns ageRange with low and high bounds, gender, and a confidence score for the gender prediction. The profile photo must contain a clear, visible face for accurate results.",
33330
- path: "/v1/detect-age-gender",
33331
- sampleResponse: {
33332
- ageRange: { low: 23, high: 29 },
33333
- gender: "Male",
33334
- confidence: { gender: 82.51082611083984 },
33335
- },
33336
- params: [
33337
- {
33338
- name: "url",
33339
- type: "string",
33340
- required: true,
33341
- description: "URL to users social profile",
33342
- placeholder: "https://twitter.com/levelsio",
33343
- },
33344
- ],
33345
- },
33346
- ],
33347
- },
33348
34014
  {
33349
34015
  id: "scrape-creators",
33350
34016
  name: "Scrape Creators",
@@ -33502,7 +34168,7 @@ export const apis = [
33502
34168
  method: "GET",
33503
34169
  description: "Get Linkme profile info by URL",
33504
34170
  fullDescription:
33505
- "Retrieves a Linkme profile by URL, including identity, social links, and contact details. Returns profile with id, firstName, username, bio, profileVisitCount, profileImage, verifiedAccount, and isAmbassador flag. Also includes infoLinks (email addresses) and webLinks, an array of categorized social platform links (Spotify, Instagram, YouTube, Twitter, Facebook, and more) each with linkValue and faceValue.",
34171
+ "Retrieves a Linkme profile by URL, including identity, social links, and contact details. Returns profile with id, firstName, username, bio, profileVisitCount, profileImage, verifiedAccount, and isAmbassador flag. Also includes infoLinks (email addresses) and webLinks, an array of categorized social platform links (Spotify, Instagram, YouTube, Twitter, Facebook, and more) each with linkValue and faceValue. Contact fields come from the submitted public Linkme profile. To request removal of your own information from Scrape Creators results, email support@scrapecreators.com with the profile URL.",
33506
34172
  path: "/v1/linkme",
33507
34173
  params: [
33508
34174
  {
@@ -33879,3 +34545,114 @@ export const apis = [
33879
34545
  ],
33880
34546
  },
33881
34547
  ];
34548
+
34549
+ // mirrors CACHEABLE_ROUTES in the api's responseCache.js — keep in sync.
34550
+ const CACHEABLE_PATHS = new Set([
34551
+ "/v2/instagram/media/transcript",
34552
+ "/v1/instagram/profile",
34553
+ "/v1/instagram/basic-profile",
34554
+ "/v1/instagram/post",
34555
+ "/v2/instagram/post",
34556
+ "/v3/instagram/post",
34557
+ "/v1/tiktok/profile",
34558
+ "/v2/tiktok/video",
34559
+ "/v1/facebook/adLibrary/ad",
34560
+ "/v1/facebook/adLibrary/ad/transcript",
34561
+ "/v1/facebook/post",
34562
+ "/v1/facebook/post/transcript",
34563
+ "/v1/facebook/profile",
34564
+ "/v1/youtube/channel",
34565
+ "/v1/youtube/video",
34566
+ "/v1/youtube/video/transcript",
34567
+ "/v1/google/ad",
34568
+ "/v1/find-social-profiles",
34569
+ "/v1/threads/post",
34570
+ "/v1/threads/profile",
34571
+ "/v1/twitter/profile",
34572
+ "/v1/twitter/tweet",
34573
+ "/v1/twitter/tweet/transcript",
34574
+ "/v1/pinterest/pin",
34575
+ "/v1/komi",
34576
+ "/v1/linkbio",
34577
+ "/v1/linkme",
34578
+ "/v1/linktree",
34579
+ "/v1/pillar",
34580
+ "/v1/twitch/clip",
34581
+ "/v1/twitch/profile",
34582
+ "/v1/reddit/subreddit",
34583
+ "/v1/reddit/subreddit/details",
34584
+ "/v1/reddit/ad",
34585
+ "/v1/reddit/post/transcript",
34586
+ "/v1/telegram/channel",
34587
+ "/v1/telegram/channel/posts",
34588
+ "/v1/telegram/post",
34589
+ ]);
34590
+
34591
+ const CACHE_MAX_AGE_PARAM = {
34592
+ name: "cache_max_age",
34593
+ type: "select",
34594
+ required: false,
34595
+ options: ["1d", "3d", "7d", "14d", "30d"],
34596
+ placeholder: "7d",
34597
+ };
34598
+
34599
+ // envelope fields the api adds to every response body.
34600
+ const SAMPLE_CREDITS_REMAINING = 1000000;
34601
+ const SAMPLE_CACHED_AT = "2026-07-20T14:32:11.000Z";
34602
+
34603
+ const isPlainObject = (value) =>
34604
+ value !== null && typeof value === "object" && !Array.isArray(value);
34605
+
34606
+ // prepends success/credits_remaining/credits_charged to a 200 sample.
34607
+ // values already present in the sample win; arrays are left untouched.
34608
+ const withEnvelope = (sample, creditsCharged) =>
34609
+ isPlainObject(sample)
34610
+ ? {
34611
+ success: true,
34612
+ credits_remaining: SAMPLE_CREDITS_REMAINING,
34613
+ credits_charged: creditsCharged,
34614
+ ...sample,
34615
+ }
34616
+ : sample;
34617
+
34618
+ // applied here (instead of per endpoint) so the docs, openapi spec, and
34619
+ // synced copies all pick everything up from one place.
34620
+ for (const api of apis) {
34621
+ for (const endpoint of api.endpoints) {
34622
+ const creditsCharged =
34623
+ typeof endpoint.credits === "number" ? endpoint.credits : 1;
34624
+
34625
+ endpoint.sampleResponse = withEnvelope(endpoint.sampleResponse, creditsCharged);
34626
+ for (const variant of [
34627
+ "trimmedResponse",
34628
+ "privateResponse",
34629
+ "ageRestrictedResponse",
34630
+ "gatedProfileResponse",
34631
+ ]) {
34632
+ if (endpoint[variant]) {
34633
+ endpoint[variant] = withEnvelope(endpoint[variant], creditsCharged);
34634
+ }
34635
+ }
34636
+
34637
+ if (CACHEABLE_PATHS.has(endpoint.path)) {
34638
+ const creditLabel = `${creditsCharged} ${creditsCharged === 1 ? "credit" : "credits"}`;
34639
+ endpoint.params = [
34640
+ ...(endpoint.params || []),
34641
+ {
34642
+ ...CACHE_MAX_AGE_PARAM,
34643
+ description: `If we have a response in the cache that is this many days old or newer, return the cached response (0 credits, with "cached": true and a "cached_at" timestamp). Otherwise, scrape a live result (${creditLabel}). [See the Caching page for details.](https://docs.scrapecreators.com/caching)`,
34644
+ },
34645
+ ];
34646
+ // "200 (cached)" tab: same data, free, plus cached markers at the end
34647
+ // (mirrors where the api appends them).
34648
+ if (isPlainObject(endpoint.sampleResponse)) {
34649
+ endpoint.cachedResponse = {
34650
+ ...endpoint.sampleResponse,
34651
+ credits_charged: 0,
34652
+ cached: true,
34653
+ cached_at: SAMPLE_CACHED_AT,
34654
+ };
34655
+ }
34656
+ }
34657
+ }
34658
+ }