# TikTok Posts API

Beta

Returns a TikTok account's public videos and photo posts, newest first, with caption, hashtags, mentions, publish time, duration, cover, photos and engagement counts.

[Get 100 free credits](https://staging.socialtap.dev/signup/?next=%2Fplayground%2F%3Fendpoint%3Dtiktok.posts) · [API reference](https://staging.socialtap.dev/docs/reference/tiktok/posts/index.md) · [Try it](https://staging.socialtap.dev/playground/?endpoint=tiktok.posts)

- **Price**: From **1 credit** per page$0.75–$1.45 per 1,000 pages
- **Request**: `GET /v1/tiktok/posts`One API key, one JSON schema
- **Input**: `handle`e.g. `nasa`
- **Page size**: Up to 15 posts

Use cases

## What teams build with it. From one request.

- Monitor an account's new posts since a date
- Benchmark engagement across accounts
- Build datasets of an account's TikTok content

What you get

## Posts in one schema. The same on every platform.

- **`platform`string**: Platform ID (tiktok, youtube, …).
- **`id`string**: Platform-native post ID (string; Instagram shortcode, Reddit without t3_).
- **`url`string**: Canonical post URL.
- **`type`string**: Normalized content shape. New values may be added; treat unknown values as other.
- **`platform_type`string**: The platform's own product label, lowercase (reel, short, story, live, tweet, …).
- **`title`string**: Headline (YouTube title, Reddit title); null on caption-only platforms.
- **`text`string**: Caption, description or body as plain text.
- **`language`string**: BCP-47 language of text, when the platform states it.

Every field, its type and when it is `null`: [the response reference](https://staging.socialtap.dev/docs/reference/tiktok/posts/index.md#response) and the [post schema](https://staging.socialtap.dev/resources/post/index.md).

## Example request

cURL:

```shell
curl -G 'https://staging.socialtap.dev/v1/tiktok/posts' \
  --data-urlencode 'handle=@khaby.lame' \
  -H "x-api-key: $SOCIALTAP_API_KEY"
```

Node.js:

```javascript
const params = new URLSearchParams({
  handle: "@khaby.lame",
});
const res = await fetch(`https://staging.socialtap.dev/v1/tiktok/posts?${params}`, {
  headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);
```

Python:

```python
import os

import requests

res = requests.get(
    "https://staging.socialtap.dev/v1/tiktok/posts",
    params={"handle": "@khaby.lame"},
    headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
    raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])
```

Go:

```go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
)

func main() {
	q := url.Values{}
	q.Set("handle", "@khaby.lame")
	req, err := http.NewRequest("GET", "https://staging.socialtap.dev/v1/tiktok/posts?"+q.Encode(), nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	var body struct {
		Data  json.RawMessage `json:"data"`
		Page  json.RawMessage `json:"page"`
		Meta  map[string]any  `json:"meta"`
		Error *struct {
			Code    string `json:"code"`
			Message string `json:"message"`
		} `json:"error"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		log.Fatal(err)
	}
	if body.Error != nil {
		log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
	}
	fmt.Println(string(body.Data), body.Meta["credits_charged"])
}
```

200 OK:

```json
{
  "data": [
    {
      "approximate_fields": [
        "metrics.view_count",
        "metrics.like_count",
        "metrics.share_count"
      ],
      "author": {
        "avatar_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
        "display_name": "Khabane lame",
        "id": "127905465618821121",
        "is_verified": true,
        "url": "https://www.tiktok.com/@khaby.lame",
        "username": "khaby.lame"
      },
      "coauthors": [],
      "duration_ms": 9000,
      "hashtags": [
        "learnfromkhaby",
        "comedy"
      ],
      "id": "7697307919943060767",
      "is_nsfw": null,
      "is_pinned": null,
      "is_sponsored": null,
      "language": "en",
      "media": [
        {
          "alt_text": null,
          "duration_ms": 9000,
          "expires_at": null,
          "height": 1280,
          "thumbnail_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oQbHQmFfa5VY3NlkEGDAQT00RzqAqBOETlEafj~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
          "type": "video",
          "url": null,
          "width": 720
        }
      ],
      "mentions": [],
      "metrics": {
        "comment_count": 7503,
        "like_count": 305900,
        "quote_count": null,
        "repost_count": null,
        "save_count": 16282,
        "share_count": 32600,
        "view_count": 4600000
      },
      "platform": "tiktok",
      "platform_specific": {
        "tiktok": {
          "author_sec_uid": "MS4wLjABAAAAwAg0rSzO65WQfz4RzQgGv2Xdv108BgPXhRrrmNVIHQZ9PO8-flwwRtEppYTS0OjA",
          "country_code": null,
          "is_ad": false,
          "is_ai_generated": true,
          "location": null,
          "music": {
            "author_name": "Khabane lame",
            "cover_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
            "duration_ms": 9000,
            "id": "7697308007327730462",
            "is_original": true,
            "play_url": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-useast8-v-27dcd7-tx2/oEEIAbfkyMVIeCnAjGGKYI9gqpqTImLAAfYo09/?a=1988&bti=ODszNWYuMDE6&&bt=125&ft=GcAInInz7Th~v-RGXq8Zmo&mime_type=audio_mpeg&rc=M2lybXI5cnE4ZTMzaTU8NEBpM2lybXI5cnE4ZTMzaTU8NEBxYG5tMmRrNjZhLS1kMTJzYSNxYG5t…",
            "title": "original sound"
          }
        }
      },
      "platform_type": "video",
      "published_at": "2026-10-16T16:46:21Z",
      "text": "I guess is time to retire #learnfromkhaby #comedy 🥊",
      "thumbnail_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oQbHQmFfa5VY3NlkEGDAQT00RzqAqBOETlEafj~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
      "title": null,
      "type": "video",
      "unknown_fields": [],
      "url": "https://www.tiktok.com/@khaby.lame/video/7697307919943060767"
    },
    {
      "approximate_fields": [
        "metrics.view_count",
        "metrics.like_count",
        "metrics.comment_count"
      ],
      "author": {
        "avatar_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
        "display_name": "Khabane lame",
        "id": "127905465618821121",
        "is_verified": true,
        "url": "https://www.tiktok.com/@khaby.lame",
        "username": "khaby.lame"
      },
      "coauthors": [],
      "duration_ms": 30000,
      "hashtags": [
        "learnfromkhaby",
        "comedy"
      ],
      "id": "7694335322922044703",
      "is_nsfw": null,
      "is_pinned": null,
      "is_sponsored": null,
      "language": "en",
      "media": [
        {
          "alt_text": null,
          "duration_ms": 30000,
          "expires_at": null,
          "height": 1280,
          "thumbnail_url": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/osAHzWAIipBAxVMie5CIDqxK0ArEREAAEKVSfn~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
          "type": "video",
          "url": null,
          "width": 720
        }
      ],
      "mentions": [],
      "metrics": {
        "comment_count": 12600,
        "like_count": 690100,
        "quote_count": null,
        "repost_count": null,
        "save_count": 40145,
        "share_count": 20800,
        "view_count": 6900000
      },
      "platform": "tiktok",
      "platform_specific": {
        "tiktok": {
          "author_sec_uid": "MS4wLjABAAAAwAg0rSzO65WQfz4RzQgGv2Xdv108BgPXhRrrmNVIHQZ9PO8-flwwRtEppYTS0OjA",
          "country_code": null,
          "is_ad": false,
          "is_ai_generated": true,
          "location": null,
          "music": {
            "author_name": "Khabane lame",
            "cover_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
            "duration_ms": 30000,
            "id": "7694335437137087262",
            "is_original": true,
            "play_url": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-useast8-v-27dcd7-tx2/o4fHr3qIArT5AEXEiCLVExDGAeqCAIOVe4joPR/?a=1988&bti=ODszNWYuMDE6&&bt=125&ft=GcAInInz7Th~v-RGXq8Zmo&mime_type=audio_mpeg&rc=M3lzeG45cm92ZTMzaTU8NEBpM3lzeG45cm92ZTMzaTU8NEBzNGtiMmRjXjBhLS1kMTJzYSNzNGti…",
            "title": "original sound"
          }
        }
      },
      "platform_type": "video",
      "published_at": "2026-10-08T16:31:16Z",
      "text": "Was the ball out, or was it just my imagination? 🤨#learnfromkhaby #comedy",
      "thumbnail_url": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/osAHzWAIipBAxVMie5CIDqxK0ArEREAAEKVSfn~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
      "title": null,
      "type": "video",
      "unknown_fields": [],
      "url": "https://www.tiktok.com/@khaby.lame/video/7694335322922044703"
    },
    {
      "approximate_fields": [
        "metrics.view_count",
        "metrics.like_count",
        "metrics.share_count"
      ],
      "author": {
        "avatar_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
        "display_name": "Khabane lame",
        "id": "127905465618821121",
        "is_verified": true,
        "url": "https://www.tiktok.com/@khaby.lame",
        "username": "khaby.lame"
      },
      "coauthors": [],
      "duration_ms": 34000,
      "hashtags": [
        "learnfromkhaby",
        "comedy"
      ],
      "id": "7691740195418377502",
      "is_nsfw": null,
      "is_pinned": null,
      "is_sponsored": null,
      "language": "en",
      "media": [
        {
          "alt_text": null,
          "duration_ms": 34000,
          "expires_at": null,
          "height": 1280,
          "thumbnail_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/o0jRDQRMAbfFAlZX8eqGQcARBqerRfAHR7gVSU~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
          "type": "video",
          "url": null,
          "width": 720
        }
      ],
      "mentions": [],
      "metrics": {
        "comment_count": 7325,
        "like_count": 418500,
        "quote_count": null,
        "repost_count": null,
        "save_count": 20087,
        "share_count": 23900,
        "view_count": 5000000
      },
      "platform": "tiktok",
      "platform_specific": {
        "tiktok": {
          "author_sec_uid": "MS4wLjABAAAAwAg0rSzO65WQfz4RzQgGv2Xdv108BgPXhRrrmNVIHQZ9PO8-flwwRtEppYTS0OjA",
          "country_code": null,
          "is_ad": false,
          "is_ai_generated": true,
          "location": null,
          "music": {
            "author_name": "Khabane lame",
            "cover_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=9640&refresh_token=07918010&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast5",
            "duration_ms": 34000,
            "id": "7691740326570019615",
            "is_original": true,
            "play_url": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-useast8-v-27dcd7-tx2/ogcDFBGWoU0A8F0eIAAREf8XVjvDqICFsEDJAo/?a=1988&bti=ODszNWYuMDE6&&bt=125&ft=GcAInInz7Th~v-RGXq8Zmo&mime_type=audio_mpeg&rc=M3hmanQ5cjg7ZDMzaTU8NEBpM3hmanQ5cjg7ZDMzaTU8NEBjMGgyMmRzbnNhLS1kMTJzYSNjMGgy…",
            "title": "original sound"
          }
        }
      },
      "platform_type": "video",
      "published_at": "2026-10-01T16:40:54Z",
      "text": "Just give me 5 more minutes 😭#learnfromkhaby #comedy",
      "thumbnail_url": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/o0jRDQRMAbfFAlZX8eqGQcARBqerRfAHR7gVSU~tplv-tiktokx-origin.image?dr=9636&x-expires=4070908800&x-signature=SCRUBBED&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
      "title": null,
      "type": "video",
      "unknown_fields": [],
      "url": "https://www.tiktok.com/@khaby.lame/video/7691740195418377502"
    }
  ],
  "page": {
    "has_more": true,
    "next_cursor": "c1.EXAMPLE_CURSOR",
    "next_cursor_expires_at": "2026-10-26T12:00:00Z",
    "end_reason": null
  },
  "meta": {
    "request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
    "platform": "tiktok",
    "source": "api",
    "is_cached": false,
    "credits_charged": 1,
    "latency_ms": 0,
    "fetched_at": "2026-10-25T12:00:00Z",
    "input": {
      "kind": "profile",
      "id": "127905465618821121",
      "url": "https://www.tiktok.com/@khaby.lame"
    },
    "credits_remaining": 9999,
    "client_request_id": null,
    "warnings": [],
    "mode": "live"
  }
}
```

Long arrays and strings are shortened for display; real responses are complete.

> [!NOTE]
>
> **Good to know**
>
> - Large play, like, comment and share counts are rounded by TikTok (see approximate_fields).
> - media\[\].url is null for videos: TikTok serves video files only with its player's cookie.
> - If TikTok's list is down, the first page lists the latest posts from its embed profile, with fewer fields.

Pricing

## Pay per page. Only when it succeeds.

| Source | Price per successful page | Per 1,000 pages |
| --- | --- | --- |
| Any source | 1 credit | $0.75–$1.45 |

- Failed requests are free: errors cost 0 credits.
- Cache hits are free: responses served from the cache cost 0 credits.
- Credits never expire.
- One credit balance for every endpoint and platform.

[Credit packs](https://staging.socialtap.dev/pricing/index.md) · [How this endpoint is priced](https://staging.socialtap.dev/docs/reference/tiktok/posts/index.md#pricing) · [How credits work](https://staging.socialtap.dev/docs/credits/index.md)

FAQ

## Questions, answered.

**How much does the TikTok Posts API cost?**

1 credit per page of up to 15 items, charged for every successful page, empty pages included. SocialTap credits cost $0.75–$1.45 per 1,000 depending on the pack.

**How do I get the next page?**

Repeat the same request with cursor set to page.next_cursor from the previous response, keeping the other parameters. When page.has_more is false there are no more items. Cursors expire after 24 hours.

**Am I charged for failed requests?**

No. Requests that return an error cost 0 credits. Responses served from the cache are free too.

Same schema, other platforms

## Posts everywhere. One parser.

[Instagram Post APIBetaPost`GET /v1/instagram/post`1 credit](https://staging.socialtap.dev/apis/instagram/post/index.md) · [TikTok Post APIBetaPost`GET /v1/tiktok/post`1 credit](https://staging.socialtap.dev/apis/tiktok/post/index.md) · [YouTube Video APIBetaPost`GET /v1/youtube/post`1 credit](https://staging.socialtap.dev/apis/youtube/post/index.md) · [YouTube Channel Videos APIBetaPost`GET /v1/youtube/posts`1 credit / page](https://staging.socialtap.dev/apis/youtube/posts/index.md)

More TikTok

## TikTok API. 5 endpoints, one key.

[TikTok Comments APIBetaComment`GET /v1/tiktok/comments`1 credit / page](https://staging.socialtap.dev/apis/tiktok/comments/index.md) · [TikTok Post APIBetaPost`GET /v1/tiktok/post`1 credit](https://staging.socialtap.dev/apis/tiktok/post/index.md) · [TikTok Profile APIBetaProfile`GET /v1/tiktok/profile`1 credit](https://staging.socialtap.dev/apis/tiktok/profile/index.md) · [TikTok Transcript APIBetaTranscript`GET /v1/tiktok/transcript`From 1 credit](https://staging.socialtap.dev/apis/tiktok/transcript/index.md)

## Start with 100 free credits. No card required.

Test keys answer every endpoint from recorded responses, free, so you can build before you spend. Failed requests are always free.

[Get your API key](https://staging.socialtap.dev/signup/?next=%2Fplayground%2F%3Fendpoint%3Dtiktok.posts) · [Read the API reference](https://staging.socialtap.dev/docs/reference/tiktok/posts/index.md)

---

[HTML version](https://staging.socialtap.dev/apis/tiktok/posts/) · [Docs index for AI agents](https://staging.socialtap.dev/llms.txt) · [All docs in one file](https://staging.socialtap.dev/llms-full.txt)
