Get an API key; the examples use
api.socialscrape.dev.Set up
You need Node 18 or newer. It has fetch built in, so there is nothing to install.
1export SOCIALSCRAPE_API_KEY=ss_live_...The script
Save as scrape.mjs and run node scrape.mjs. It calls GET /v1/tiktok/ad-library/search.
1import { writeFileSync } from "node:fs";23const BASE = "https://api.socialscrape.dev/v1/tiktok/ad-library/search";4const KEY = process.env.SOCIALSCRAPE_API_KEY;5const PARAMS = {6 query: "\"free trial\"",7 start_date: "2026-10-22",8 end_date: "2026-10-29",9};10const MAX_ITEMS = 100;1112// Follow a path through nested objects; undefined if any step is missing or null.13const pick = (obj, ...path) => path.reduce((o, k) => (o == null ? undefined : o[k]), obj);14const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));1516// One request. Failures cost nothing; retry the ones the API marks retryable.17async function get(params) {18 for (let attempt = 0; attempt < 3; attempt++) {19 const url = new URL(BASE);20 url.search = new URLSearchParams(params).toString();21 const body = await (await fetch(url, { headers: { "x-api-key": KEY } })).json();22 if (body.ok) return body;23 const { code, message, retryable } = body.error;24 if (!retryable || attempt === 2) throw new Error(`${code}: ${message}`);25 await sleep(2 ** attempt * 1000);26 }27}2829let items = [];30let params = { ...PARAMS };31let body;32while (items.length < MAX_ITEMS) {33 body = await get(params);34 items.push(...body.data.items);35 if (!body.has_more) break;36 params = { ...params, cursor: body.cursor };37}38items = items.slice(0, MAX_ITEMS);3940writeFileSync("out.json", JSON.stringify(items, null, 2));41for (const item of items.slice(0, 5)) {42 console.log(pick(item, "title"), pick(item, "id"));43}44console.log(`saved ${items.length} items to out.json, credits left: ${body.credits_remaining}`);How it works
get()sends one request and retries the failures the API marksretryable. A failed request costs nothing.- The loop follows
cursoruntilhas_moreis false or 100 items are collected. Each page costs its own price. pick()reads nested fields and givesundefinedinstead of crashing when the platform returnednull.- Items go to
out.json, and the first five are printed.
What you get back
These fields come from a recorded sample. The full field list is on the endpoint page.
SampleFields in the script
1{2 "title": "This year, sleep deeper, train smarter, and live better for longer. Start your WHOOP free trial.",3 "id": "1880321679899026"4}The short version
Without paging, saving or retries, the request is this.
1const url = new URL("https://api.socialscrape.dev/v1/tiktok/ad-library/search");2url.search = new URLSearchParams({3 query: "\"free trial\"",4 start_date: "2026-10-22",5 end_date: "2026-10-29",6}).toString();7const res = await fetch(url, {8 headers: { "x-api-key": process.env.SOCIALSCRAPE_API_KEY },9});10const body = await res.json();1112if (body.ok) {13 console.log(body.data);14} else {15 console.error(body.error.code, body.error.message);16}With the SDK
The JavaScript client does the retries and the paging for you: see the SDKs.
1import { SocialScrape } from "socialscrape";23const client = new SocialScrape(); // reads SOCIALSCRAPE_API_KEY45for await (const item of client.paginate(client.tiktok.adLibrarySearch, { query: "\"free trial\"", start_date: "2026-10-22", end_date: "2026-10-29" }, { maxItems: 100 })) {6 console.log(item.title);7}What it costs
1 credit. A failed request costs nothing. Add max_age_days to reuse a cached result for 0 credits. Results are kept 30 days.
Next
- The same request in nine languages.
- TikTok Ad Library search API: sample response and every parameter.
- The Python version.
- All TikTok endpoints.