Micro-Influencer Discovery on TikTok: 10K-100K Creators

Published on May 29, 2026

Mega-influencers are easy to find and hard to afford. Their engagement is also frequently underwhelming: when an account passes a few million followers, the audience becomes too broad, too passive, and too sceptical of sponsored content. Micro-influencers, generally defined as creators in the 10,000-100,000 follower range, consistently post higher engagement rates, command lower per-post fees, and feel more like a friend's recommendation than a billboard. For a marketing team, that means better ROI per dollar - if you can actually find them.

That "if" is the entire problem. TikTok's native search is built for entertainment discovery, not influencer sourcing. You cannot filter by follower tier, you cannot sort by engagement rate, and you cannot export anything. This post walks through a complete programmatic discovery workflow using the TikLiveAPI endpoints: from a niche keyword to a ranked CSV your outreach team can work through on Monday morning.

What "micro-influencer" actually means

The follower tiers used across the industry are not standardized, but the most common definition looks like this:

  • Nano: 1K-10K followers - very high engagement, very local reach
  • Micro: 10K-100K followers - high engagement, niche authority
  • Mid-tier: 100K-500K followers
  • Macro: 500K-1M followers
  • Mega: 1M+ followers

Micro-influencers are the sweet spot for most performance campaigns because they cover a specific topic (fitness for new moms, sourdough baking, indie skincare) with an audience that actually believes them. They are also a discovery nightmare without tooling: you cannot just open TikTok and scroll past 200 mega-creators to find them.

The data signals that matter

Before you write a single line of code, agree on the signals your shortlist will be scored against. Five usually cover it:

  • Follower tier (10,000 ≤ followerCount ≤ 100,000)
  • Engagement rate over the last 10-20 posts
  • Posting cadence (active in the last 14 days, ideally 3+ posts per week)
  • Niche fit (keywords in bio signature and recent post titles)
  • Region (creator's market, in your shipping or campaign country)

Each of these maps cleanly to a field in the TikTok API response. We will pull them in steps.

Step 1: Seed your niche

You need a starting pool of posts that are clearly on-topic. Two endpoints work well as seeds: /challenge-posts/ when you have a strong hashtag, and /search-video/ when you want a broader keyword sweep with sort filters.

The hashtag route is usually higher-precision. Combine it with a region filter if you only care about one market.

import requests

API_KEY = "YOUR_API_KEY"
BASE = "https://api.tikliveapi.com"
HEADERS = {"X-Api-Key": API_KEY}

def search_videos(keyword, count=35, region=None, publish_time=30, sort_by=0):
    """Seed candidates with keyword search. publish_time=30 = last month."""
    params = {
        "keyword": keyword,
        "count": count,
        "publish_time": publish_time,
        "sort_by": sort_by,
    }
    if region:
        params["region"] = region
    r = requests.get(f"{BASE}/search-video/", headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()

def challenge_posts(challenge_id, count=35, region=None):
    """Seed candidates from a specific hashtag (challenge_id)."""
    params = {"challenge_id": challenge_id, "count": count}
    if region:
        params["region"] = region
    r = requests.get(f"{BASE}/challenge-posts/", headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()

If you only know the hashtag text (say, cleanbeauty) and not its numeric ID, look it up first via /challenge-info-name/, then pass the returned id into /challenge-posts/.

Step 2: Extract candidate creators

Each seed response returns a videos array (along with cursor and hasMore for pagination). Every video item carries an author object - that is your candidate. Deduplicate aggressively because popular hashtags surface the same creators many times.

def collect_candidates(seed_response, candidates):
    for v in seed_response.get("videos", []):
        author = v.get("author") or {}
        uid = author.get("id") or author.get("uid")
        if not uid:
            continue
        if uid not in candidates:
            candidates[uid] = {
                "userid": uid,
                "username": author.get("unique_id") or author.get("uniqueId"),
                "nickname": author.get("nickname"),
                "seed_posts": [],
            }
        candidates[uid]["seed_posts"].append(v.get("aweme_id"))
    return candidates

# Page through a hashtag
candidates = {}
resp = challenge_posts("7164308107226054661", count=35, region="US")
collect_candidates(resp, candidates)
while resp.get("hasMore") and len(candidates) < 500:
    resp = requests.get(
        f"{BASE}/challenge-posts/",
        headers=HEADERS,
        params={"challenge_id": "7164308107226054661", "count": 35,
                "cursor": resp.get("cursor"), "region": "US"},
        timeout=30,
    ).json()
    collect_candidates(resp, candidates)

500 candidates from a single hashtag is usually plenty; if you need more, run the same flow against 3-5 related hashtags and merge the dictionaries.

Step 3: Filter by follower tier

Now hydrate each candidate with their profile so you can apply the 10K-100K filter. Use /userinfo-by-username/ when you have the handle, or /userinfo-by-id/ when you only have the numeric ID.

The response contains a user object and a stats object, both using camelCase. stats.followerCount is the field you want.

def userinfo(username):
    r = requests.get(
        f"{BASE}/userinfo-by-username/",
        headers=HEADERS,
        params={"username": username},
        timeout=30,
    )
    r.raise_for_status()
    return r.json()

def in_tier(profile, low=10_000, high=100_000):
    stats = profile.get("stats") or {}
    fc = stats.get("followerCount", 0)
    return low <= fc <= high

tier_filtered = {}
for uid, c in candidates.items():
    if not c["username"]:
        continue
    try:
        p = userinfo(c["username"])
    except requests.HTTPError:
        continue
    if in_tier(p):
        c["profile"] = p
        c["followers"] = p["stats"]["followerCount"]
        c["verified"] = p["user"].get("verified", False)
        c["signature"] = p["user"].get("signature", "")
        tier_filtered[uid] = c

A single seed batch of 500 candidates typically drops to 60-120 micro-tier accounts after this filter, which is exactly what you want.

Step 4: Compute engagement rate per creator

Follower count alone is meaningless - a 50K account with 200 views per post is dead weight. Pull each creator's recent posts via /user-posts/ and compute a median engagement rate.

Note the casing quirk: the top-level pagination flag is hasMore (camelCase), but inside each video the fields are snake_case - play_count, digg_count, comment_count, share_count.

import statistics

def recent_posts(userid, count=20):
    r = requests.get(
        f"{BASE}/user-posts/",
        headers=HEADERS,
        params={"userid": userid, "count": count},
        timeout=30,
    )
    r.raise_for_status()
    return r.json().get("videos", [])

def engagement_rate(videos):
    rates = []
    for v in videos:
        plays = v.get("play_count") or 0
        if plays < 500:        # too few plays to be statistically useful
            continue
        engagements = (v.get("digg_count") or 0) + \
                      (v.get("comment_count") or 0) + \
                      (v.get("share_count") or 0)
        rates.append(engagements / plays)
    if not rates:
        return 0.0, 0
    return statistics.median(rates), len(rates)

for uid, c in tier_filtered.items():
    videos = recent_posts(uid, count=20)
    er, n = engagement_rate(videos)
    c["engagement_rate"] = er
    c["posts_sampled"] = n
    c["recent_videos"] = videos[:5]
    # cadence: are they posting recently?
    import time
    cutoff = time.time() - 14 * 86400
    c["recent_count_14d"] = sum(1 for v in videos if (v.get("create_time") or 0) >= cutoff)

Industry benchmarks for TikTok micro-creators tend to sit between 5% and 12% engagement. A creator at 0.5% is probably running a bot-padded follower count; a creator at 25% is either genuinely viral or has a tiny play base that is gaming the ratio. Keep both extremes in mind during review.

Step 5: Niche fit scoring

A 50K creator with 8% engagement is only useful to you if they actually talk about your category. Score each candidate by counting how many of your niche keywords show up in their bio (user.signature) and in recent post titles.

NICHE_TERMS = [
    "skincare", "skin care", "skinroutine", "glowup",
    "cleanbeauty", "sensitiveskin", "acne", "moisturizer",
]

def niche_score(signature, videos, terms):
    blob_parts = [signature or ""]
    for v in videos:
        if v.get("title"):
            blob_parts.append(v["title"])
    blob = " ".join(blob_parts).lower()
    hits = sum(1 for t in terms if t.lower() in blob)
    return hits

for c in tier_filtered.values():
    c["niche_score"] = niche_score(
        c.get("signature", ""),
        c.get("recent_videos", []),
        NICHE_TERMS,
    )

You can refine this with weighted keywords (brand names worth 3, generic category terms worth 1) or with embedding similarity if you already have an NLP pipeline. For most brand teams, a plain keyword count is enough to separate "yes" from "maybe" from "no".

Step 6: Region filter

Two regions to check: the creator's declared region on their profile, and the regions appearing on their recent posts. Each post item carries a region field, and the user object often carries one too.

TARGET_REGIONS = {"US", "CA", "GB"}

def passes_region(c, allowed):
    user_region = (c.get("profile", {}).get("user", {}) or {}).get("region")
    if user_region in allowed:
        return True
    # Fall back to majority region in their recent uploads
    regions = [v.get("region") for v in c.get("recent_videos", []) if v.get("region")]
    if regions and max(set(regions), key=regions.count) in allowed:
        return True
    return False

geo_filtered = {uid: c for uid, c in tier_filtered.items()
                if passes_region(c, TARGET_REGIONS)}

If you need a definitive country list, hit /region-list/ once and cache it; the response is a dictionary keyed by ISO 3166-1 alpha-2 codes (uppercase).

Step 7: Output a ranked CSV

Combine the signals into a simple weighted score and write the result somewhere your outreach team can open in a spreadsheet.

import csv

def final_score(c):
    er = c.get("engagement_rate", 0) * 100        # to percent
    niche = c.get("niche_score", 0)
    cadence = min(c.get("recent_count_14d", 0), 10)
    return round(er * 5 + niche * 4 + cadence * 2, 2)

ranked = sorted(geo_filtered.values(), key=final_score, reverse=True)

with open("micro_influencers.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow([
        "username", "nickname", "followers", "verified",
        "engagement_rate_pct", "niche_score", "posts_14d",
        "score", "sample_post_1", "sample_post_2", "signature",
    ])
    for c in ranked[:200]:
        samples = [v.get("aweme_id") for v in c.get("recent_videos", [])][:2]
        w.writerow([
            c.get("username"),
            c.get("nickname"),
            c.get("followers"),
            c.get("verified"),
            round(c.get("engagement_rate", 0) * 100, 2),
            c.get("niche_score"),
            c.get("recent_count_14d"),
            final_score(c),
            samples[0] if samples else "",
            samples[1] if len(samples) > 1 else "",
            (c.get("signature") or "").replace("\n", " "),
        ])

A 200-row CSV ranked by score is a manageable Monday-morning task list for a single campaign manager: the top 30 get warm outreach, the next 50 go into a longer-term nurture list, and the rest stay in the database for the next campaign.

Step 8: Avoiding bot accounts

Inflated follower counts are the single biggest waste of micro-influencer budget. Even a clean engagement rate can be misleading if a creator bought a large block of followers six months ago and now posts to a real (but smaller) audience. Before you spend a dollar, run each shortlisted creator through a quick fake-follower audit: pull a follower sample via /user-followers/, then check the proportion of accounts with zero posts, default avatars, or completion ratios that look algorithmic. We walked through the full method in Detect Fake TikTok Followers Programmatically - run it on your top 50 candidates before outreach.

Outreach workflow

Once you have the CSV:

  • Enrich contact info. A creator's TikTok bio almost always links to Instagram, a Linktree, or a business email. Visit each profile, paste the contact into your CRM.
  • Send a personal first message. Reference a specific recent post by aweme_id from the CSV. Generic "we love your content" pitches get ignored.
  • Quote real numbers. "Your last 20 posts averaged 7.2% engagement" is a powerful opener and lets you anchor pricing.
  • Run a tiered offer. Free product for nano/lower-micro, paid + product for upper-micro, paid + usage rights for the strongest performers.
  • Track results back into the same database. The creators who deliver on campaign one become your priority list for campaign two.

Compliance reminder

Programmatic discovery does not exempt you from the rules. A short checklist:

  • Consent before contact. Cold outreach to a publicly listed business email is fine in most jurisdictions; scraping personal email addresses out of bios and adding them to a bulk marketing list is not.
  • FTC disclosure. US creators must clearly tag paid partnerships - #ad, #sponsored, or TikTok's built-in branded content toggle. Build this into the contract, not into a verbal request.
  • GDPR for EU creators. If your CSV ends up storing personal data about an EU citizen (name + contact + behavioural metrics), you have a legitimate interest basis for processing, but you must also be ready to delete on request and to disclose your processing in a privacy notice.
  • Platform terms. TikLiveAPI returns only publicly available data, but your downstream use still needs to respect TikTok's platform terms and any local advertising codes.

Talk to legal once, document the workflow, and your team can reuse the same compliance template across every campaign.

FAQ

How many credits does a full discovery run cost?

For a 500-candidate seed funnel that ends with 200 ranked micro-influencers, expect roughly 500-700 credits: 5-10 hashtag pages, 500 /userinfo-by-username/ calls, and 100-150 /user-posts/ calls on the tier-passing accounts. At pay-as-you-go pricing that is a one-time cost per campaign, and the CSV is reusable.

Can I discover by sound instead of hashtag?

Yes. If a specific song is trending in your category, call /music-posts/ with its music_id as the seed instead of /challenge-posts/. The downstream pipeline (Steps 2 through 8) is identical because both endpoints return the same videos shape with an author object per item.

What if my niche is too small to fill 200 slots?

Use 3-5 adjacent hashtags as parallel seeds, lower the engagement-rate floor (to 3% instead of 5%), and consider widening the tier to 5K-150K. You can also pull related creators via /user-following/ from your strongest matches - micro-influencers in a niche tend to follow each other.

How fresh is the data?

Profile stats and recent posts are pulled live on each request, so engagement numbers reflect the creator's state at query time. Re-run the pipeline before each campaign launch rather than relying on a stale CSV from three months ago - micro-creators can double or halve their follower count quickly.

Can I test the workflow before committing?

Yes. Register on tikliveapi.com, verify your email, and you get 100 free credits - enough to seed a small hashtag, hydrate 20 profiles, and confirm the end-to-end flow returns what you expect. From there you can try a full run on the playground before wiring it into your stack, or jump straight into the users documentation and posts documentation to plan the pipeline. Questions during integration? Contact support and you will hear back within one business day.

Build with the TikTok API

Ready to put what you read into code? Try our endpoints live or grab the full reference.

Open Playground Read Documentation