API reference
Docs
One authenticated gateway to social post data. Every call is attributed to the key that made it, and the upstream provider key never leaves the server.
Why route through this
- The TikHub key never leaves the server. Consumers hold a router key instead, which can be revoked on its own without rotating anything else.
- Attribution is automatic. Spend is recorded under the key's project with no client-side tracking code to install, forget, or overwrite.
- Pacing is handled here. Outbound calls are held to the plan's 100 rps, so a batch job cannot collect 429s.
- Normalized shapes. One post schema across TikTok, Instagram, YouTube and X instead of per-platform field digging in every project.
Authentication
Send your router key as a bearer token. x-api-key works too.
curl "https://tikdata.io/v1/whoami" \
-H "Authorization: Bearer thr_live_xxxxxxxxxxxx"401 means the key is unknown or disabled. 403 means the key is scoped and the path is outside its scope.
Endpoints
/v1/post?url=...Stats for a single post, normalized. Pass any TikTok, Instagram, YouTube or X post URL — the platform is detected from it. Add &platform= to override detection.
curl "https://tikdata.io/v1/post?url=https://www.tiktok.com/@tiktok/video/7680721699171601694" \
-H "Authorization: Bearer thr_live_xxx"{
"platform": "tiktok",
"id": "7680721699171601694",
"url": "https://www.tiktok.com/@tiktok/video/7680721699171601694",
"caption": "this summer was all about the classic hits...",
"cover": "https://...",
"createdAt": "2026-08-31T12:03:08.000Z",
"author": { "handle": "tiktok", "name": "TikTok", "followers": 95629332 },
"stats": { "views": 137541, "likes": 6320, "comments": 991,
"shares": 436, "saves": 677 }
}Missing stats come back as 0 rather than throwing — platforms omit different fields, and a partial answer beats a failed refresh.
A deleted or unknown post returns 404, never a post with zeroed stats. TikHub answers 200 with the post object omitted in that case, so the router checks for it explicitly — otherwise a removed video would look like a real drop to 0 views.
/v1/postsThe batch form. Up to 500 URLs per request, fanned out server-side at the router's own concurrency and rate limit. One slow post never blocks the rest, and each result carries its own success flag.
curl -X POST "https://tikdata.io/v1/posts" \
-H "Authorization: Bearer thr_live_xxx" \
-H "content-type: application/json" \
-d '{"urls":["https://www.tiktok.com/@a/video/123",
"https://x.com/b/status/456"]}'{
"requested": 2, "succeeded": 2, "failed": 0,
"results": [
{ "url": "...", "ok": true, "post": { ...same shape as /v1/post... } },
{ "url": "...", "ok": false, "error": "upstream 404" }
]
}/v1/raw/{tikhub path}Straight pass-through to TikHub for anything without a custom endpoint. The response is returned verbatim, so adopting the router never blocks you on us adding something first. Query params are forwarded as given.
curl "https://tikdata.io/v1/raw/api/v1/tiktok/app/v3/fetch_one_video?aweme_id=123" \
-H "Authorization: Bearer thr_live_xxx"Billable calls are attributed automatically. Account endpoints under /api/v1/tikhub/user/ are free and are not counted.
/v1/whoamiConfirms which key and project you are calling as. Useful as a health check when wiring a new consumer.
{ "keyId": "rk_ab12cd34", "label": "Market Bubble site",
"project": "market-bubble", "scopes": null,
"requestCount": 10527, "lastUsedAt": "2026-09-07T..." }Managing keys
Admin only. Send the tracker's ingest token as x-admin-token.
# mint a key for a project
curl -X POST "https://tikdata.io/v1/keys" \
-H "x-admin-token: $INGEST_TOKEN" \
-H "content-type: application/json" \
-d '{"label":"Market Bubble site","project":"market-bubble"}'curl "https://tikdata.io/v1/keys" -H "x-admin-token: $INGEST_TOKEN" # list
curl -X PATCH "https://tikdata.io/v1/keys" -H "x-admin-token: $INGEST_TOKEN" \
-H "content-type: application/json" -d '{"id":"rk_x","enabled":false}' # disable
curl -X DELETE "https://tikdata.io/v1/keys?id=rk_x" -H "x-admin-token: $INGEST_TOKEN"The plaintext key is shown once, at creation. Only its SHA-256 hash is stored, so a lost key is replaced rather than recovered. Restrict a key with "scopes":["/api/v1/tiktok/"] to limit which paths it can reach.
Errors
| Status | Meaning |
|---|---|
| 400 | Bad input — missing url, unparseable body, too many urls |
| 401 | Missing, unknown, or disabled key |
| 403 | Key is scoped and this path is outside it |
| 404 | Post is deleted or never existed (not a zeroed result) |
| 502 | TikHub unreachable or returned an error |
Errors are always JSON: {"error": "...", "hint": "..."}
Every call the router forwards is attributed to its key's project and recorded per day, so spend can be broken down without any client-side tracking.