> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-fetch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# TikTok search

> Search TikTok by keyword: one row per video, with author fields on every row. scraper_type tiktok_search.

`tiktok_search` runs TikTok keyword searches. One result is one video, and every row carries the video's author
fields. A video that matches two keywords is returned once, under the first.

## Run it

```python Python theme={null}
import os

from gofetch import GoFetchClient

client = GoFetchClient(api_key=os.environ["GOFETCH_API_KEY"])

run = client.actor("tiktok_search").call(run_input={"searchQueries": ["nasa"], "maxItems": 50})

for video in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(video["keyword"], video["postPage"], video["views"], video["channel"]["username"])
```

```bash cURL theme={null}
curl https://go-fetch.io/api/v1/jobs/create/ \
  -H "X-API-Key: $GOFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scraper_type": "tiktok_search", "config": {"searchQueries": ["nasa"], "maxItems": 50}}'
```

> [!NOTE]
>
> gofetch-client 0.8.0 does not list `tiktok_search` yet. `client.actor("tiktok_search")` works, and Python prints a
> `UserWarning: Unknown actor URL 'tiktok_search', passing through as scraper type` you can ignore.

## Inputs

| Field | Type | Default | What it does |
| - | - | - | - |
| `searchQueries` | list of text | | Keywords, up to 100 after duplicates are removed. `keywords` is accepted as another name. |
| `maxItems` | integer | `1000` | Rows for the whole job, from 1 to 100,000. Honoured exactly: it is also what the job reserves credit for. |
| `maxItemsPerKeyword` | integer | | Rows per keyword, from 1 to 100,000. |
| `maxPostsPerAuthor` | integer | | Videos per author across the whole job, from 1 to 100,000. |
| `uniqueAuthors` | true / false | `false` | At most one video per author across the whole job. |
| `sortType` | text | `RELEVANCE` | `RELEVANCE`, `MOST_LIKED` or `DATE_POSTED`. The last two re-order the videos collected for each keyword; they do not fetch the most-liked or newest videos. |
| `expansion` | list | `[]` | Also search TikTok's suggestions (`suggest`), hashtag feeds (`hashtag`) or the sounds most used in the results (`music`). Expansions add only authors not yet in the job, one video each. |
| `relevanceThreshold` | number | `0.3` | For `music` only: how closely a sound's videos must match the keyword (0 to 1) to be kept. |
| `includeSearchKeywords` | true / false | `true` | Add `inputSource` and `keyword` to each row. |
| `maxTotalChargeUsd` | number | | A spending cap. Without `maxItems`, the budget sets the volume, up to 100,000 items. An explicit `maxItems` whose cost exceeds the budget is refused with `400`. See [Billing](https://docs.go-fetch.io/billing.md#cap-a-job-with-maxtotalchargeusd). |

Keywords run one after another, in the order you send them. A search also tries close spellings of the keyword, so
`home workout` can return videos for `homeworkout`.

## Output

One row per video. There are no error or placeholder rows: every row is a billed result. A real row from a search
for `nasa`:

```json theme={null}
[
  {
    "inputSource": "nasa",
    "id": "7686148096895569165",
    "title": "Turns out you can dance in space! 🪩🕺💫🛰️ Microgravity just unlocked some new moves. ",
    "views": 1300000,
    "likes": 154300,
    "comments": 2826,
    "shares": 7567,
    "bookmarks": 11500,
    "hashtags": [],
    "channel": {
      "id": "7664638705177150477",
      "name": "NASA",
      "username": "nasa",
      "avatar": "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/e5143212a59c09a008bf50f487d54d1f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=10399&refresh_token=b9217d73&x-expires=1792227600&x-signature=BWpEVM%2BJIq1PvR5AkSos7G%2F5YUA%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=no1a",
      "verified": true,
      "url": "https://www.tiktok.com/@nasa",
      "followers": 2100000,
      "following": 23,
      "videos": 56,
      "likes": 11000000
    },
    "collabInfo": null,
    "uploadedAt": 1789570841,
    "uploadedAtFormatted": "2026-09-16T15:00:41.000Z",
    "video": {
      "width": 720,
      "height": 1280,
      "ratio": "720p",
      "duration": 58,
      "url": "https://v16-webapp-prime.tiktok.com/video/tos/alisg/tos-alisg-ve-37c799-sg/ooZKIHALfI2VijQAtgIVDoEVKprJGeMCk0oVeq/?a=1988&bti=ODszNWYuMDE6&&bt=1517&ft=-Csk_mwKPD12NT2Yhn-UxhM2hY3W3wv25McAp&mime_type=video_mp4&rc=NWU1ZTw3NjU8PGc0OTNnOkBpajZtcW85cjRkZDMzZzczNEBgYi02MzIzXi4xM2I2Yl9fYSNocm1hMmQ0bmlhLS1kMS9zcw%3D%3D&expire=1792227965&l=20261015090506DCF2B0E8E2326EA08DF7&ply_type=2&policy=2&signature=003f18575c4c89680c1740b977c3125b&tk=tt_chain_token&btag=e00088000",
      "cover": "https://p16-common-sign.tiktokcdn-eu.com/tos-useast5-p-0068-tx/owxfIpLsSekJwDsqHCGAIoVVjtVArCqIyVIZeN~tplv-tiktokx-origin.image?dr=10395&x-expires=1792227600&x-signature=zn%2B%2FEPfEQZ2G2r6dXIdHHThoEOE%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=no1a",
      "thumbnail": "https://p16-common-sign.tiktokcdn-eu.com/tos-useast5-p-0068-tx/oIq8AVGCTQV9LeeolkeCjtJZxVHqrVIzAIHSiQ~tplv-tiktokx-origin.image?dr=10395&x-expires=1792227600&x-signature=BdpkI0dr7%2F%2FAtK245hsQ9D3PtSQ%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=no1a"
    },
    "song": {
      "id": 7686148224364695000,
      "title": "original sound - NASA",
      "artist": "NASA",
      "album": null,
      "duration": 58,
      "cover": "https://p16.tiktokcdn-us.com/aweme/720x720/tos-useast5-avt-0068-tx/e5143212a59c09a008bf50f487d54d1f.jpeg"
    },
    "subtitleInformation": null,
    "postPage": "https://www.tiktok.com/@nasa/video/7686148096895569165",
    "poi": null,
    "keyword": "nasa"
  }
]
```

This row was captured before `song.id` became text, so it shows the id as a rounded number. Every id in a row is now text.

| Field | Type | What it holds |
| - | - | - |
| `id` | text | The video's id. |
| `title` | text | The caption; `""` when there is none. |
| `postPage` | URL | Link to the video. |
| `views`, `likes`, `comments`, `shares`, `bookmarks` | integer | Counts; `0` when TikTok sent none. |
| `uploadedAt`, `uploadedAtFormatted` | integer, date-time | When it was posted, as Unix seconds and as ISO 8601 UTC. |
| `hashtags` | list | Tag names without `#`. An entry can be `null` for a caption entity that is not a hashtag. |
| `channel` | object | Author fields: `id`, `name`, `username`, `url`, `avatar`, `verified` (`null` when TikTok sent no badge), `followers`, `following`, `videos`, `likes`. |
| `video` | object | `width`, `height`, `ratio`, `duration`, `url`, `cover`, `thumbnail`. `url` is TikTok's own link. |
| `song` | object | The sound: `id` (text), `title`, `artist`, `album`, `duration`, `cover`. |
| `subtitleInformation` | list or null | Caption tracks with `lang`, `language_code`, `is_auto_generated` and `url`; `null` when there are none. |
| `poi` | object or null | A tagged place: `poiName`, `address`, `cityName`, `latitude`, `longitude` and more. |
| `collabInfo` | object or null | TikTok's collaboration data, unchanged. |
| `inputSource`, `keyword` | text | The keyword the row was found for (with `includeSearchKeywords`). |
| `expansion_source` | text | With `expansion`: `relevance`, `suggest`, `hashtag` or `music`, the search that found the author. |

## What logged-out means here

**You get:** what TikTok's search shows a signed-out visitor for each keyword, with the video's counts and its
author's public fields.

**Not available:** choosing the country or region a search runs for. A `location` input is accepted and ignored;
a value other than `US` adds a warning to the job's log.

A keyword TikTok did not answer is marked `blocked` in `completeness.keywords`, and the job still completes with the
other keywords' rows. The job fails, with `error_code` `BLOCKED`, only when it collected nothing and at least one
keyword got no answer.

## Completeness

`scraper_metadata.completeness`:

| Key | What it says |
| - | - |
| `keywords` | Per keyword: `requested`, `classic_items`, `pool_items` (from expansions), `unique_authors`, `blocked`, `empty`. |
| `totals` | `items`, `classic_items`, `pool_items`, `unique_authors` for the job. |
| `keywords_total`, `keywords_blocked`, `keywords_empty` | How many keywords ran, got no answer, or answered with nothing. |
| `truncated_by_max_items` | `maxItems` ran out before every keyword was searched. |
| `failure_reason` | `ok`, or `empty` when every keyword answered with nothing. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.