DEV Community

ApiVault Labs
ApiVault Labs

Posted on

How to Check If Your TikTok Videos Are Shadowbanned (and What to Do About It)

You post a video, it does the usual first-hour numbers, and then… nothing. No FYP, no search, no new followers. You didn't get a notification, TikTok didn't tell you anything, but the reach just quietly evaporated. That's what a shadow ban feels like — a soft suppression you're never officially informed about.

The hard part is proving it. "My views dropped" isn't evidence; it could be the algorithm, the topic, or the time of day. What you need is the actual restriction signals on the video itself. That's what our TikTok Shadow Ban Checker reads — and this post explains what a shadow ban actually is, how to check for one, and how to read the result.

What a "shadow ban" really is

There isn't one single switch. TikTok can restrict a video in several ways at once: pull it from the For You feed, hide it from search, force it to private, or disable features like duet, stitch, comments, downloads, or sharing. Any of those quietly caps your reach. So a real check can't rely on one flag — it has to look at all of them.

Historically the giveaway was TikTok's internal indexEnabled property. But throughout 2026 TikTok has been removing that flag from public HTML, which breaks the old single-signal checkers. The reliable approach now is multi-signal.

Multi-signal detection, not one flag

The checker aggregates 15+ signals rather than betting on one:

  • Hard signals: takeDown, secret, privateItem, divertedToPrivate (TikTok forced the video private — a strong ban indicator), isReviewing, forFriend, plus the legacy indexEnabled, forYouEligible, and searchVisible.
  • Soft restrictions: duet disabled, stitch disabled, comments disabled, downloads disabled, sharing disabled.

Because it reads many signals, the verdict survives even when TikTok hides the legacy indexEnabled flag. Each video comes back with a banReasonHints[] list (human-readable, every active restriction spelled out) and a restrictionCount.

The numbers it computes

Beyond raw flags, every video gets scored:

  • videoHealthScore (0–100) — a composite of all ban indicators plus engagement. 80+ healthy, 60–79 slightly restricted, 40–59 restricted, 20–39 heavily restricted, under 20 shadowbanned.
  • videoHealthStatus — the same thing in words (healthyshadowbanned).
  • engagementRate — (likes + comments + shares) / views × 100. Industry benchmark is roughly 3–6%; unusually low engagement (under ~0.5%) can itself signal soft suppression.
  • viralPotentialScore (0–100) — based on view velocity and engagement.

Advice, not just flags

The part that actually helps: every result includes a recommendations[] array in plain English, tied to the signals it found. Instead of a wall of booleans, you get lines like:

🟠 Restricted. Several signals flagged — consider re-uploading.
💬 Comments are disabled. Re-enable them in Privacy settings — engagement loops drive FYP eligibility.
📉 Engagement rate 0.4% is well below average for 50,000 views — possible soft suppression. Hook the first 3 seconds harder.

And when a video is clean:

✅ Video looks healthy. No shadow-ban action needed.
🔥 Engagement rate 4.23% is excellent — keep this format in rotation.

A 30-second check

Paste any number of video URLs (one per line, or the urls array):

{
  "urls": [
    "https://www.tiktok.com/@username/video/1234567890",
    "https://vm.tiktok.com/shortlink"
  ],
  "includeRecommendations": true
}
Enter fullscreen mode Exit fullscreen mode

An abridged result:

{
  "shadowbanned": false,
  "videoHealthScore": 95,
  "videoHealthStatus": "healthy",
  "engagementRate": 4.23,
  "viralPotentialScore": 72,
  "restrictionCount": 0,
  "recommendations": ["✅ Video looks healthy. No shadow-ban action needed."]
}
Enter fullscreen mode Exit fullscreen mode

Check a batch and you also get a summary record — totalChecked, shadowbannedPct, avgHealthScore, avgEngagementRate, and the most common restrictions across the set — so an agency can hand a client one clean health report instead of raw JSON.

Built to survive TikTok's defenses

TikTok actively fights scrapers, so a naive fetch fails constantly. The checker uses a multi-strategy fetcher that tries embed/v2 → embed → desktop UA → mobile UA → m.tiktok.com → Googlebot in sequence, extracts data from the embedded JSON, and falls back to oEmbed metadata if the full HTML fails — so you still get title, author, and thumbnail rather than an empty error. It runs through residential proxies (pin a country with proxyCountry, or bring your own via customProxyUrls).

How people use it

  • Creators — monitor your own videos and catch a restriction early, before you've wasted a week wondering.
  • Agencies — bulk-check a client's recent uploads and generate a health report.
  • Competitor research — see whether a rival's videos are quietly restricted.
  • Automation — wire it into your content workflow via the API, the official n8n community node (n8n-nodes-apivault-tiktok-shadowban), or the Python SDK (check_one(), check_urls()).

At $0.01 per video ($10 per 1,000), auditing a whole content calendar costs pennies.

A note on interpreting results

Shadow-ban detection reads the public signals TikTok exposes, and TikTok changes what it exposes over time. indexEnabled=false is the most reliable single signal because it's TikTok's own internal flag; others (For You eligibility, search visibility) are less consistently present in the HTML. For catch-all situations the checker reports its best signal rather than a false "healthy," so you get an honest read instead of a misleading one. Treat it as strong evidence to act on, not a courtroom verdict.

Bottom line

If your reach dropped and you can't tell whether it's you or the algorithm, stop guessing. TikTok Shadow Ban Checker reads 15+ restriction signals per video, scores each one 0–100, and tells you in plain English what's wrong and what to do next — in bulk, for a cent a video. Check first, then fix.


What signal or recommendation would make your TikTok audits more useful? Tell me and I'll look at adding it.

Top comments (0)