tiktok.search_keyword. The transport rules that apply to every API a seller serves - signed requests, the response envelope, timeouts, and body limits - are on the operator endpoint contract.
The price you compete with
AnyAPI publishes this API from $0.60 per 1,000 requests. That is the price a buyer sees today, so it is the price your endpoint has to come in under to win traffic.The request your endpoint receives
| Field | Type | Required | What it means |
|---|---|---|---|
cursor | string | no | Pagination cursor from a previous response. |
datePosted | integer or string | no | Time frame filter, in days back from now. Use a canonical JSON integer that is nonnegative: 0 for any time, 1 for the past 24 hours, 7 for the past week, 30 for the past month, 90 for the past three months, or 180 for the past six months. Any other number is not guaranteed to filter anything. Legacy numeric strings remain accepted. Default 0. |
query | string | yes | The keyword to search TikTok for. |
requireCursor | boolean | no | Deprecated: name nextCursor in requireFields instead, which is the field this flag is translated into. It stays accepted so callers that already send it keep working. Sending it routes you to a source that returns a pagination cursor, which can raise your price when the cheapest source cannot page. |
requireFields | array | no | Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example nextCursor, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a record that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. |
sortBy | string | no | Sort order: relevance, most-liked, date-posted. One of: relevance, most-liked, date-posted. Default "relevance". |
Full input JSON Schema
Full input JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://getanyapi.com/schemas/tiktok.search_keyword.input.json",
"example": {
"query": "cooking",
"datePosted": 0,
"sortBy": "relevance"
},
"title": "TikTok keyword search input",
"type": "object",
"additionalProperties": false,
"x-anyapi-compat-values": {
"sortBy": {
"0": "relevance",
"1": "most-liked",
"2": "date-posted",
"popular": "most-liked",
"like": "most-liked"
}
},
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"description": "The keyword to search TikTok for."
},
"datePosted": {
"type": [
"integer",
"string"
],
"minimum": 0,
"pattern": "^[0-9]+$",
"default": 0,
"description": "Time frame filter, in days back from now. Use a canonical JSON integer that is nonnegative: 0 for any time, 1 for the past 24 hours, 7 for the past week, 30 for the past month, 90 for the past three months, or 180 for the past six months. Any other number is not guaranteed to filter anything. Legacy numeric strings remain accepted."
},
"sortBy": {
"type": "string",
"enum": [
"relevance",
"most-liked",
"date-posted"
],
"default": "relevance",
"description": "Sort order: relevance, most-liked, date-posted."
},
"cursor": {
"type": "string",
"description": "Pagination cursor from a previous response."
},
"requireCursor": {
"type": "boolean",
"deprecated": true,
"description": "Deprecated: name `nextCursor` in `requireFields` instead, which is the field this flag is translated into. It stays accepted so callers that already send it keep working. Sending it routes you to a source that returns a pagination cursor, which can raise your price when the cheapest source cannot page."
},
"requireFields": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"authorFollowers",
"authorVerified",
"locationName",
"nextCursor",
"paidPartnership",
"soundAuthor",
"soundTitle"
]
},
"description": "Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `nextCursor`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a record that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge."
}
}
}
The response your endpoint must return
| Field | Type | Always present | What it means |
|---|---|---|---|
data | null or object | yes | |
data.nextCursor | string or null | no | Opaque cursor for the next page of videos, or null when this lane has no more. Pass it back as cursor to continue. |
data.videos | array | yes | |
data.videos[].author | string | no | Username (handle) of the account that posted, without the @ prefix. |
data.videos[].authorFollowers | integer or null | no | The author’s follower count at the time of the request. Null when the serving source does not report it. |
data.videos[].authorImage | string | no | Author’s avatar image URL. Signed and short-lived, so the query string is load-bearing and kept intact. |
data.videos[].authorName | string | no | Author’s display name. |
data.videos[].authorUserId | string | no | Author’s numeric TikTok user id. |
data.videos[].authorVerified | boolean or null | no | Whether the author’s account carries a TikTok verification badge. Null when the serving source does not report it. |
data.videos[].caption | string | yes | |
data.videos[].comments | integer | yes | |
data.videos[].createdUtc | number | no | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
data.videos[].durationSeconds | number | no | Video duration in seconds. |
data.videos[].hashtags | array | no | Hashtags carried in the caption, without the leading #. Empty when the post uses none; @-mentions are excluded. |
data.videos[].id | string | yes | |
data.videos[].image | string | no | URL of the video’s cover/thumbnail image. A signed, short-lived TikTok CDN URL (typically expires within about a day; query params are load-bearing and kept intact), often served as HEIC rather than JPEG, so fetch it promptly and transcode if you need broad browser support. |
data.videos[].likes | integer | yes | |
data.videos[].locationName | string or null | no | Name of the place the video is tagged at. Absent when the video has no location tag. Null when the serving source does not report it. |
data.videos[].paidPartnership | boolean or null | no | Whether the video is labeled as a paid partnership. Null when the serving source does not report it. |
data.videos[].region | string | yes | |
data.videos[].saves | integer | no | |
data.videos[].shares | integer | yes | |
data.videos[].soundAuthor | string or null | no | Credited author of the sound. Null when the serving source does not report it. |
data.videos[].soundClipId | string | no | Id of the sound the video uses. Pass it to tiktok.song or tiktok.song_videos as clipId. |
data.videos[].soundTitle | string or null | no | Name of the sound. “original sound” means the creator’s own audio rather than a licensed track. Null when the serving source does not report it. |
data.videos[].url | string | no | Canonical TikTok URL of the video. |
data.videos[].videoUrl | string | no | Playable video URL. Signed and short-lived, so the query string is load-bearing and kept intact. |
data.videos[].views | integer | yes | |
found | boolean | yes |
Full output JSON Schema
Full output JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://getanyapi.com/schemas/tiktok.search_keyword.output.json",
"title": "TikTok keyword search output",
"type": "object",
"additionalProperties": false,
"required": [
"found",
"data"
],
"properties": {
"found": {
"type": "boolean"
},
"data": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"additionalProperties": false,
"required": [
"videos"
],
"properties": {
"nextCursor": {
"type": [
"string",
"null"
],
"description": "Opaque cursor for the next page of videos, or null when this lane has no more. Pass it back as cursor to continue."
},
"videos": {
"x-anyapi-must-populate": true,
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"caption",
"region",
"views",
"likes",
"comments",
"shares"
],
"properties": {
"id": {
"x-anyapi-must-populate": true,
"type": "string"
},
"caption": {
"x-anyapi-must-populate": true,
"type": "string"
},
"author": {
"type": "string",
"description": "Username (handle) of the account that posted, without the @ prefix."
},
"createdUtc": {
"type": "number",
"description": "UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds."
},
"region": {
"type": "string"
},
"views": {
"type": "integer"
},
"likes": {
"type": "integer"
},
"comments": {
"type": "integer"
},
"shares": {
"type": "integer"
},
"saves": {
"type": "integer"
},
"url": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "Canonical TikTok URL of the video."
},
"image": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "URL of the video's cover/thumbnail image. A signed, short-lived TikTok CDN URL (typically expires within about a day; query params are load-bearing and kept intact), often served as HEIC rather than JPEG, so fetch it promptly and transcode if you need broad browser support."
},
"videoUrl": {
"type": "string",
"description": "Playable video URL. Signed and short-lived, so the query string is load-bearing and kept intact."
},
"durationSeconds": {
"type": "number",
"description": "Video duration in seconds."
},
"authorName": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "Author's display name."
},
"authorUserId": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "Author's numeric TikTok user id."
},
"authorImage": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "Author's avatar image URL. Signed and short-lived, so the query string is load-bearing and kept intact."
},
"authorFollowers": {
"type": [
"integer",
"null"
],
"description": "The author's follower count at the time of the request. Null when the serving source does not report it."
},
"authorVerified": {
"type": [
"boolean",
"null"
],
"description": "Whether the author's account carries a TikTok verification badge. Null when the serving source does not report it."
},
"soundClipId": {
"x-anyapi-must-populate": true,
"type": "string",
"description": "Id of the sound the video uses. Pass it to tiktok.song or tiktok.song_videos as clipId."
},
"soundTitle": {
"type": [
"string",
"null"
],
"description": "Name of the sound. \"original sound\" means the creator's own audio rather than a licensed track. Null when the serving source does not report it."
},
"soundAuthor": {
"type": [
"string",
"null"
],
"description": "Credited author of the sound. Null when the serving source does not report it."
},
"hashtags": {
"x-anyapi-must-populate": true,
"type": "array",
"description": "Hashtags carried in the caption, without the leading #. Empty when the post uses none; @-mentions are excluded.",
"items": {
"type": "string"
}
},
"locationName": {
"type": [
"string",
"null"
],
"description": "Name of the place the video is tagged at. Absent when the video has no location tag. Null when the serving source does not report it."
},
"paidPartnership": {
"type": [
"boolean",
"null"
],
"description": "Whether the video is labeled as a paid partnership. Null when the serving source does not report it."
}
}
}
}
}
}
]
}
}
}
Fields that must never come back empty
authorImageauthorNameauthorUserIdcaptionhashtagsidimagesoundClipIdurlvideos
Not found, and how it differs from empty
When the entity does not exist, answer 2xx with the not-found shape:{
"found": false,
"data": null
}
found: true and an empty videos array.
This output schema declares no reason field, so found: false is the whole not-found answer.
Example request
{
"query": "cooking",
"datePosted": 0,
"sortBy": "relevance"
}
Next
- The operator endpoint contract for signing, budgets, and the live trial.
- Every API open to sellers.
- Want to sell an API that is not on that list? Email support@getanyapi.com.