Authentication
Every /v1/* endpoint needs a TikData key. Keys look like thr_live_ followed by 48 hex characters, and each one belongs to exactly one project — that is how spend gets attributed without any client-side tracking code.
Sending the key
Bearer token, on every request:
curl "https://tikdata.io/v1/whoami" \
-H "Authorization: Bearer thr_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
x-api-key is accepted as an alternative header for clients that cannot set Authorization:
curl "https://tikdata.io/v1/whoami" \
-H "x-api-key: thr_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
What a key can do
| consumer key | admin token | |
|---|---|---|
/v1/post, /v1/posts, /v1/videos/bulk_stats |
yes | — |
/v1/profile, /v1/creator/stats |
yes | — |
/v1/raw/* |
yes, within scope | — |
/v1/whoami |
yes | — |
/v1/usage |
own usage only | every key |
/v1/account |
— | yes |
/v1/keys |
— | yes |
The admin token is sent as x-admin-token. It is the deployment's INGEST_TOKEN and is never issued to consumers.
Scopes
A key can be restricted at creation to a set of upstream path prefixes:
{ "label": "clip bot", "project": "clip-bot", "scopes": ["/api/v1/tiktok/", "/api/v1/instagram/"] }
Scopes apply to /v1/raw/*. A scoped key that reaches outside its prefixes gets 403 with the allowed prefixes in the hint. Keys with no scopes can reach any upstream path.
Failure responses
| status | body | meaning |
|---|---|---|
| 401 | {"error":"missing api key","hint":"send: Authorization: Bearer thr_live_..."} |
no key in either header |
| 401 | {"error":"invalid or disabled api key"} |
key unknown, deleted, or enabled: false |
| 403 | {"error":"key is not scoped for this path","hint":"allowed: ..."} |
scoped key, path outside scope |
| 401 | {"error":"admin token required","hint":"send: x-admin-token: <INGEST_TOKEN>"} |
admin endpoint, no or wrong token |
Key hygiene
- The plaintext is shown once, in the
POST /v1/keysresponse. Only its SHA-256 hash is stored, so a lost key is replaced, not recovered. - Disable before deleting when you want to keep the key's usage history attributable:
PATCH /v1/keyswithenabled: falsestops it immediately;DELETEremoves the record. Per-key usage rows survive deletion becauseprojectis denormalized onto them. - Every response from an authenticated endpoint carries
x-router-project: <project>so a caller can confirm which project it is being billed to.