.md raw

POST /v1/videos/bulk_stats

Up to 100 videos per call, platforms mixed freely, identified by id or URL, flattened to one row per video with every engagement stat the platform exposes. One entry out per entry in, in order, each with its own ok, so a single dead id never fails the batch.

Request

curl -X POST "https://tikdata.io/v1/videos/bulk_stats" \
  -H "Authorization: Bearer thr_live_xxx" \
  -H "content-type: application/json" \
  -d '{"videos":[
        {"platform":"tiktok",    "id":  "7680721699171601694"},
        {"platform":"instagram", "id":  "Dc30nJeRKKz"},
        {"platform":"instagram", "url": "https://www.instagram.com/reel/Dc30nJeRKKz/"},
        {"platform":"x",         "id":  "2095890073031966734"},
        {"platform":"youtube",   "id":  "dQw4w9WgXcQ"}
      ]}'
field required notes
videos yes array of 1–100 objects
videos[].platform one of platform or url tiktok | instagram | youtube | x; if omitted, detected from url
videos[].id one of id or url TikTok aweme id, Instagram shortcode, YouTube video id, X tweet id
videos[].url one of id or url any post URL; the id is extracted from it

Instagram accepts a bare shortcode with no URL — the provider's endpoint takes either.

Response — 200

{
  "count": 5,
  "videos": [
    {
      "id": "7680721699171601694",
      "platform": "tiktok",
      "ok": true,
      "views": 202473,
      "likes": 8267,
      "comments": 1261,
      "shares": 631,
      "saves": 922,
      "reposts": 0,
      "quotes": 0,
      "downloads": 40,
      "created_at": "2026-09-02T00:03:08Z",
      "author": "tiktok",
      "cover_url": "https://p16-common-sign.tiktokcdn-us.com/…"
    },
    {
      "id": "Dc30nJeRKKz",
      "platform": "instagram",
      "ok": true,
      "views": 111591938,
      "likes": 871528,
      "comments": 19968,
      "shares": 166102,
      "saves": 28346,
      "reposts": 23535,
      "quotes": 0,
      "downloads": 0,
      "created_at": "2026-09-04T16:32:46Z",
      "author": "instagram",
      "cover_url": "https://scontent-….cdninstagram.com/…"
    },
    { "id": "9999999999999999999", "platform": "tiktok", "ok": false, "error": "invalid_id" }
  ]
}
field type notes
count integer videos.length — always equals the input length
videos[].id string the id used (extracted from url when only that was given)
videos[].platform string
videos[].ok boolean
views likes comments shares saves reposts quotes downloads integer see the platform table in /v1/post; 0 where a platform has no such number
created_at ISO 8601 (seconds) | null
author string bare handle
cover_url string
error string only on ok: false

Error codes

code meaning costs a call?
invalid_id malformed id — TikTok ids encode a creation timestamp, so this is decided offline no
not_found well-formed reference, but the platform returned no post yes
unsupported_platform platform given but not one of the four no
bad_input no usable id or url, or no platform determinable no
upstream_error provider returned a non-2xx we could not classify no (errors are free upstream)
upstream_unreachable timeout or network failure no

There is deliberately no video_private. The provider omits the post object identically whether a video was deleted, made private, or never existed. The signal exists at TikTok itself (statusMsg: "status_self_see" vs "item doesn't exist") but is stripped before it reaches us — verified 2026-09-08 across seven endpoints. Reporting video_private would be inventing information your tracker might act on.

What this saves, and what it does not

It saves 100 round-trips, client-side pacing and per-item error handling — the fan-out happens here, under the router's rate gate. It does not save money: the provider has no working bulk video endpoint to fan into (its four fetch_multi_video* routes are 404, or accept the schema and then 400 — re-verified 2026-09-07), so 100 videos is 100 billable calls either way.

Errors

status body
400 {"error":"body must be JSON","hint":"{\"videos\":[{\"platform\":\"tiktok\",\"id\":\"768...\"}]}"}
400 {"error":"videos[] is required"}
400 {"error":"too many videos","hint":"max 100 per request, got N"}
401 see authentication