TikTok
TikTok profiles, videos, social graph, locations, music charts, comments, and replies without the Research API.
Openhandle reads public TikTok profiles, videos, followers, liked posts, comments, hashtags, locations, music, search results, and trending feeds with an API key. No Research API application or institutional requirements are needed.
Endpoints
| Operation | Endpoint |
|---|---|
| Get a profile | GET /v1/tiktok/profiles/{identifier} |
| List profile videos | GET /v1/tiktok/profiles/{identifier}/posts |
| List liked posts | GET /v1/tiktok/profiles/{identifier}/liked-posts |
| List followers | GET /v1/tiktok/profiles/{identifier}/followers |
| List following | GET /v1/tiktok/profiles/{identifier}/following |
| List profile music | GET /v1/tiktok/profiles/{identifier}/music |
| List playlist posts | GET /v1/tiktok/profiles/{identifier}/playlists/{playlistId}/posts |
| Get a video | GET /v1/tiktok/posts/{identifier} |
| List comments | GET /v1/tiktok/posts/{identifier}/comments |
| List replies to a comment | GET /v1/tiktok/posts/{identifier}/comments/{commentId}/replies |
| Search profiles | GET /v1/tiktok/search/profiles?q={query} |
| Search posts | GET /v1/tiktok/search/posts?q={query} |
| Search hashtags | GET /v1/tiktok/search/hashtags?q={query} |
| Search locations | GET /v1/tiktok/search/locations?q={query} |
| Search music | GET /v1/tiktok/search/music?q={query} |
| Get a hashtag | GET /v1/tiktok/hashtags/{identifier} |
| List hashtag posts | GET /v1/tiktok/hashtags/{identifier}/posts |
| Get a location | GET /v1/tiktok/locations/{id} |
| List location posts | GET /v1/tiktok/locations/{id}/posts |
| Get music | GET /v1/tiktok/music/{id} |
| List music posts | GET /v1/tiktok/music/{id}/posts |
| List effect posts | GET /v1/tiktok/effects/{id}/posts |
| List trending categories | GET /v1/tiktok/trending/categories |
| List trending music | GET /v1/tiktok/trending/music |
| List trending posts | GET /v1/tiktok/trending/posts |
The complete 28-operation surface also covers liked posts, effects, and playlists. Every operation has a generated API reference page.
All endpoints accept the freshness
parameter. Paginated list endpoints use
cursors.
Each operation and locator has a generated API reference with a working Test request before its Live request.
Identifiers
Use @tiktok for a username or place the stable platform ID directly in the
same path. Both work on every profile path, including /posts. Video lookups
use the platform video ID. Convert public URLs locally or with the
URL resolver.
Handles change; platform IDs do not. Openhandle resolves both through its
durable identity index. If you store references
long-term, store the id from the response and use it for later lookups.
Test example
curl "https://api.openhandle.dev/v1/tiktok/profiles/@pixel_orchard_tt_test/posts?freshness=24h" \
-H "Authorization: Bearer $OPENHANDLE_TEST_KEY"Expected: HTTP 200, Openhandle-Environment: test, and
Openhandle-Cost: 0.000. Find other documented inputs in the
Test Data catalog.
Live example
curl "https://api.openhandle.dev/v1/tiktok/profiles/@$REAL_TIKTOK_USERNAME/posts?freshness=7d" \
-H "Authorization: Bearer $OPENHANDLE_LIVE_KEY"Rich response data
TikTokProfile adds verification type and label, professional-account status,
and commerce availability when TokAPI supplies them. TikTokPost returns the
author and music nodes, commercial-music status, AI-generated-content label,
all public media renditions with semantic roles and watermark flags, and the
platform's download metric in addition to the shared post metrics.
Effects and playlists have dedicated typed schemas rather than generic entity payloads.
Media
Every media file uses a type made for its kind. A type only carries the keys TikTok can fill for that kind, so a cover image never lists codec or subtitle keys.
| Type | Where it appears | Own keys |
|---|---|---|
TikTokMedia | media[] on a post | type (video or image), duration, hasWatermark, qualityLabel, renditions, covers, subtitles, previewThumbnails |
TikTokImage | cover, avatar, icon, covers[], images[], comment media[], sticker renditions[] | role, label, renditions |
TikTokRendition | renditions[] on a video, a photo, or a sound | role, label, bitrate, frameRate, isBytevc1, codecCode, qualityLabel, qualityCode |
TikTokSubtitle | subtitles[] on a video | format, language, locale, isAutoGenerated, isOriginal, version, expiresAt |
TikTokAudio | audio on a music entry | volumeInfo, renditions |
All five share id, url, size, hash, and urls. Pictures, videos, and
renditions also share width and height.
urlis the preferred address.urlslists every mirror of the same file, starting withurl.renditionsare other encodings, sizes, or crops of the same content. Each has aroleor alabel.- Video rendition roles:
playback,h264,bytevc1,download,downloadWithoutWatermark,adaptive, anddownloadVariant. - Photo rendition roles:
thumbnail,ownerWatermark, anduserWatermark. - Cover roles:
cover,original,dynamic,animated,aiDynamic, andaiDynamicBackup. - Avatar rendition labels:
larger,300x300,168x168,medium, andthumb.
{
"id": "v15044gf0000dag32mfog65losoj38ig",
"type": "video",
"url": "https://media.openhandle.dev/…",
"width": 720,
"height": 1280,
"duration": 68.986,
"hasWatermark": true,
"urls": ["https://media.openhandle.dev/…", "https://media.openhandle.dev/…"],
"renditions": [{ "role": "playback", "url": "https://media.openhandle.dev/…", "width": 720, "height": 1280 }],
"covers": [{ "role": "cover", "url": "https://media.openhandle.dev/…", "width": 720, "height": 720 }],
"subtitles": [{ "language": "en", "format": "webvtt", "url": "https://media.openhandle.dev/…" }]
}Changed in contract 1.2.1
Contract 1.2.0 and earlier used one TikTokAsset type for every file. It
carried every key of every kind, so most keys were null on every record.
Contract 1.2.1 replaces it with the types above. Update readers as follows:
| Before (1.2.0) | After (1.2.1) |
|---|---|
variants[].url on any file | urls[] |
avatar.variants[] with label | avatar.renditions[] with label and urls |
type on a cover, avatar, icon, or product image | Removed. The field name says what it is. type stays on post media[]. |
previewThumbnails[].images[].url | previewThumbnails[].urls[] |
beatData.variants[] | beatData.urls[] |
Video-only keys on a picture, such as bitrate or subtitles | Not present |
The SDKs expose the new types under the same names from version 1.2.1.
Honest limits
- Private profiles return
PROFILE_PRIVATE(HTTP 403). We do not access private content. The definitive answer is billable. - TikTok
viewscount loops. See metric semantics before comparing across platforms. - Media URLs are proxied through
media.openhandle.devso they stay stable while you process them. - Search returns what TikTok returns. Profile, post, and hashtag search match loosely, so a query with no real match can still return unrelated results.