Universal social search across 15 platforms
Fans out a single query across Reddit, X (ai-search), YouTube, TikTok, Instagram, Hacker News, Polymarket, GitHub, Threads, Pinterest, LinkedIn, Rumble, Perplexity, and Tavily in parallel (17 sources, since TikTok, Instagram and YouTube each add a hashtag lane). A query that contains Hangul also runs naver: Naver blog, cafe and KnowledgeiN search in one lane, where Korean posts actually are; on other queries it runs only when you pass sources=naver. Naver rows carry the corpus in metadata.corpus; blog rows have the posting day, KnowledgeiN rows an estimated date (date_confidence: low) and cafe rows no date. Returns ranked + clustered results, enriched with real-people comments on the six lanes that have a comments surface: Reddit upvoted comments, Hacker News thread replies, YouTube, TikTok and Instagram top-liked comments, and GitHub issue discussion. The other lanes (X, Threads, Pinterest, LinkedIn, Rumble, Polymarket, Perplexity, Tavily) have no comments concept and their rows carry none, so read top_comments as absent rather than empty there. The comments per result live at data.items[i].source_items[0].metadata.top_comments[], sorted by score descending, each { score, excerpt, truncated, author, url, date }. Bodies are clipped to 300 characters on a word boundary; a clipped one ends with an ellipsis and sets truncated: true, so a short comment is never mistaken for a cut one. GitHub bot accounts are excluded from this block, so a CI deploy-preview or build-status comment never spends the budget. Attribution varies by lane, honestly: the Reddit, Hacker News, YouTube, TikTok, Instagram and GitHub lanes are post-shaped and carry an author and a date, while the Perplexity and Tavily lanes index the open web and have no author to give, so their rows are labelled with the source host. Expect 28 to 30 seconds for a full fan-out; allow a 60s client timeout. On the JSON path the X lane (twitter-ai-search, an AI-written synthesis of X posts that takes 15 to 45 seconds) runs only when it is the only source requested (sources=twitter-ai-search, or x / twitter); beside other sources it is not run, so it appears in sources_failed with a reason saying so and is left out of sources_called and coverage. Use the streaming path for the X synthesis alongside other sources, or /v1/twitter/search/tweets for X posts. Each row's date_confidence says how far to trust published_at: YouTube rows dated from a "3 years ago" or "2 months ago" label are low. Supports streaming via Accept: text/event-stream (emits comments_enriched chunks per candidate as enrichment lands, before the terminal done) and sync via Accept: application/json. Flat 20 credits per call regardless of enrichment.
Request
- Base URL: https://www.socialcrawl.dev/v1
- URL: https://www.socialcrawl.dev/v1/search/everywhere
- Auth: API key in header x-api-key
Query parameters
Search query (1-512 chars)
Recency window in days (minimum 1, default 30); mutually exclusive with from_date/to_date. This is a ranking signal, not a hard filter: it sets the freshness curve and is forwarded to the sources whose upstream supports date bounds, so a much older item can still rank when nothing recent matches. Windows over 90 days degrade coverage on the sources with no upstream date filtering and emit a warning rather than an error. Check each row's date_confidence before filtering on its date: low means the date is an estimate (a rounded YouTube label, a KnowledgeiN estimate).
ISO YYYY-MM-DD lower bound; mutually exclusive with lookback_days.
ISO YYYY-MM-DD upper bound; defaults to today when from_date is set alone.
Optional CSV allowlist of sources (mutually exclusive with exclude). Valid names: reddit, twitter-ai-search, youtube, tiktok, instagram, hackernews, polymarket, github, threads, pinterest, perplexity, tavily, linkedin, rumble, tiktok-hashtag, instagram-hashtag, youtube-hashtag, naver. naver (Naver blog, cafe and KnowledgeiN) is in the default set only when the query contains Hangul. Platform shorthands expand to their full group: twitter/x → twitter-ai-search; youtube, instagram, tiktok also include their -hashtag lane. Unknown names return a 400.
Optional CSV blocklist of sources (mutually exclusive with sources). Same valid names and platform shorthands as sources: excluding youtube/instagram/tiktok also excludes the platform's -hashtag lane. Unknown names return a 400.
Fetch spoken-word transcripts for the top 3 video results (default false), so a video whose title never mentions your query but whose narration does can still be found and quoted. Applies to the YouTube, Rumble, TikTok and Instagram lanes; YouTube and Rumble transcripts carry timestamped segments, TikTok and Instagram are plain text. Transcripts land on data.items[i].source_items[0].metadata.transcript and stream as transcript_enriched chunks. Included in the flat 20 credits.
Optional. filter drops the ranked results our relevance judgment already scored as off-topic for your query (unrelated, or clearly about a different thing that shares its words) and lists their ids in data.relevance.dropped_ids, with counts. A result that could not be judged is never dropped; when none could be judged nothing is dropped and data._warnings says relevance_unavailable. items_by_source is not filtered. Omit it to keep every ranked result, ordered as before; each result still carries computed.relevance by default (see judgments). Included in the flat 20 credits.
Optional CSV of extra blocks. stance is now on by default and accepted for compatibility: data.items[i].computed.stance ({ label: positive, negative, neutral, no_opinion or null when unsure, probabilities, confidence }) says what each post, with any replies shown, says about your query, and data.stance_split counts it per platform and overall with the ids behind every count. Posts judged under the confidence floor count as uncertain, never as a stance. If the judgment is unavailable the search still returns, stance is null and data._warnings says stance_unavailable (or stance_skipped when judging was skipped). Included in the flat 20 credits.
Optional. on (default) or off. On, every result also carries data.items[i].computed.stance (see include) and data.items[i].computed.relevance ({ score 0 to 1, on_topic, entity }), with data.relevance counting the off-topic results and listing their ids. Nothing is dropped or reordered and the price does not change. off returns the response without these blocks.
Optional brand. data.switch_receipts lists results where the author says they personally left that brand, with the verbatim text, the reason, where they went, and the link. There is no percentage. Rows that are not a switch stay in items. Included in the flat 20 credits.
Headers
Send no-cache to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the no-cache directive triggers this. See the Response Schema guide for details.
Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives 409 IDEMPOTENCY_IN_PROGRESS with a Retry-After of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: credits_used becomes 0, idempotent_replay becomes true, and credits_remaining is refreshed to the current balance. A known current balance appears in both the body and X-Credits-Remaining header; no balance row resolves to 0. On a transient lookup failure, body credits_remaining is null and X-Credits-Remaining is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use Accept: application/json when sending this header. The unsupported key-plus-SSE combination is rejected before billing.
Response
Successful response
Example response
{
"success": true,
"platform": "search",
"endpoint": "/v1/search/everywhere",
"credits_used": 1,
"credits_remaining": 4999,
"request_id": "req-abc123",
"idempotent_replay": true,
"meta": {
"hint": {
"code": "search_multi",
"message": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged.",
"method": "GET",
"path": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
}
}
}Changes
No recorded changes to this operation across all 1 revision of this API.