Give Ultra Search a brief in plain words and get back a finished creator list. It reads the brief, searches our index, crawls TikTok for creators we don't have yet, and has a model judge every candidate against your brief. Each creator comes back with a tier, a fit score and a one-sentence reason.
What it does
- The same Ultra Search as in the app, with the same checks, the same pipeline and the same list. A search started here shows up in your account's Ultra Search history and in Lists.
- It runs in the background: from a few minutes to a few hours, depending on how much of the niche we need to crawl. You start it, poll its status, then read the list.
- The list keeps the judge's order, best first:
bullseyecreators, thenadjacent, thencraft, then near misses. - Words like "ideally" or "bonus if" in the brief rank creators higher; they never filter anyone out. A number or a contact email is a hard requirement only when the brief says so ("at least", "must").
What it costs
Ultra Search uses no API credits. Each search you start uses one of your plan's monthly Ultra Searches, exactly as in the app, and the count is shared between the app, the API and the MCP server. How many you get depends on your plan; meta.quota always says. A search that stops on our side gives its Ultra Search back. Reading the status and the results is free.
Every response carries meta.quota so you can see what's left:
"quota": {
"unlimited": false,
"remaining": 14,
"monthly_limit": 15,
"bonus": 0,
"period_end": "2026-11-05T00:00:00Z",
"left": "14 of 15 left"
}409 already_running with the newest running search's id.
POST/v1/ultra_searches#
Starts a search. Your brief is read before anything is spent: if it names no topic, or asks for one specific account or link, you get a 422 with suggestions and nothing is used.
Body
| Param | Type | Notes |
|---|---|---|
briefrequired | string | Who you want to find, in plain words, up to 500 characters. Say what they post about and where. |
countries | string[] | Optional. Two-letter country codes the creators must be in, e.g. ["GB", "IE"]. Leave it out and any countries named in the brief are used. |
min_followers | int | Optional. Smallest follower count. Leave it out and a floor stated in the brief is used. |
max_followers | int | Optional. Largest follower count. |
language | string | Optional. Two-letter language code the creators post in, e.g. en. |
curl -X POST "https://developers.tokfluence.com/v1/ultra_searches" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"brief": "UK fitness creators who review sports drinks, ideally with 50k+ followers",
"countries": ["GB"]
}'The answer is 201 with the same object the status endpoint returns, below.
GET/v1/ultra_searches/:id#
Where the search is. Poll it every minute or two until results_ready is true.
{
"data": {
"id": 4812,
"brief": "UK fitness creators who review sports drinks, ideally with 50k+ followers",
"stage": "judging",
"stage_label": "Checking every creator against your brief",
"started_at": "2026-10-22T09:14:03Z",
"updated_at": "2026-10-22T09:31:40Z",
"estimate_seconds_remaining": 420,
"estimate_note": null,
"reading": "UK fitness creators who review sports drinks, ideally 50k+ followers",
"keywords": ["sports drink review", "gym supplements uk"],
"countries": ["GB"],
"counts": { "creators_found": 38, "bullseye": 11, "near_misses": 4, "below_floor": 6, "profiles_scanned": 912, ... },
"country_split": { "confirmed": 30, "unconfirmed": 8, "countries": ["GB"] },
"crawl": null,
"list": { "id": 20931, "name": "Fitness creators in the UK", "url": "https://app.tokfluence.com/lists/20931" },
"results_ready": true,
"free_preview": false,
"brief_reason": null,
"brief_message": null,
"brief_suggestions": [],
"error": null
},
"meta": { "quota": { ... } }
}| Param | Type | Notes |
|---|---|---|
stage | string | queued, expanding_hashtags, crawling, scanning_profiles, judging, building, then done or failed. |
estimate_seconds_remaining | int | null | Our estimate from past searches. null when the search has run past it; estimate_note then says which step is still running and how long it usually takes. |
results_ready | bool | The list exists and /results can be read. The list can appear before done and keeps growing while the search runs. |
crawl | object | null | Set when the list was delivered while our crawl keeps adding to it: { running, added }. |
error | string | null | Why a failed search stopped, in words you can show your user. |
GET/v1/ultra_searches/:id/results#
One page of the list, best first. Each creator uses the same schema as creators.search (tkc_ id, stats, contact emails), plus an ultra block with the judge's verdict.
Query
| Param | Type | Notes |
|---|---|---|
page | int | From 1. Defaults to 1. |
per_page | int | Defaults to 50, max 100. |
{
"data": [
{
"id": "tkc_a1b2c3d4e5f6a7b8",
"username": "liftwithjo",
"follower_count": 84000,
"region": "GB",
...,
"ultra": {
"rank": 1,
"tier": "bullseye",
"fit": 92,
"reason": "Reviews protein and sports drinks from a Manchester gym, weekly.",
"evidence": { "quote": "Honest protein reviews from my gym in Manchester",
"url": null },
"audience_type": "consumers",
"near_miss": false,
"country_confirmed": true,
"country_confidence": "confirmed",
"country_signal": "profile_region",
"platform": "tiktok"
}
}
],
"meta": { "page": 1, "per_page": 50, "total": 38, "final": true, "list_id": 20931,
"age_filter": { "excluded_likely_minors": 0 } }
}| Param | Type | Notes |
|---|---|---|
ultra.tier | string | null | bullseye (exactly the brief), adjacent (close, worth a look), craft (makes this kind of content for others). null for a creator you added to the list yourself. |
ultra.fit | int | null | The judge's fit from 0 to 100, against your brief. null when the judge did not score that creator. |
ultra.reason | string | null | One sentence on why the creator is on the list. |
ultra.evidence | object | null | The creator's own words that back the judge's read: quote, copied exactly from their bio or one of their recent captions (200 characters at most), and url, the post it came from, or null when it is their bio. null when the judge found no quote we could check against what they wrote. |
ultra.audience_type | string | null | Who mostly watches them: consumers, professionals, b2b_buyers, students, parents, local_community or other. null when the judge did not read that creator. |
ultra.near_miss | bool | Listed below everyone else: nearly a fit, worth a human look. |
ultra.country_confirmed | bool | null | When the brief names countries: true when we saw a sign the creator is there, false when we saw none either way. null when the brief names no country. |
ultra.country_confidence | string | null | When the brief names countries: confirmed (their profile country is one of them), likely (a sign short of that) or unknown. null when the brief names no country. |
ultra.country_signal | string | null | The sign behind country_confidence: profile_region, language (they write in its language), bio_text (their own words place them there), phone_country_code (the calling code of a contact phone; the number itself is never returned), audience_regions (only their audience is mostly there, which is not where they live) or none. |
ultra.platform | string | Always tiktok today. |
profile_unavailable | bool | Present and true when we could not read the creator's profile just now. The creator is still on the list; try again later for the stats. |
meta.final | bool | false while the list can still grow. |
meta.locked | int | Free accounts only: how many more creators a paid plan shows. A free Ultra Search shows its 10 best. |
Creators whose own bio states an age under 18 are always left out, as on every search, and counted in meta.age_filter.
423 account_held until we have reviewed it.
Errors
| Param | Type | Notes |
|---|---|---|
422 | missing_parameter | No brief. |
422 | brief_needs_niche | The brief names no topic we can search. error.details.suggestions lists topics to add. Nothing was spent. |
422 | brief_is_lookup | The brief asks for one account or link. Describe the kind of creators instead. Nothing was spent. |
422 | invalid_filters | A country, language or follower bound we cannot read. The message names it. |
422 | invalid_brief | The brief is too long, or asks for a niche we don't search. |
402 | no_searches_left | This period's Ultra Searches are used. The message says when more arrive; error.details.quota has the numbers. |
403 | ultra_not_included | Your plan has no Ultra Searches. |
409 | already_running | As many as your account may run at once are running (one, unless set up for more). error.details.running_search_id is the newest one's id. |
429 | free_daily_cap | Free accounts' Ultra Searches for today are used up. Try again tomorrow. |
404 | ultra_search_not_found | No Ultra Search with that id on your account. |
409 | results_not_ready | The list does not exist yet. error.details.stage says where the search is. |
409 | ultra_search_failed | The search stopped before it built a list. The message says why. |
423 | account_held | Your account is paused while we review unusual activity. |
From an AI agent
The MCP server has the same thing as two tools. start_ultra_search asks first: its first call starts nothing and returns how many Ultra Searches you have left, so your assistant can check with you before using one. get_ultra_search reads the status and, once the list exists, a page of it. Over OAuth, starting a search needs the crawl permission.