How to vet an influencer programmatically with video transcripts
To vet a creator programmatically, pull their profile and recent posts on each platform, compute engagement against views rather than followers, and run their latest videos through a transcript endpoint so you can search what they actually say. Do not rely on the platform's paid-partnership flag to find past sponsors: it is only set when the creator ticks the label, while spoken sponsor reads show up in the transcript.
The rest of this post is the code, field by field, and the places it goes wrong.
The three calls per platform
For each platform you need a profile, a page of recent posts, and transcripts for a few of those posts:
| Platform | Profile | Recent posts | Transcript |
|---|---|---|---|
| TikTok | /v1/tiktok/channel-details |
/v1/tiktok/channel-posts |
/v1/tiktok/transcript |
/v1/instagram/channel-details |
/v1/instagram/channel-posts |
/v1/instagram/transcript |
|
| YouTube | /v1/youtube/channel-details |
/v1/youtube/channel-videos |
/v1/youtube/transcript |
All of them take a url — the profile URL for the first two columns, a post or video URL for the third.
Pull the data
import os
import re
import statistics
import requests
API = "https://api.captapi.com"
HEADERS = {"Authorization": f"Bearer {os.environ['CAPTAPI_API_KEY']}"}
def get(path, **params):
r = requests.get(API + path, headers=HEADERS, params=params, timeout=180)
if r.status_code >= 400:
return None, r.json().get("error", {})
return r.json()["data"], None
profile, _ = get("/v1/tiktok/channel-details", url="https://www.tiktok.com/@mkbhd")
listing, _ = get("/v1/tiktok/channel-posts", url="https://www.tiktok.com/@mkbhd", limit=10)
posts = listing["posts"]
print(profile["followers"], profile["followersIsApproximate"], profile["postCount"])
Every post row has an engagement object. On TikTok it carries views, likes, comments, shares and saves, each with an ...IsApproximate twin; Instagram Reels carry views, likes and comments; YouTube video rows carry viewCount.
Engagement against views, not followers
The common formula divides likes and comments by follower count. Two problems: followers are often rounded, and a video's audience is not the follower base. YouTube's channel endpoint returns followers: 21400000 with followersIsApproximate: true for a channel shown as "21.4M subscribers" — dividing by that bakes the rounding into your rate. Per-post views are exact far more often, so use them:
def engagement_rate(post):
e = post["engagement"]
if not e.get("views"):
return None # photos and carousels have no view count
return (e.get("likes", 0) + e.get("comments", 0)) / e["views"]
rates = [r for r in (engagement_rate(p) for p in posts) if r is not None]
print("median engagement per view:", round(statistics.median(rates), 4))
Use the median of ten posts rather than the mean; one viral video otherwise dominates the number. Keep the ...IsApproximate flags in whatever you show a client.
Find past sponsors: flags miss what transcripts catch
TikTok and Instagram post rows include isPaidPartnership. It is true only when the creator applied the platform's paid-partnership label. Plenty of sponsored segments are read out loud inside an otherwise normal video and never labelled. The transcript catches those:
SPONSOR_PHRASES = re.compile(
r"\b(sponsored by|thanks to .{0,40} for sponsoring|use (my )?code|"
r"link in (my )?bio|partnered with|in partnership with)\b",
re.I,
)
def sponsor_signals(post, transcript_text):
hits = sorted({m.group(0).lower() for m in SPONSOR_PHRASES.finditer(transcript_text or "")})
return {
"url": post["url"],
"labelled": bool(post.get("isPaidPartnership")),
"spoken": hits,
}
for post in posts[:3]:
transcript, err = get("/v1/tiktok/transcript", url=post["url"])
text = transcript["text"] if transcript else ""
print(sponsor_signals(post, text), err.get("code") if err else "")
For YouTube there is a third source: /v1/youtube/video-sponsors returns sponsor and self-promotion segments that viewers submitted to SponsorBlock, with start and end seconds, vote counts and the data's license (CC BY-NC-SA 4.0) in the response. It is community-reported: treat a segment with few votes as a lead, not a fact.
The same scan in JavaScript, for a list of transcripts you already fetched:
const SPONSOR_PHRASES =
/\b(sponsored by|thanks to .{0,40} for sponsoring|use (my )?code|link in (my )?bio|partnered with|in partnership with)\b/gi;
function sponsorSignals(post, transcriptText = "") {
const spoken = [...new Set([...transcriptText.matchAll(SPONSOR_PHRASES)].map((m) => m[0].toLowerCase()))];
return { url: post.url, labelled: Boolean(post.isPaidPartnership), spoken };
}
The gotchas
No transcript is not "said nothing". Instagram's transcript endpoint transcribes the Reel's audio. A music-only Reel comes back as HTTP 422 with {"code": "VALIDATION_ERROR", "message": "No speech found in this Reel", "retryable": false}. Record that, move to the next Reel, and do not retry it. On-screen text in such videos is invisible to a transcript.
Not every transcript is speech-to-text. TikTok and YouTube transcripts often come from the video's captions — check the response's source (for example "captions"); YouTube also returns isAutoGenerated. Auto-generated captions mishear brand names, so search for the brands you care about with some tolerance (lowercase, no punctuation) and have a person check any hit before it goes in a report.
Small samples lie. Ten posts is enough to see a posting rhythm and a typical engagement level. It is not enough to call an audience "fake". Profile data is public and logged-out only: no audience demographics, no follower-quality score. If a brief needs those, say they are unavailable rather than estimating them.
Restricted accounts are a final answer. An Instagram profile behind a logged-out "Restricted profile" wall returns 403 profile_restricted with retryable: false. Mark the platform as unavailable for that creator; retrying will not change it.
What it costs
On Captapi, profile calls are 1 credit, TikTok channel-posts and YouTube channel-videos are 2, Instagram channel-posts is about 0.3 credits per returned post, TikTok and Instagram transcripts are 2, YouTube transcripts are 1 and video-sponsors is free. Failed calls — including the 422 above — are not billed. Vetting one creator on all three platforms with ten posts and three transcripts each comes to about 25 credits.
Finding creators is a separate problem from vetting them; influencer identification covers the search side. If you want an agent to run the vetting end to end and print the credit estimate first, the flow above is packaged as an agent skill.