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

# Get TikTok Search Result

> Poll an async TikTok keyword search task and retrieve cursor-paginated normalized result items.

This endpoint does not consume credits — polling is free.

**Usage disclosure:** Set `include_usage=true` to receive a `usage` block describing the charges the background worker recorded for this task. 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).

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`](/api-reference/endpoint/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

| Parameter       | In    | Required | Description                                                                                                                                                                                                   |
| --------------- | ----- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `task_id`       | path  | Yes      | Task ID returned by `POST /tiktok/search`                                                                                                                                                                     |
| `cursor`        | query | No       | Opaque pagination cursor from a previous response                                                                                                                                                             |
| `limit`         | query | No       | Maximum number of items to return, between `1` and `500`. Default is `50`.                                                                                                                                    |
| `include_usage` | query | No       | 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). |

## 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

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.vidnavigator.com/v1/tiktok/search/tt_search_abc123?limit=25&include_usage=true" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  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())
  ```

  ```javascript JavaScript theme={null}
  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();
  ```
</CodeGroup>

## Example Completed Response

```json theme={null}
{
  "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
  }
}
```

<Note>
  The `usage` block appears only when `include_usage=true` and `task_status=completed`.
</Note>

## 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`


## OpenAPI

````yaml GET /tiktok/search/{task_id}
openapi: 3.0.3
info:
  title: VidNavigator Developer API
  description: >-
    The VidNavigator Developer API provides programmatic access to video
    analysis, transcription, and search capabilities.


    ## Authentication

    All endpoints require API key authentication via the `X-API-Key` header:

    ```

    X-API-Key: YOUR_API_KEY

    ```


    ## Rate Limits

    Check the documentation for the rate limits for each endpoint.


    ## Error Handling

    The API uses standard HTTP status codes and returns error responses in JSON
    format:

    ```json

    {
      "status": "error",
      "error": "error_type",
      "message": "Human readable error message"
    }

    ```
  version: 1.0.0
  contact:
    name: VidNavigator Support
    url: https://vidnavigator.com/support
    email: support@vidnavigator.com
  license:
    name: Proprietary
    url: https://vidnavigator.com/terms
servers:
  - url: https://api.vidnavigator.com/v1
    description: Production server
security:
  - ApiKeyAuth: []
tags:
  - name: Transcripts
    description: Extract transcripts from online videos
  - name: TikTok
    description: Scrape TikTok profile metadata and per-video stats
  - name: Files
    description: Manage uploaded audio/video files
  - name: Analysis
    description: AI-powered content analysis
  - name: Extraction
    description: >-
      Extract structured data from video and file transcripts using custom
      schemas
  - name: Namespaces
    description: Organize uploaded files into namespaces (folders)
  - name: Search
    description: Search videos and files using AI
  - name: System
    description: System health and information
  - name: Tweet Analysis
    description: Extract structured claims and metadata from X/Twitter tweets
paths:
  /tiktok/search/{task_id}:
    get:
      tags:
        - TikTok
      summary: Get TikTok keyword search result
      description: >-
        Poll an async TikTok keyword search task and retrieve cursor-paginated
        normalized result items.


        This endpoint does not consume credits — polling is free.


        **Usage disclosure:** Set `include_usage=true` to receive a `usage`
        block describing the charges the background worker recorded for this
        task. 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).
      operationId: getTikTokSearch
      parameters:
        - name: task_id
          in: path
          required: true
          schema:
            type: string
        - name: cursor
          in: query
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 50
        - name: include_usage
          in: query
          required: false
          description: >-
            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).
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Task found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  data:
                    $ref: '#/components/schemas/TikTokSearchTask'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          description: Task not found, expired, or not owned by this user.
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    TikTokSearchTask:
      type: object
      description: >-
        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.
      properties:
        task_id:
          type: string
        task_status:
          type: string
          enum:
            - processing
            - completed
            - failed
        query:
          type: string
        parallel_search_slices:
          type: integer
          minimum: 1
          maximum: 4
          description: >-
            Slice count the task was created with. An N-slice request ran as N
            concurrent paginated TikTok query chains and was billed at up to ~Nx
            the residential pages of a single search.
        filters:
          type: object
          additionalProperties: true
          description: >-
            Echo of the client-side filters supplied at task creation
            (`after_datetime`, `before_datetime`, `min_likes`, `max_likes`,
            `min_views`, `max_views`). Unset fields are returned as null.
          properties:
            after_datetime:
              type: string
              nullable: true
            before_datetime:
              type: string
              nullable: true
            min_likes:
              type: integer
              nullable: true
            max_likes:
              type: integer
              nullable: true
            min_views:
              type: integer
              nullable: true
            max_views:
              type: integer
              nullable: true
        stats:
          type: object
          properties:
            pages_fetched:
              type: integer
            results_count:
              type: integer
            next_search_cursor:
              type: integer
              nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/TikTokSearchResult'
        pagination:
          $ref: '#/components/schemas/TikTokProfilePagination'
        download_url:
          type: string
          format: uri
          nullable: true
          description: >-
            Short-lived (~1 hour) signed Google Cloud Storage URL with the full
            search result as a single JSON file (same shape as paginated
            `results` but unsliced). Same model as AWS S3 / CloudFront
            pre-signed URLs: time-limited and resource-scoped, so it can be used
            from browsers, no-code tools, or any HTTP client without forwarding
            header auth. Set for completed tasks when GCS is configured;
            otherwise null and clients must paginate. Call GET
            /tiktok/search/{task_id} again at any time to mint a fresh URL.
          example: >-
            https://storage.googleapis.com/bucket/api/tiktok_searches/user/task.json?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Signature=...
        error_message:
          type: string
          nullable: true
          description: Present only when task_status is 'failed'.
        created_at:
          type: string
          format: date-time
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true
        expires_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the task document and its download URL availability expire (~1
            hour after creation).
    TikTokSearchResult:
      type: object
      description: Normalized TikTok item from keyword search.
      properties:
        id:
          type: string
          nullable: true
        item_type:
          type: integer
          nullable: true
        description:
          type: string
          nullable: true
        timestamp:
          type: integer
          nullable: true
        published_at:
          type: string
          format: date-time
          nullable: true
        author:
          type: object
          properties:
            id:
              type: string
              nullable: true
            unique_id:
              type: string
              nullable: true
            nickname:
              type: string
              nullable: true
            sec_uid:
              type: string
              nullable: true
        stats:
          type: object
          properties:
            views:
              type: integer
              nullable: true
            likes:
              type: integer
              nullable: true
            comments:
              type: integer
              nullable: true
            shares:
              type: integer
              nullable: true
            collects:
              type: integer
              nullable: true
        music:
          type: object
          properties:
            id:
              type: string
              nullable: true
            title:
              type: string
              nullable: true
            author_name:
              type: string
              nullable: true
            duration:
              type: integer
              nullable: true
        duration:
          type: integer
          nullable: true
        hashtags:
          type: array
          items:
            type: string
        url:
          type: string
          format: uri
          nullable: true
    TikTokProfilePagination:
      type: object
      description: >-
        Cursor-based pagination over the videos array. The cursor encodes an
        absolute offset, so callers can change `limit` between requests without
        skipping or duplicating items.
      properties:
        limit:
          type: integer
        offset:
          type: integer
        total_items:
          type: integer
        has_next:
          type: boolean
        has_prev:
          type: boolean
        next_cursor:
          type: string
          nullable: true
          description: >-
            Opaque cursor; pass in `cursor` query param of the next request, or
            null when has_next is false.
        prev_cursor:
          type: string
          nullable: true
  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                enum:
                  - error
              error:
                type: string
              message:
                type: string
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                enum:
                  - error
              error:
                type: string
                enum:
                  - internal_server_error
              message:
                type: string
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        API key authentication. Include your VidNavigator API key in the
        X-API-Key header.

````