TikTok · Instagram · YouTube · X
Paste any post or profile URL, get the same normalized JSON back — every engagement number each platform exposes, deleted content as a real 404, and the cost attributed to the key that asked. Your bots just ask for numbers.
curl "https://tikdata.io/v1/post?url=https://www.tiktok.com/@tiktok/video/7680721699171601694" \
-H "Authorization: Bearer thr_live_xxx"{
"platform": "tiktok",
"id": "7680721699171601694",
"caption": "this summer was all about the classic hits…",
"createdAt": "2026-09-02T00:03:08.000Z",
"author": {
"handle": "tiktok",
"name": "TikTok",
"followers": 95663434
},
"stats": {
"views": 202473,
"likes": 8267,
"comments": 1261,
"shares": 631,
"saves": 922,
"reposts": 0,
"quotes": 0,
"downloads": 40
}
}Coverage
Eight engagement numbers under one set of names. Where a platform doesn't expose one, the field is present and 0 — never missing, never an exception. Each cell is the upstream field it was read from, verified against a live response.
On X a repost is the share mechanism, so shares and reposts carry the same number there by design — summing shares across platforms gives you a comparable figure instead of a zero.
| stat | TikTok | YouTube | X | |
|---|---|---|---|---|
| views | play_count | play_count | view_count | views |
| likes | digg_count | like_count | like_count | likes |
| comments | comment_count | comment_count | comment_count | replies |
| shares | share_count | share_count | — | retweets |
| saves | collect_count | save_count | — | bookmarks |
| reposts | repost_count | repost_count | — | retweets |
| quotes | — | — | — | quotes |
| downloads | download_count | — | — | — |
| followers | follower_count | via /v1/profile | subscriber_count | sub_count |
Why route through it
A leaked credential, no attribution, no shared pacing, and the same normalization code copied into each project. One gateway retires all four.
The same JSON whether the URL is a TikTok video, a Reel, a Short or a post on X. Field archaeology — X's sub_count, Instagram's edge_* wrappers, YouTube's “4.54M subscribers” strings — happens here, once.
Consumers hold a thr_live_ key that only this gateway understands. Revoke one without rotating anything else, and never ship the upstream account key to a bot again.
Every call is counted against the key that made it, then priced at read time against the provider's progressive account-wide discount tiers — so the number matches the bill, not a snapshot.
Outbound calls are held under the plan's 100 req/s by a sliding window. Batch 500 URLs in one request and the fan-out is paced for you; one dead id never sinks the rest.
Detail that matters
Upstream answers HTTP 200 for a dead video id and simply omits the post object. Read that naively and a removed post looks like a real crash to 0 views — which, if the numbers feed view tracking, is a payout dispute waiting to happen.
TikData checks for the post explicitly and answers 404. Same for creators: X and Instagram return 200 with an invented "not found" body for accounts that don't exist, and both become 404 here — so a renamed creator never reads as one who lost their whole audience.
HTTP/1.1 200 OK
{ "code": 200, "data": {} }
→ looks like: 0 views, 0 likesHTTP/1.1 404 Not Found
{ "error": "post not found",
"platform": "tiktok",
"id": "9999999999999999999" }Endpoints
| GET | /v1/post | One post, every stat, platform detected from the URL. |
| POST | /v1/posts | Up to 500 URLs, fanned out server-side, per-item ok. |
| POST | /v1/videos/bulk_stats | Up to 100 videos by id or url, one flat row each, typed errors. |
| GET | /v1/profile | The creator — followers, bio, verified, post count. |
| GET | /v1/creator/stats | Followers plus everything published in the last N days. |
| ANY | /v1/raw/{path} | Verbatim pass-through; a two-line migration for existing bots. |
| GET | /v1/whoami | Which key and project am I. |
| GET | /v1/usage | This key's calls and cost today, priced live. |
| GET | /v1/account | The provider's live account meter (admin). |
| ADMIN | /v1/keys | Mint, list, disable, delete. |
Already calling the provider directly? Point your base URL at /v1/raw and swap the key. Existing call sites keep working unchanged.
Three steps
One per consumer, so spend is attributable and any one project can be cut off on its own.
curl -X POST "https://tikdata.io/v1/keys" \
-H "x-admin-token: $INGEST_TOKEN" \
-H "content-type: application/json" \
-d '{"label":"my bot","project":"my-bot"}'whoami echoes the key and project — the health check when wiring a new consumer.
curl "https://tikdata.io/v1/whoami" \
-H "Authorization: Bearer thr_live_xxx"One URL or five hundred. Every result carries its own ok, so one bad URL never sinks the request.
curl -X POST "https://tikdata.io/v1/posts" \
-H "Authorization: Bearer thr_live_xxx" \
-H "content-type: application/json" \
-d '{"urls":["https://…","https://…"]}'For agents
/llms.txt indexes the whole reference in the llmstxt.org format, and every docs page is also served as raw Markdown at its .md URL. Same files — one source of truth for people and agents.