vlayervlayer docs
Data lookups

Post metrics

Read a public post's views, likes, comments, shares and saves, its caption and its owner, straight from the post URL.

Counts are read from the platform at the moment you call and never stored, so call again whenever you want newer numbers.

One post

GET/v1/stats?url={postUrl}Data lookup
curl -G {API_BASE_URL}/v1/stats \
  -H "Authorization: Bearer <API_TOKEN>" \
  --data-urlencode "url=https://www.tiktok.com/@creator/video/7300000000000000000"
const params = new URLSearchParams({ url: "https://www.tiktok.com/@creator/video/7300000000000000000" });
const res = await fetch(`${API_BASE_URL}/v1/stats?${params}`, {
  headers: { Authorization: `Bearer ${API_TOKEN}` },
});
const { owner, stats } = await res.json();
{
  "platform": "tiktok",
  "contentType": "video",
  "postUrl": "https://www.tiktok.com/@creator/video/7300000000000000000",
  "owner": {
    "handle": "creator",
    "accountId": "7198363676607530026",
    "secUid": "MS4wLjAB...",
    "displayName": "Creator"
  },
  "post": {
    "caption": "New video",
    "postedAt": "2026-09-22T18:30:00.000Z",
    "thumbnailUrl": "https://...",
    "mediaUrls": ["https://..."]
  },
  "stats": {
    "views": 125000,
    "likes": 5432,
    "comments": 312,
    "shares": 89,
    "saves": 144
  },
  "source": "provider"
}
FieldNotes
contentTypepost or reel on Instagram, video on TikTok
postUrlThe cleaned-up post URL, without share tags or other query parameters
owner.accountIdThe platform's id for the account that posted. It stays the same when the handle changes
owner.secUidTikTok only; null on Instagram
post.thumbnailUrl, post.mediaUrlsSigned platform URLs that expire. Download the files promptly if you need to keep them
stats.viewsReels and TikTok videos; null for Instagram image posts
stats.shares, stats.savesAlways null on Instagram, which does not show them publicly
sourceprovider normally; fallback when a second read path answered, see below

Any metric is null when the platform does not expose it, for example when the author hides the like count.

Check ownership with accountId

To confirm a post belongs to a creator, compare owner.accountId with the accountId from their creator profile, not the handle in the URL. A handle can change or be typed wrong; the account id cannot.

Fallback reads

Some Instagram posts, such as age-restricted ones, cannot be read the usual way. The API then tries a second read path and, if that works, answers 200 with source: "fallback". A fallback read carries the views, likes, comments and thumbnail, but owner is all null, caption and postedAt are null, and mediaUrls is empty. Do not use a fallback read for an ownership check.

Up to 25 posts in one call

POST/v1/stats/batchData lookup

Instagram and TikTok URLs can be mixed. Results come back in the order you sent them.

curl -X POST {API_BASE_URL}/v1/stats/batch \
  -H "Authorization: Bearer <API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://www.tiktok.com/@creator/video/7300000000000000000",
      "https://www.instagram.com/p/GONE/"
    ]
  }'
{
  "results": [
    {
      "url": "https://www.tiktok.com/@creator/video/7300000000000000000",
      "ok": true,
      "platform": "tiktok",
      "contentType": "video",
      "postUrl": "https://www.tiktok.com/@creator/video/7300000000000000000",
      "owner": { "handle": "creator", "accountId": "7198363676607530026", "secUid": "MS4wLjAB...", "displayName": "Creator" },
      "post": { "caption": "New video", "postedAt": "2026-09-22T18:30:00.000Z", "thumbnailUrl": "https://...", "mediaUrls": ["https://..."] },
      "stats": { "views": 125000, "likes": 5432, "comments": 312, "shares": 89, "saves": 144 },
      "source": "provider"
    },
    {
      "url": "https://www.instagram.com/p/GONE/",
      "ok": false,
      "error": { "code": "POST_NOT_FOUND", "message": "Post not found" }
    }
  ],
  "summary": { "total": 2, "succeeded": 1, "failed": 1 }
}

Each URL succeeds or fails on its own. A successful result has the same fields as a single lookup, and url is the URL exactly as you sent it. A failed result carries the error code that URL would have returned alone, inside error.code; note that this is an object here, not the plain error string of a single call.

StatusMeaning
200The batch ran. A failed post does not fail the batch, so check ok on every result
422 VALIDATION_ERRORThe body is not { "urls": [...] } with 1 to 25 entries. Nothing was read
429 RATE_LIMITEDThe batch would go past 60 URLs per minute from your client IP. Wait for Retry-After
  • Duplicates. A URL sent twice is read once and returned in both positions.
  • Deadline. A batch stops after 100 seconds. URLs not finished by then come back with BATCH_TIMEOUT; send them again in a new batch.
  • Usage. Each distinct post that succeeds counts as one lookup. Failed and timed-out URLs do not count.

Errors

When the post cannot be read, the single lookup returns one of the data lookup errors. 404 and 422 are permanent for that post; 429, 502 and 503 are worth retrying.

Last updated on