01 How exploration works
Unlike the pre-tracked niches on the Niches page, a topic group is yours: you pick the seeds, we build the map around them.
topic group — a niche you define with your own seed hashtags (and optionally seed creators), identified by a stable group_id. Nobody else's group affects yours.
wave — one round of exploration. Wave 0 crawls your seed hashtags; wave 1 crawls the hashtags wave 0 found; and so on until max_depth.
max_depth.active, and it's refreshed on the normal discovery cycle from there.Creating a group starts real crawling. It isn't instant — expect the first /status call right after create to show a queued or in-progress wave, not finished results. Check back in an hour for a group with real depth.
Every request on this page needs Authorization: Bearer <API_KEY>. All examples below use <GROUP_ID> as a placeholder for the group_id a create call hands you.
02 Create & manage
Spin a group up, list what you've got, look at one in detail, pause it, or force a fresh crawl.
202.
At least one of hashtags or seed_creators is required — an empty body on both returns 400.
curl -s -X POST "https://api.metrix.ac/api/v1/topic-groups" \
-H "Authorization: Bearer $TM_API_KEY" -H "Content-Type: application/json" \
-d '{"label":"docs-demo-cooking","hashtags":["cooking","recipes"]}'
{
"group_id": "docs-demo-cooking-f40c970b",
"status": "exploring",
"message": "Topic group 'docs-demo-cooking' created. Exploration started."
}
| Field | Type | Notes |
|---|---|---|
label | string | Required. Your own name for the group — shown back in list/get responses. |
hashtags | string[] | Optional, default []. Seed hashtags for wave 0, with or without leading #. |
seed_creators | string[] | Optional, default []. Seed creators to crawl alongside (or instead of) hashtags. |
max_depth | int | Optional, default 3. How many waves out the exploration goes. |
videos_per_hashtag | int | Optional, default 50. Sample size per hashtag per wave. |
Real capture from the call that created the docs-demo-cooking-f40c970b group used as <GROUP_ID> throughout the rest of this page.
curl -s "https://api.metrix.ac/api/v1/topic-groups" \
-H "Authorization: Bearer $TM_API_KEY"
{
"groups": [
{ "group_id": "docs-demo-cooking-f40c970b", "label": "docs-demo-cooking",
"seed_hashtags": ["cooking", "recipes"], // ← pass group_id as <GROUP_ID> below
"status": "active", "hashtag_count": 2, "total_videos": 100 }
],
"total": 1
}
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "label": "docs-demo-cooking",
"status": "active", "max_depth": 3, "hashtag_count": 2, "total_videos": 100,
"waves": [
{ "depth": 0, "status": "done", "hashtags_in": 2, "videos_found": 100,
"creators_found": 90, "hashtags_out": 0 }, // ← wave 0 found no new hashtags to chase yet
]
}
Nothing is destroyed. The group's hashtags, videos, and history all stay queryable; it just stops crawling until you /refresh it again.
curl -s -X DELETE "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>" \
-H "Authorization: Bearer $TM_API_KEY"
{ "status": "paused", "group_id": "docs-throwaway-pause-21ceef58" }
Captured against a disposable throwaway group created solely to demonstrate this call — that's why the group_id above doesn't match docs-demo-cooking-f40c970b used elsewhere on this page. Pausing your own active group works the same way.
?mode= controls how much re-runs: default rescan only re-crawls wave 0's existing hashtags; explore flips the group back to exploring and re-expands outward from scratch.
curl -s -X POST "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/refresh" \
-H "Authorization: Bearer $TM_API_KEY"
{ "status": "active", "group_id": "docs-demo-cooking-f40c970b" }
Non-admin, non-destructive — safe to call whenever you want fresher numbers ahead of the normal discovery cycle. Without pro tier this returns 403.
03 Progress
Poll these while a group is exploring — wave-by-wave counts, and the hashtag tree those waves have built.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/status" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "status": "active",
"waves": [
{ "depth": 0, "status": "done", "hashtags_in": 2, "videos_found": 100,
"creators_found": 90, "hashtags_out": 0 }
],
"hashtag_count": 2, "total_videos": 100
}
?pursue_only=true filters to hashtags the crawler is still actively expanding from, rather than every hashtag ever touched.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/hashtags" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "total": 2,
"hashtags": [
{ "hashtag": "cooking", "hop_depth": 0, "video_count": 50, "pursue": true },
{ "hashtag": "recipes", "hop_depth": 0, "video_count": 50, "pursue": true }, // ← both are seeds: hop_depth 0
]
}
hop_depth is which wave discovered the hashtag — 0 for your seeds, 1 for what wave 0 found, and so on.
04 Harvest
Once a group has depth, these are the payoff calls: the velocity leaderboard, tier-jump detection, and a one-call digest — all scoped to just this group's ecosystem.
Same shape as the trending page, pre-scoped to this group. entity_type defaults to hashtag (also sound, creator, ig_hashtag); window defaults to 24h.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/trending?limit=3" \
-H "Authorization: Bearer $TM_API_KEY"
{
"entity_type": "hashtag", "window": "24h", "total": 2,
"results": [
{ "entity_id": "cooking", "velocity": 0.0, "size_tier": "xl", "latest_value": 113307711 },
{ "entity_id": "recipes", "velocity": -43431.26, // ← negative velocity = losing steam
"size_tier": "medium", "pct_change": -14.38 }
]
}
Same "went viral overnight" detector as the niches page's breakouts endpoint — entities whose size_tier jumped min_tier_jump+ steps (default 2), scoped to this group's hashtags. Optional tier filters by the result's new tier and accepts nano, micro, mini, small, medium, large, or xl; an invalid value returns 422.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/breakouts?limit=3" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "window": "24h",
"min_tier_jump": 2, "total": 0, "breakouts": []
}
Live-captured, genuinely empty — this group only has 2 hashtags so far (wave 0), and a 2+ tier jump needs a real population of entities to jump within. Not a broken call; a young group's expected result.
A pre-computed roundup rather than a live query: hashtag clusters, the hottest creators and sounds in the group, and running totals. Computed on the discovery cycle, not per-request — 404 until the first pass has run.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/summary" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b",
"clusters": [
{ "cluster_id": 0, "label": "#recipes", "size": 66, "cohesion": 0.642 }, // ← 13 clusters total, trimmed
],
"hot_creators": [ { "entity_id": "chef_boydbrownthe3rd", "velocity": 782.78 } ],
"trending_sounds": [ { "entity_id": "7273614838022178818", "velocity": 747.83 } ],
"total_hashtags": 2, "total_videos": 566, "total_creators": 42, "total_sounds": 54
}
Real capture, not thin — this group had already produced 13 hashtag clusters and a populated hot_creators/trending_sounds list by the time we captured it, well before wave 1 had even started. total_videos here (566) is higher than the group's own total_videos (100) because the summary counts every video seen across the seed hashtags' full corpus, not just this group's wave-0 sample.
05 Suggestions
Four flavors of "what haven't we used yet" — sounds, sub-niches, caption patterns, and creators — all pulled from the group's own ecosystem, not the generic library.
Pass ?model_id= to scope the "haven't used" exclusion to one specific model instead of all of them.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/suggestions/sounds" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "window": "24h", "total": 20,
"sounds": [
{ "sound_id": "7273614838022178818", "sound_title": "Paint The Town Red (Instrumental)",
"sound_author": "Doja Cat", "velocity": 747.83, "used_by_model": false }, // ← 20 total, trimmed to 1
]
}
Groups the group's own hashtags into sub-niche clusters and scores each by how little the client's models have touched it. Returns 404 if the group-intel job hasn't run yet for this group.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/suggestions/topics" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "window": "24h", "total": 10,
"topics": [
{ "cluster_label": "#recipes", "cluster_size": 66, "avg_velocity": -658.05,
"model_coverage": "0/66", "opportunity_score": 0.0 }, // ← 10 clusters total, trimmed to 1
]
}
opportunity_score: 0.0 here isn't a bug — this client has no models posting in this niche yet, so model_coverage is 0/N across every cluster and the opportunity math has no signal to work with. Score rises once a model in this niche starts posting.
Analyzes up to ?limit= (default 200) of the group's top-performing video captions for recurring hooks, calls-to-action, and emoji use.
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/suggestions/captions" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "avg_length": 473.7, "sample_size": 55,
"top_hooks": ["#recipes #easyrecipe #cooking"],
"top_ctas": ["save this", "link in bio"],
"emoji_patterns": { "avg_count": 1.1, "top": ["😋", "✨", "❤"] }
}
curl -s "https://api.metrix.ac/api/v1/topic-groups/<GROUP_ID>/suggestions/creators" \
-H "Authorization: Bearer $TM_API_KEY"
{
"group_id": "docs-demo-cooking-f40c970b", "window": "24h", "total": 15,
"creators": [
{ "creator_id": "chef_boydbrownthe3rd", "velocity": 782.78,
"size_tier": "medium", "is_own_model": false }, // ← 15 total, trimmed to 1
]
}
is_own_model is how your own models get excluded from their own suggestions — pass ?model_id= to scope that exclusion to one model.