# Brand mention monitoring (/docs/recipes/brand-mention-monitoring) Run a daily brand-mention sweep across 14 social platforms with one API call, dedupe against yesterday's results, and alert on what's new. 20 credits per sweep. You will build the core loop of a social listening tool: every day (or hour), find every new post mentioning your brand across the social web, skip what you have already seen, and push the rest to Slack, email, or a dashboard. **Cost per run:** 20 credits flat per sweep, whatever the fan-out returns. A daily sweep is 600 credits per month, hourly is 14,400. ## How do you track brand mentions with an API? Call `GET /v1/search/everywhere` with your brand name and a short `lookback_days` window. The endpoint fans out across Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, GitHub, Threads, Pinterest, LinkedIn, Rumble, Perplexity, and Tavily in parallel, returning every recent mention ranked and clustered, with each post's top comments attached, for a flat 20 credits. You supply the dedupe layer, because "new since last run" is your state, not ours. ## What you need | Endpoint | What it does | Cost | | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | -------- | | `GET /v1/search/everywhere` | Universal social search. Params: `query` (required), `lookback_days`, `from_date` / `to_date`, `sources`, `exclude`, `relevance` | 20cr | | `GET /v1/tiktok/search`, `/v1/reddit/search`, `/v1/youtube/search` | Optional per-platform deep dives on the platforms that matter most. Param: `query` | 1cr each | ## The code ```typescript title="TypeScript" // recipe-brand-mentions.ts // Daily brand-mention sweep with dedupe. Persist `seen` anywhere durable // (a JSON file, Redis, a DB table) between runs. // Run with: SOCIALCRAWL_KEY=sc_... npx tsx recipe-brand-mentions.ts import { readFile, writeFile } from "node:fs/promises"; const KEY = process.env.SOCIALCRAWL_KEY; if (!KEY) throw new Error("Set SOCIALCRAWL_KEY"); const BRAND = "socialcrawl"; const SEEN_FILE = "./seen-mentions.json"; // ── Step 1: One universal search call, sync mode ────────────────────────── const url = new URL("https://www.socialcrawl.dev/v1/search/everywhere"); url.searchParams.set("query", BRAND); url.searchParams.set("lookback_days", "1"); // only what's new since yesterday url.searchParams.set("relevance", "filter"); // drop results not about the brand, free const res = await fetch(url, { headers: { "x-api-key": KEY, accept: "application/json" }, }); const json = (await res.json()) as { success: boolean; data: { items: Array<{ source: string; url: string; title: string; snippet: string; final_score: number; source_items: Array<{ metadata?: { top_comments?: Array<{ text: string; score: number }> }; }>; }>; }; }; if (!json.success) throw new Error("sweep failed"); // ── Step 2: Dedupe against previous runs by canonical post URL ──────────── const seen = new Set( await readFile(SEEN_FILE, "utf8") .then((raw) => JSON.parse(raw) as string[]) .catch(() => []), ); const fresh = json.data.items.filter((item) => !seen.has(item.url)); for (const item of fresh) seen.add(item.url); await writeFile(SEEN_FILE, JSON.stringify([...seen], null, 2)); // ── Step 3: Alert on what's new ──────────────────────────────────────────── console.log(`${fresh.length} new mentions of "${BRAND}" today`); for (const item of fresh) { const top = item.source_items[0]?.metadata?.top_comments?.[0]; console.log(`\n[${item.source}] ${item.title}`); console.log(` ${item.url}`); if (top) console.log(` top comment: "${top.text.slice(0, 140)}…"`); // Replace console.log with a Slack webhook / email / DB insert. } ``` Run it on a daily cron. The `lookback_days=1` window plus the URL dedupe set guarantees each mention surfaces exactly once. `relevance=filter` drops the results the ranking step judged off-topic (unrelated, or about a different thing that shares the brand's name) and lists their ids in `data.relevance.dropped_ids`. It is included in the flat 20 credits, and it matters most when the brand is also an ordinary word. A result that could not be judged is never dropped. Source names are not platform names, and a wrong one fails silently. The X source is called **`twitter-ai-search`**, not `twitter`. Unknown names in `sources` / `exclude` are filtered out with no error, so `sources=reddit,twitter,tiktok` succeeds, quietly drops X coverage, and still charges the full flat 20 credits. Check `data.sources_called` in the response to confirm you got the fan-out you asked for. The [full source table](/docs/search/everywhere.md#sources) lists all 17 canonical names. ## What you get back ```jsonc title="JSON" // json.data.items, each mention, ranked and comment-enriched: [ { "source": "reddit", "title": "Anyone tried SocialCrawl for TikTok data?", "url": "https://reddit.com/r/webscraping/comments/...", "snippet": "Looking for an alternative to running my own scrapers...", "final_score": 0.88, // <-- RRF + rerank fused "source_items": [ { "metadata": { "top_comments": [ { "text": "Been using it for 3 months, the unified schema is the killer feature.", "score": 41, }, ], }, }, ], }, // ... mentions from twitter, youtube, tiktok, hackernews, ... ] ``` ## What to change - **`BRAND`**: swap in a competitor, a product name, or a person. The same loop tracks any of them. - **`lookback_days`**: match it to your cron interval so windows do not overlap or leave gaps. - **Narrow the fan-out**: add `url.searchParams.set("sources", "reddit,twitter-ai-search,tiktok")`, or `exclude` the noisy ones. The price stays 20 credits either way. - **Judge each mention against the brand**: the per-platform searches take `label=mention&brand=`, for example `/v1/reddit/search?query=socialcrawl&label=mention&brand=SocialCrawl`. Each post gains a `mention` label: is it about the brand rather than something that shares its name, how it feels about the brand on five levels, which aspect it talks about, and whether the author bought or used it. `mention` is metered: 1 credit per started 25 newly judged posts, on top of the 1-credit page. See [Labels](/docs/labels.md#what-stays-opt-in-and-metered). - **Swap the sink**: replace the `console.log` in Step 3 with a Slack webhook, an email, or a database insert. - **Persist `seen` properly**: the JSON file is fine for one machine. Move it to Redis or a table before you run this on more than one worker. ## Related - [Sentiment analysis](/docs/recipes/sentiment-analysis.md): Label each fresh mention positive, negative, or neutral before alerting. - [Social listening pulse-check](/docs/recipes/social-listening-pulse-check.md): The streaming (SSE) variant of this same call. - [Competitor tracking](/docs/recipes/competitor-tracking.md): Track the accounts themselves, not just what people say about them. - [Monitor webhooks](/docs/webhooks.md): Run this on a managed schedule with signed, retried delivery. - [Universal social search](/platforms/search/everywhere): Full parameter reference for the endpoint this recipe calls. - [Quickstart](/docs/quickstart.md): New here? Get a key and make your first request.