---
title: "One query, each platform's own search results, in one call at each platform's own price."
method: GET
path: "/search/multi"
tags: ["search"]
---

# One query, each platform's own search results, in one call at each platform's own price.

`GET /search/multi`

## Request

- Base URL: `https://www.socialcrawl.dev/v1`
- URL: `https://www.socialcrawl.dev/v1/search/multi`
- Auth: API key in header `x-api-key`

Runs the same query on several platforms' native search endpoints at once and returns their rows together: TikTok (`/v1/tiktok/search`), Instagram reels (`/v1/instagram/search/reels`), YouTube (`/v1/youtube/search`), Reddit (`/v1/reddit/search`), Threads (`/v1/threads/search`), X (`/v1/twitter/search/tweets`), Facebook (`/v1/facebook/search/posts`), LinkedIn (`/v1/linkedin/search/posts`) and Telegram (`/v1/telegram/search`, whose rows are channels under `author`, not posts, deduped by handle). `platforms` picks them (default tiktok,instagram,youtube,reddit,threads). Each platform is searched by calling that platform's own endpoint, so every row in `data.items` is exactly the row a direct call returns, with its `post` and `computed` blocks, plus `platform`, and each platform is billed exactly as a direct call would be. Rows are grouped by platform in the order you asked for them, in each platform's own order, and a post URL that already appeared is dropped (`data.duplicates_removed`). Each platform's own filters pass through with a platform prefix, for example `tiktok.region=US` or `reddit.sort=new`. `since` and `until` keep only posts published inside a date window on every platform; a row without a date is kept. Each platform is also sent the native date filter that fits the window, so its one page holds the right posts: Threads and Facebook `start_date` and `end_date`, the X `since:` and `until:` operators, and on TikTok, YouTube and Reddit the narrowest rolling bucket (`date_posted`, `uploadDate`, `timeframe`) that still reaches `since`, for example `tiktok.date_posted=last-3-months` for a date 44 days back. A filter you send yourself is never changed, and `data._warnings` says `window_unreachable` when it cannot reach `since`. On Instagram and LinkedIn the bucket is only suggested, because their date filter changes what the platform returns (Instagram reels lose their view counts). `data.window` reports what each platform was sent (`native`, `origin`, `reaches_since`, `suggested`) and how many of its rows fell outside the window. A newest-first page that ends before `since` (`reddit.sort=new`, X) says `since_not_reached` and names the cursor to continue with. `data.sources` reports each platform: `status` (`ok`, `empty` or `failed`), the rows it returned and kept, the credits it cost, its own `request_id` and `warnings` (for example the note that a Threads query was expanded), and its `next_cursor`, which you send as `cursor` to that platform's own endpoint (listed in `endpoint`) for its next page. This endpoint does not page itself. Native search matches your words literally; `expand=context` also runs up to three short searches written from your query and `relevant_to` (how sellers and posters phrase the same thing), merges them with your query's rows, tags each row with `matched_query`, and reports the searches in `data.expansion`. Pair it with `relevance=filter` and `relevant_to` to keep only the rows about what you mean. `instagram.include=creator` adds each Instagram creator's declared country, followers and public email, billed by the reel search as on a direct call. For a planned, reranked and clustered answer across more sources, use /v1/search/everywhere.

## Query parameters

- `query` string, required
- `platforms` string
- `since` string
- `until` string
- `expand` 'context'
- `expand_queries` integer
- `tiktok.date_posted` 'yesterday' | 'this-week' | 'this-month' | 'last-3-months' | 'last-6-months' | 'all-time'
- `tiktok.sort_by` 'relevance' | 'most-liked' | 'date-posted'
- `tiktok.region` string
- `instagram.date_posted` 'last-week' | 'last-month' | 'last-year'
- `instagram.include` 'creator'
- `youtube.uploadDate` 'today' | 'this_week' | 'this_month' | 'this_year'
- `youtube.sortBy` 'relevance' | 'popular'
- `youtube.type` 'videos' | 'shorts'
- `youtube.duration` 'under_3_min' | 'between_3_and_20_min' | 'over_20_min'
- `youtube.region` string
- `reddit.sort` 'relevance' | 'new' | 'top' | 'comment_count'
- `reddit.timeframe` 'all' | 'day' | 'week' | 'month' | 'year'
- `threads.start_date` string
- `threads.end_date` string
- `twitter.sort` 'latest' | 'top'
- `facebook.start_date` string
- `facebook.end_date` string
- `facebook.recent_posts` boolean
- `facebook.location_uid` string
- `linkedin.sort_by` 'date_posted' | 'relevance'
- `linkedin.date_posted` 'past_24h' | 'past_week' | 'past_month'
- `linkedin.content_type` 'videos' | 'photos' | 'jobs' | 'live_videos' | 'documents' | 'collaborative_articles'
- `telegram.date_posted` 'last-hour' | 'last-day' | 'last-week' | 'last-month' | 'last-year'
- `telegram.region` string
- `relevance` 'score' | 'filter'
- `relevance_threshold` string
- `relevant_to` string
- `judgments` 'on' | 'off'
- `dry_run` '1'
- `fit` 'goal'
- `goal` string
- `fit_tokens` integer
- `label` string
- `exclude` string
- `brand` string
- `brand_description` string
- `offer` string
- `label_evidence` '1'

## Headers

- `Cache-Control` string
- `Idempotency-Key` string

## Response `200`

Successful response

- object
  - `success` boolean, required: Whether the request succeeded
  - `platform` string, required: Platform name
  - `endpoint` string, required: API endpoint path
  - `data` object, required: Platform-specific response data
    - `metrics` object: Key performance metrics
      - `total_views` integer: Total view count
      - `total_likes` integer: Total like count
      - `total_comments` integer: Total comment count
      - `engagement_rate` number: Computed engagement rate (0-1)
    - `period` string, nullable: Time period for the analytics data
    - `breakdown` object[], nullable: Per-item or per-period breakdown
    - `_warnings` string[]: Non-fatal notices about this response (field-map drift, clamped computed values). Advisory only: its presence never means the request failed. Omitted entirely when there is nothing to report, so treat absent as 'no warnings'.
  - `credits_used` integer, required: Number of credits consumed
  - `credits_remaining` integer, nullable, required: Current account balance, or null when this response could not establish one. Free cache hits always return null because they do not establish an authoritative post-request balance. An idempotency replay also returns null when its current-balance lookup fails. It is never a fabricated zero, so a zero here means the account really is empty. The authoritative reading is the one on a billed response, which comes straight from the deduction.
  - `request_id` string, required: Unique request identifier for support
  - `cached` boolean, required: Whether the response was served from cache
  - `idempotent_replay` boolean: True only when this response is an idempotency replay
  - `meta` object: Optional. Present only when this call completed a pattern that one other call does more cheaply or in one step, at most once per pattern per API key per day. Send the header `X-SocialCrawl-Hints: off` to never receive it.
    - `hint` object: One suggestion: what to call instead and why, with the price when the suggested call costs more than the calls it replaces.
      - `code` string: creator_card | batch_profiles | search_multi | incremental_sync | comment_labels | search_repeat
      - `message` string: One sentence for a person or an agent to read.
      - `method` string: GET or POST.
      - `path` string: The call the hint points to.

## Other responses

- `400`: Invalid request - missing or malformed parameters
- `401`: Unauthorized - missing or invalid API key
- `402`: Payment required - the account balance is too low, or the calling key has spent its own per-key credit limit
- `404`: Not found - the endpoint does not exist, or the requested resource was not found upstream
- `405`: Method not allowed - wrong HTTP verb for this endpoint
- `409`: Conflict - an idempotent request is still in flight, its completed body exceeded the replay limit, or the cohort resource is not in a state that allows this operation
- `410`: Gone - the discover run's retention passed and its rows were deleted; start a new run
- `413`: Payload too large: the JSON request body exceeds the 1 MB size limit and is rejected before parsing, or a single cohort result cannot fit beneath the 1 MB response-page ceiling
- `422`: Idempotency payload mismatch - this Idempotency-Key was already used with a different request payload; or a discover request with async=false is over what one call can answer (NEEDS_ASYNC)
- `429`: Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.
- `500`: Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit
- `502`: Upstream error - the platform returned an error; an immediate refund is attempted and credits_used reports the committed net charge
- `503`: Service unavailable - the request is unbilled when rejected before deduction, otherwise an immediate refund is attempted and credits_used reports the committed net charge
- `504`: Gateway timeout - the request was still running close to the platform time limit and is answered as UPSTREAM_ERROR, the same code as 502. An immediate refund is attempted and credits_used reports the committed net charge. When details.retry_with is set, retryable is false and there is no Retry-After

---

[API](https://skmtc.dev/socialcrawl/apis/socialcrawl-api.md) · [All operations](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/llms.txt) · [OpenAPI document](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/revisions/a0ad2511004a?raw)
