# Best Multi-Platform Social Search API: 129 Rows, 4 Credits (https://www.socialcrawl.dev/blog/best-multi-platform-social-search-api)
> Best multi-platform social search API: one coldplay call returned 129 rows from TikTok, Instagram, YouTube, and Reddit. Four sources were billed 1 credit each.
On 4 October 2026, `GET /v1/search/multi?query=coldplay&platforms=tiktok,instagram,youtube,reddit` returned HTTP 200, 129 rows, and `credits_used` 4. That request is the measured best multi-platform social search API example in this post.
TikTok returned 30 rows, Instagram 30, YouTube 44, and Reddit 25. Those four counts add to 129, which matches `data.total`, and `duplicates_removed` was 0. All four sources had `status` ok and `http_status` 200. Each source `credits` value was 1, and `cached` on this first call was false.
Instagram on this call is reels. `data.sources.instagram.endpoint` was `/v1/instagram/search/reels`.
The row-walk names `min_views`, `max_age_days`, `exclude_country`, `max_pages`, `sort_rows`, and `seen`, bare and with a `tiktok.` prefix, came back HTTP 200, and the endpoint ignored them. There was no `data.walk`.
`tiktok.region=US` was accepted. It is not a filter that keeps only US posts.
## What does one multi-platform search API call return?
On this capture, a multi platform search API response is four platform searches in one envelope. The capture window is 2026-10-04T15:58:36Z through 2026-10-04T15:58:55Z, with header `x-api-key`.
```bash
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/search/multi?query=coldplay&platforms=tiktok,instagram,youtube,reddit"
```
`search_status` was `complete`, and `data.credits_charged` was 4, the same number as `credits_used`. Source warnings were empty. `data._warnings` and `data.walk` were absent, `meta` was null, and `since` was not sent, so `data.since` was null.
| Platform | Source endpoint | status | rows | rows_kept | credits | has_more |
| --- | --- | --- | ---: | ---: | ---: | --- |
| TikTok | `/v1/tiktok/search` | ok | 30 | 30 | 1 | true |
| Instagram | `/v1/instagram/search/reels` | ok | 30 | 30 | 1 | true |
| YouTube | `/v1/youtube/search` | ok | 44 | 44 | 1 | true |
| Reddit | `/v1/reddit/search` | ok | 25 | 25 | 1 | true |
The trimmed fields below are the ones this capture recorded for that envelope. Cursor tokens are left out. Each source still had a next cursor, and this response did not follow it.
```json
{
"credits_used": 4,
"cached": false,
"meta": null,
"pagination": {
"page_size": 129,
"has_more": false,
"next_cursor": null
},
"data": {
"search_status": "complete",
"total": 129,
"duplicates_removed": 0,
"credits_charged": 4,
"since": null,
"sources": {
"tiktok": {
"endpoint": "/v1/tiktok/search",
"status": "ok",
"http_status": 200,
"rows": 30,
"rows_kept": 30,
"credits": 1,
"has_more": true
},
"instagram": {
"endpoint": "/v1/instagram/search/reels",
"status": "ok",
"http_status": 200,
"rows": 30,
"rows_kept": 30,
"credits": 1,
"has_more": true
},
"youtube": {
"endpoint": "/v1/youtube/search",
"status": "ok",
"http_status": 200,
"rows": 44,
"rows_kept": 44,
"credits": 1,
"has_more": true
},
"reddit": {
"endpoint": "/v1/reddit/search",
"status": "ok",
"http_status": 200,
"rows": 25,
"rows_kept": 25,
"credits": 1,
"has_more": true
}
}
}
}
```
`pagination.page_size` was 129, while `pagination.has_more` was false and `pagination.next_cursor` was null. Every source still had `has_more` true. The endpoint returned one page of each search and stopped. There is no page 2 in this capture.
The response grouped rows by platform, in the order named on the query. The first two rows of each platform are below. That order is payload order, not a ranking. YouTube `likes` and `comments`, and Reddit `views`, are null on these sampled rows only. The rest of the page was not counted for nulls.
| Platform | post id | published_at | views | likes | comments | region |
| --- | --- | --- | ---: | ---: | ---: | --- |
| TikTok | `7692099102292610326` | 2026-10-02T15:53:11.000Z | 3528 | 395 | 24 | GB |
| TikTok | `7692138139384646926` | 2026-10-02T18:25:11.000Z | 854 | 80 | 1 | GB |
| Instagram | `3999068825524289411` | 2026-10-02T13:03:15.000Z | 49172 | 3178 | 13 | null |
| Instagram | `3998744852601457183` | 2026-10-02T02:21:04.000Z | 7827 | 600 | 39 | null |
| YouTube | `cIGd8gm_pYE` | 2024-09-26T14:53:55.000Z | 14786472 | null | null | null |
| YouTube | `dvgZkm1xWPE` | 2008-08-04T09:36:03.000Z | 1080495932 | null | null | null |
| Reddit | `1wurpy3` | 2026-10-01T06:03:16.000Z | null | 225 | 54 | null |
| Reddit | `1j7j68k` | 2025-03-09T22:11:33.000Z | null | 29075 | 623 | null |
The second YouTube row is `dvgZkm1xWPE`, text prefix `Coldplay - Viva La Vida (Official Video)`, published 2008-08-04, with 1080495932 views. It is on a 2026 search page because `since` was not sent. `data.since` stayed null. The first TikTok text prefix is `Coldplay fix you (live at Ahmedabad)`, region GB, 3528 views. The first Reddit text prefix starts `2027 Tour Announcement Soon`, 225 likes, views null.
Four searches came back in one envelope, and each source cost 1 credit on this call. The region call further down still returned rows from all four platforms and cost 1 credit.
Page-1 articles for this query are a [data-collection listicle with no request](https://www.cm-alliance.com/cybersecurity-blog/top-5-social-media-api-for-data-collection-and-analytics-in-2026), a [posting API roundup](https://buffer.com/resources/social-media-api-multi-platform-posting/), and a [listening API roundup](https://embedsocial.com/blog/social-listening-api/).
## How do you search multiple social platforms in one request?
The coldplay call named `platforms=tiktok,instagram,youtube,reddit`. That set is the example that was run, not a measured default. A 23 September note names a wider `platforms` list: Threads, X, Facebook, and LinkedIn. It also names a default of TikTok, Instagram, YouTube, Reddit, and Threads when `platforms` is omitted. This run did not omit `platforms`, and it did not call Threads, X, Facebook, or LinkedIn. A price for those platforms, and the cost of the omitted-list default, was not measured here.
Instagram in the diagram is reels search, `/v1/instagram/search/reels`, not a general Instagram search. One page means the combined envelope. Multi's own `pagination.next_cursor` was null while each source still had `has_more` true and a cursor. The next page is that cursor sent to the source endpoint. These cursors were not followed, so this post has no second page to show.
```text
client
| header x-api-key
v
GET /v1/search/multi?query=coldplay&platforms=tiktok,instagram,youtube,reddit
|
+-- /v1/tiktok/search rows 30, rows_kept 30, credits 1, has_more true
+-- /v1/instagram/search/reels rows 30, rows_kept 30, credits 1, has_more true
+-- /v1/youtube/search rows 44, rows_kept 44, credits 1, has_more true
+-- /v1/reddit/search rows 25, rows_kept 25, credits 1, has_more true
|
v
one envelope
data.total 129
credits_used 4
pagination.has_more false
pagination.next_cursor null
```
This request is a multi platform social search api call because four search endpoints share one response. The posting roundup linked above is a multi platform social media api for publishing. This URL searches and does not create a post.
[Social Search Engine API](/blog/social-search-engine) is the planned search, on a different endpoint, and [the later write-up](/blog/universal-search-more-usable-rows) is what that endpoint returned on its own date. This run did not call it.
## When does a cross-platform social search API charge you?
On the two coldplay calls where the outer `cached` flag was false, `credits_used` equaled the sum of `data.sources` credits. That is the cross platform social search api charge these two calls support. Call B returned rows on all four platforms and `credits_used` was 1.
Call A is the unfiltered request already shown. `credits_used` 4, each source `credits` 1, `cached` false, `data.credits_charged` 4.
Call B used the same query and the same four platforms, plus `tiktok.region=US`.
```bash
curl -s -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/search/multi?query=coldplay&platforms=tiktok,instagram,youtube,reddit&tiktok.region=US"
```
HTTP 200, `cached` false, and no ignore warning for `region`.
| Platform | status | rows | rows_kept | credits |
| --- | --- | ---: | ---: | ---: |
| TikTok | ok | 30 | 30 | 1 |
| Instagram | ok | 30 | 30 | 0 |
| YouTube | ok | 44 | 44 | 0 |
| Reddit | ok | 25 | 25 | 0 |
`1+0+0+0` is 1, and both `credits_used` and `data.credits_charged` were 1. The four row counts still add to 129. Instagram, YouTube, and Reddit reported `credits` 0 beside row counts of 30, 44, and 25. The response does not say refunded, empty, or failed. No source had `status` empty or `status` failed. The outer `cached` flag was false, and the response has no per-source cache flag, so these three zeros stay unlabeled.
The second sampled TikTok id changed. The unfiltered call's second TikTok id was `7692138139384646926`. On the region call it was `7692090331122142477`, published 2026-10-02T15:19:39.000Z, 509 views, 20 likes, 0 comments, region US. The sampled Instagram, YouTube, and Reddit ids matched the first call.
`post.ext.region` on all 30 TikTok rows, not a two-row sample:
| region | Unfiltered | `tiktok.region=US` |
| --- | ---: | ---: |
| US | 13 | 10 |
| GB | 4 | 4 |
| PE | 2 | 3 |
| PH | 2 | 2 |
| NG | 1 | 3 |
| BR | 1 | 2 |
| ES | 1 | 1 |
| DE | 1 | 1 |
| FR | 1 | 1 |
| VN | 1 | 1 |
| BE | 1 | 0 |
| LT | 1 | 0 |
| AR | 1 | 0 |
| AU | 0 | 1 |
| TR | 0 | 1 |
Both columns sum to 30. US-registered rows went from 13 to 10, not to 30. On the region call, 20 of the 30 TikTok rows carried some other code. The parameter was accepted and the TikTok page changed. The rows are not limited to US.
No source on either call had `status` empty or `status` failed, so this run cannot show what a platform with zero rows costs. A price for LinkedIn, for an omitted `platforms` list, for a `seen` repeat, or for the planned-search endpoint was not measured here.
Two later calls that attached the walk-filter names returned `credits_used` 0. The next section shows why. That 0 is not a refund for a filter that ran.
## Where do min_views and max_pages actually change rows?
A cross platform social search that wants `min_views` or `max_pages` to change the row set has to leave `GET /v1/search/multi`. On the coldplay calls the endpoint ignored those names. The same names did change rows on one `GET /v1/tiktok/search` call the same UTC day, for a different query. The 129-row coldplay envelope is not that TikTok walk.
### Ignored on the coldplay multi call
Same query, same four platforms, two extra requests. Both returned HTTP 200 with `cached` true, `credits_used` 0, and the same 129 rows, and neither returned `data.walk`. The TikTok region histogram matched the unfiltered call. `max_pages=9` did not walk and did not return 400.
The first of those requests sent the bare names together: `min_views=1000`, `max_age_days=30`, `exclude_country=IN`, `max_pages=9`, `sort_rows=views`, `seen=blogprobe1`.
The later request sent the `tiktok.`-prefixed names together: `tiktok.min_views=1000`, `tiktok.max_age_days=30`, `tiktok.exclude_country=IN`, `tiktok.max_pages=9`, `tiktok.sort_rows=views`, `tiktok.seen=blogprobe1`.
The warnings, verbatim:
- `min_views was ignored: GET /v1/search/multi has no such parameter.`
- `max_age_days was ignored: GET /v1/search/multi has no such parameter.`
- `exclude_country was ignored: did you mean exclude?`
- `max_pages was ignored: GET /v1/search/multi has no such parameter.`
- `sort_rows was ignored: did you mean tiktok.sort_by?`
- `seen was ignored: GET /v1/search/multi has no such parameter.`
- `tiktok.min_views was ignored: did you mean tiktok.date_posted?`
- `tiktok.max_age_days was ignored: did you mean tiktok.date_posted?`
- `tiktok.exclude_country was ignored: did you mean tiktok.date_posted?`
- `tiktok.max_pages was ignored: did you mean tiktok.date_posted?`
- `tiktok.sort_rows was ignored: did you mean tiktok.sort_by?`
- `tiktok.seen was ignored: did you mean tiktok.date_posted?`
`exclude`, `tiktok.sort_by`, and `tiktok.date_posted` appear only as suggestion text. They were not sent. The rows matched the unfiltered call, so the suggestion was not applied. `exclude_country=IN` left the TikTok region histogram unchanged. This run did not send `exclude`, so it does not show that name filtering country. An unknown name on this endpoint, for these twelve strings, returned HTTP 200 and an ignore warning rather than HTTP 400.
The 0 credits are the cache hit. `cached` was true, and the response note says `credits_remaining` is not read on cache hits (`credits_used` is 0) and points at `GET /v1/credits/balance` for the current balance. That 0 does not show that the filters are free when they run, and it is not a refund for a rejected parameter. The filters did not run.
`meta` was null on the English multi responses. `meta.hint` was not in them.
### Applied on a separate TikTok search
This call is separate from the coldplay multi request. Its rows and its credits stay out of the 129 and the 4.
At 2026-10-04T15:59:55Z the capture sent:
```bash
curl -sG -H "x-api-key: $SOCIALCRAWL_API_KEY" \
--data-urlencode "query=뉴진스" \
-d "min_views=100000" \
-d "max_age_days=365" \
-d "exclude_country=US" \
-d "sort_rows=views" \
-d "max_pages=2" \
-d "seen=ko-newjeans-20261005" \
"https://www.socialcrawl.dev/v1/tiktok/search"
```
`region` was not sent. The call returned HTTP 200, `cached` false, `credits_used` 2, and 12 rows.
```json
{
"credits_used": 2,
"cached": false,
"data": {
"walk": {
"pages": 2,
"stopped": "max_pages",
"rows_fetched": 52,
"rows_returned": 12,
"discarded": {
"views_below_min": 37,
"older_than_max_age": 2,
"country_excluded": 1
},
"repeats": 0,
"credits": {
"pages": 2,
"refunded": 0
}
}
}
}
```
`37+2+1` is 40, and so is `52-12`. `data.walk.pages` was 2. `stopped` was `max_pages`, so the call stopped because the request asked for 2 pages, not because the content ended. `next_cursor` was present and was not followed. `max_pages=5` was not sent. `repeats` was 0, `credits.pages` was 2, and `credits.refunded` was 0.
The 12 rows are views descending. The counts are 21974471, 11401920, 4228689, 3474772, 617569, 319066, 309407, 281670, 248911, 214954, 123405, and 113458. The minimum is 113458, so every returned row is at least 100000.
`post.ext.region` on those 12 rows has no US. The codes are KR 8, GB 1, TH 1, HU 1, and ID 1. `published_at` runs from 2026-01-29T16:14:56.000Z through 2026-10-03T06:00:08.000Z, which sits inside 365 days of 2026-10-04T15:59:55Z.
`seen=ko-newjeans-20261005` did not return 400. `walk.credits.refunded` is 0 and `credits_used` is 2. The same id was not sent again, so this capture does not show a `seen` discount.
Forty rows were discarded and the call still cost 2, one per page walked. On this TikTok search, the filters did not make the pages free. That price belongs to `GET /v1/tiktok/search`. The same names never ran on `GET /v1/search/multi`.
## How do you run this call with your own key?
### What the 4 October calls measured
The English window is 2026-10-04T15:58:36Z through 2026-10-04T15:58:55Z, on base `https://www.socialcrawl.dev`, header `x-api-key`, endpoint `GET /v1/search/multi`, query `coldplay`, platforms `tiktok,instagram,youtube,reddit`. `GET /v1/search/everywhere` was not called. `GET /v1/credits/balance` was read around the searches and itself reported `credits_used` 0.
Four multi calls, in order: unfiltered `credits_used` 4 with `cached` false, bare walk names `credits_used` 0 with `cached` true, `tiktok.region=US` `credits_used` 1 with `cached` false, and prefixed walk names `credits_used` 0 with `cached` true.
`4+0+1+0` is 5. The balance reads were 56082, then 56078, then 56077, and `56082-56077` is 5. Quote `credits_used` per call when you compare a rerun. The absolute balance is this key's audit trail, not a price.
The TikTok walk above is a different endpoint and the query `뉴진스`. Its `credits_used` of 2 is not part of the English 5.
You need a SocialCrawl key in the `x-api-key` header. The smallest call is the coldplay URL above. The row set will differ on a later day, and the counts in this post are that 4 October window.
The [multi-platform search API](/docs/search/multi) page documents this endpoint. The [pricing page](/docs/endpoint-pricing) is where current page prices live. The [API reference](/docs/api-reference) is the full catalogue. This post does not paste prices the 4 October calls did not measure. You can send the coldplay URL from the [public explorer](/explorer) before you write a client.
## Frequently asked questions
### How many credits did the four-platform coldplay call use?
The unfiltered coldplay call reported `credits_used` 4 and `data.credits_charged` 4. TikTok, Instagram, YouTube, and Reddit each had `credits` 1. That figure is this call, with those four platforms named on the query. A call that omitted `platforms` was not made, so the 4 is not a default hold.
### Does GET /v1/search/multi apply min_views or max_pages?
No. Bare `min_views`, `max_age_days`, `exclude_country`, `max_pages`, `sort_rows`, and `seen`, and the same names with a `tiktok.` prefix, returned HTTP 200, an ignore warning for each name, no `data.walk`, and the same 129 rows. `max_pages=9` did not walk. The responses with `credits_used` 0 had `cached` true, which is why the charge was 0. The filter names were ignored, so they did not run.
### Does tiktok.region=US keep only US posts?
No. The parameter was accepted, the TikTok page changed, and 10 of 30 TikTok rows had `post.ext.region` US. `credits_used` was 1. Instagram, YouTube, and Reddit still returned 30, 44, and 25 rows with `credits` 0. The response does not label those zeros as a refund.
### Where do min_views and max_pages change the rows?
Not on the coldplay multi call. On a separate `GET /v1/tiktok/search` the same UTC day, query `뉴진스`, with `min_views=100000`, `max_age_days=365`, `exclude_country=US`, `sort_rows=views`, and `max_pages=2`, the response had 12 rows, `credits_used` 2, 52 rows fetched, and 40 discarded, and `data.walk.stopped` was `max_pages`. `seen` refunded 0. The same `seen` id was not sent again.
### How is this different from a planned social search?
This call returns each platform's own search page. It does not plan the query, rank the rows, or group them. The planned endpoint is the one in [Social Search Engine API](/blog/social-search-engine) and [the later write-up of what that call returned on its own date](/blog/universal-search-more-usable-rows). This run did not call that endpoint and did not measure its price. `meta` was null, so `meta.hint` was not in the response.