Skip to main content
GET
/
tiktok
/
search
/
{task_id}
Get TikTok keyword search result
curl --request GET \
  --url https://api.vidnavigator.com/v1/tiktok/search/{task_id} \
  --header 'X-API-Key: <api-key>'
import requests

url = "https://api.vidnavigator.com/v1/tiktok/search/{task_id}"

headers = {"X-API-Key": "<api-key>"}

response = requests.get(url, headers=headers)

print(response.text)
const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};

fetch('https://api.vidnavigator.com/v1/tiktok/search/{task_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vidnavigator.com/v1/tiktok/search/{task_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.vidnavigator.com/v1/tiktok/search/{task_id}"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("X-API-Key", "<api-key>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.vidnavigator.com/v1/tiktok/search/{task_id}")
.header("X-API-Key", "<api-key>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.vidnavigator.com/v1/tiktok/search/{task_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'

response = http.request(request)
puts response.read_body
{
  "status": "success",
  "data": {
    "task_id": "<string>",
    "query": "<string>",
    "parallel_search_slices": 2,
    "filters": {
      "after_datetime": "<string>",
      "before_datetime": "<string>",
      "min_likes": 123,
      "max_likes": 123,
      "min_views": 123,
      "max_views": 123
    },
    "stats": {
      "pages_fetched": 123,
      "results_count": 123,
      "next_search_cursor": 123
    },
    "results": [
      {
        "id": "<string>",
        "item_type": 123,
        "description": "<string>",
        "timestamp": 123,
        "published_at": "2023-11-07T05:31:56Z",
        "author": {
          "id": "<string>",
          "unique_id": "<string>",
          "nickname": "<string>",
          "sec_uid": "<string>"
        },
        "stats": {
          "views": 123,
          "likes": 123,
          "comments": 123,
          "shares": 123,
          "collects": 123
        },
        "music": {
          "id": "<string>",
          "title": "<string>",
          "author_name": "<string>",
          "duration": 123
        },
        "duration": 123,
        "hashtags": [
          "<string>"
        ],
        "url": "<string>"
      }
    ],
    "pagination": {
      "limit": 123,
      "offset": 123,
      "total_items": 123,
      "has_next": true,
      "has_prev": true,
      "next_cursor": "<string>",
      "prev_cursor": "<string>"
    },
    "download_url": "https://storage.googleapis.com/bucket/api/tiktok_searches/user/task.json?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Signature=...",
    "error_message": "<string>",
    "created_at": "2023-11-07T05:31:56Z",
    "completed_at": "2023-11-07T05:31:56Z",
    "expires_at": "2023-11-07T05:31:56Z"
  }
}
{
"status": "error",
"error": "<string>",
"message": "<string>"
}
{
"status": "error",
"error": "internal_server_error",
"message": "<string>"
}
Poll a TikTok keyword search task and retrieve cursor-paginated, normalized result items.

Overview

This is the second half of the TikTok keyword search workflow. Use it after you submit a search with POST /tiktok/search. It serves three purposes:
  • check whether the task is still running
  • retrieve the matched videos page by page (sorted by published_at, newest first)
  • get a temporary download_url for the full JSON result when available
Polling does not consume credits.

Request Parameters

ParameterInRequiredDescription
task_idpathYesTask ID returned by POST /tiktok/search
cursorqueryNoOpaque pagination cursor from a previous response
limitqueryNoMaximum number of items to return, between 1 and 500. Default is 50.
include_usagequeryNoWhen true and task_status=completed, attach a usage block describing the charges the background worker recorded (pages_fetched × residential_request; no search_request for TikTok keyword search).

Usage Disclosure

Because billing happens in the background worker, the submit endpoint cannot disclose usage. Instead, pass include_usage=true here:
  • Returned only when task_status=completed (processing tasks haven’t finished billing; failed tasks have all charges refunded).
  • Charges are pages_fetched × residential_request. No search_request is billed for TikTok keyword search.

Polling Lifecycle

The task_status field will be one of:
  • processing: the search is still running
  • completed: the search finished and results are ready
  • failed: the search ended with an error (all charges refunded)
While processing, results will be empty and download_url will usually be null.

Example Requests

curl "https://api.vidnavigator.com/v1/tiktok/search/tt_search_abc123?limit=25&include_usage=true" \
  -H "X-API-Key: YOUR_API_KEY"
import requests

response = requests.get(
    "https://api.vidnavigator.com/v1/tiktok/search/tt_search_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 25, "include_usage": "true"},
)

print(response.json())
const response = await fetch(
  'https://api.vidnavigator.com/v1/tiktok/search/tt_search_abc123?limit=25&include_usage=true',
  {
    headers: {
      'X-API-Key': 'YOUR_API_KEY'
    }
  }
);

const result = await response.json();

Example Completed Response

{
  "status": "success",
  "data": {
    "task_id": "tt_search_abc123",
    "task_status": "completed",
    "query": "ai tools",
    "parallel_search_slices": 2,
    "filters": {
      "after_datetime": "2024-01-01T00:00:00Z",
      "before_datetime": null,
      "min_likes": 1000,
      "max_likes": null,
      "min_views": null,
      "max_views": null
    },
    "stats": {
      "pages_fetched": 18,
      "results_count": 172,
      "next_search_cursor": null
    },
    "results": [
      {
        "id": "7351234567890123456",
        "item_type": 1,
        "description": "Top AI tools you should try",
        "timestamp": 1712345678,
        "published_at": "2024-04-05T19:34:38Z",
        "author": {
          "id": "6789",
          "unique_id": "creator",
          "nickname": "Creator Name",
          "sec_uid": "MS4wLjAB..."
        },
        "stats": {
          "views": 250000,
          "likes": 22000,
          "comments": 950,
          "shares": 120,
          "collects": 340
        },
        "music": {
          "id": "1122",
          "title": "Original sound",
          "author_name": "creator",
          "duration": 30
        },
        "duration": 28,
        "hashtags": ["ai", "tools", "productivity"],
        "url": "https://www.tiktok.com/@creator/video/7351234567890123456"
      }
    ],
    "pagination": {
      "limit": 25,
      "offset": 0,
      "total_items": 172,
      "has_next": true,
      "has_prev": false,
      "next_cursor": "eyJvZmZzZXQiOjI1fQ==",
      "prev_cursor": null
    },
    "download_url": "https://storage.googleapis.com/bucket/api/tiktok_searches/user/task.json?...",
    "error_message": null,
    "created_at": "2026-04-26T12:00:00Z",
    "completed_at": "2026-04-26T12:01:40Z",
    "expires_at": "2026-04-26T13:00:00Z"
  },
  "usage": {
    "charges": [
      { "service_type": "residential_request", "quantity": 18, "credits": 0.09 }
    ],
    "total_credits": 0.09
  }
}
The usage block appears only when include_usage=true and task_status=completed.

Understanding the Response

stats

  • pages_fetched: number of TikTok pages fetched (this is what you are billed for, as residential_request)
  • results_count: total normalized items collected
  • next_search_cursor: internal upstream cursor, or null when exhausted

results

Each item is a normalized TikTok video with id, description, timestamp, published_at (UTC ISO 8601), author, stats (views/likes/comments/shares/collects), music, duration, hashtags, and url. Items are sorted by published_at descending; items without a timestamp go last.

download_url

When present, a short-lived signed URL pointing to the full search result as one JSON file (same shape as the paginated results, but unsliced). null when the task hasn’t finished or signed URLs aren’t configured — paginate through results instead.

Error Cases

  • 400: invalid request (e.g. bad cursor)
  • 404: task does not exist, expired, or does not belong to the current user

Tips

  • poll every few seconds while task_status is processing
  • switch to download_url for large completed jobs
  • tasks expire after about 1 hour — use expires_at to avoid polling expired tasks
  • call the endpoint again later if you need a freshly minted download_url

Authorizations

X-API-Key
string
header
required

API key authentication. Include your VidNavigator API key in the X-API-Key header.

Path Parameters

task_id
string
required

Query Parameters

cursor
string
limit
integer
default:50
Required range: 1 <= x <= 500
include_usage
boolean
default:false

When true and task_status=completed, attach a usage block describing the charges the background worker recorded (pages_fetched × residential_request; no search_request for TikTok keyword search).

Response

Task found.

status
enum<string>
Available options:
success
data
object

TikTok keyword search task result body returned by GET /tiktok/search/{task_id}. results are sorted by published_at descending (newest first); items without a timestamp go last.