01 Search
One endpoint, three entity types. Start here, then follow an entity_id into the rest of this page.
Every request on this page needs Authorization: Bearer <API_KEY>.
Real query params from the handler: query (required — a prefix match against entity names/ids, not a full-text search), entity_types (repeatable, defaults to all three), sort_by (relevance default; also velocity_1h, velocity_24h, momentum, views, followers), limit (default 20, max 100), offset, and an opaque cursor for pagination. A cursor wins when both are supplied. The API overfetches through the requested page for every selected type, applies a stable global cross-type sort, and only then slices the page, so page 2 no longer repeats page 1.
curl -s "https://api.metrix.ac/api/v1/search?query=cooking&limit=5" \
-H "Authorization: Bearer $TM_API_KEY"
{
"query": "cooking", "total": 15, "limit": 5, "offset": 0,
"has_more": true, "next_cursor": "eyJvIjogNX0=", // ← pass this back as ?cursor= for page 2
"results": [
{ "entity_type": "creator", "entity_id": "cooking10121",
"display_name": "Cooking101", "match_score": 1.0,
"metrics": { "views": null, "velocity_24h": null, "momentum": null }, // ← metrics are null until we've computed velocity for this entity
},
{ "entity_type": "creator", "entity_id": "cookingbomb", "display_name": "cookingbomb", "match_score": 1.0 }
]
}
Matching is prefix-based on the entity's own id/name, not a fuzzy or full-text search — query=cooking above only matched creators whose handle starts with "cooking." metrics stay mostly null for search hits because most matched entities haven't had velocity computed yet; it's a name index first, a leaderboard second.
02 Neighborhood
Once you have an entity, its related list answers "what else belongs with it" across hashtags, creators, sounds, and videos.
co-occurrence — how often two entities appear together on the same videos, often enough to matter. Two hashtags can keep showing up on the same clips; a creator can keep using a sound; a sound can keep riding a hashtag.
{entity_type} is one of hashtag, creator, sound, video. Results intentionally mix entity types — a hashtag's related list can include the creators and sounds that ride it, not just other hashtags. match_score is the raw co-occurrence strength (NPMI). metrics.momentum is real momentum read from the velocity engine for the 24h window — it is not derived from match_score, so the two do not track each other. It is null when the entity has no velocity row for that window, and 0 when it has one that is flat; the API never fabricates a number to fill the field.
curl -s "https://api.metrix.ac/api/v1/related/hashtag/food?limit=4" \
-H "Authorization: Bearer $TM_API_KEY"
{
"query": "hashtag:food", "total": 4, "limit": 4, "has_more": false, "next_cursor": null,
"results": [
{ "entity_type": "creator", "entity_id": "tastebuds_nyc", "match_score": 0.7313, // ← creators AND sounds mixed with hashtags here
"metrics": { "momentum": 1034.9 } },
{ "entity_type": "creator", "entity_id": "lafoodieguy", "match_score": 0.7226,
"metrics": { "momentum": 0.0 } }, // ← has a velocity row, but it is flat — not the same as null
{ "entity_type": "sound", "entity_id": "7273614838022178818", "match_score": 0.6697,
"metrics": { "momentum": 813.3 } }
]
}
03 Creator deep-dive
Four views of one creator: who they are, how they've grown, how fast, and what they've posted. Examples below are all live-captured against cookingwithshereen, a real creator in the food_cooking niche.
Aggregated from every video we've discovered for this creator: view/engagement totals, posting cadence, top sounds, top hashtags.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/profile" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator": {
"creator_id": "cookingwithshereen", "nickname": "Shereen Pavlides", "verified": true,
"follower_count": null, "follower_count_known": false, // ← see note below,
"video_count": 26, "total_views": 38570026, "avg_views": 1483463,
"engagement_rate": 0.0032,
"posting_frequency": { "daily_avg": 1.86, "last_7d": 2, "last_30d": 26 },
"top_sounds": [{ "sound_id": "6847961051430914050", "title": "Mambo No. 5", "usage_count": 2 }]
},
"top_hashtags": ["cookingwithshereen", "foodies", "italianfood", "chicken", "homemade", "recipe"]
}
follower_count_known flags whether TikTok actually included a follower count on the responses we captured — it strips that field from roughly 86% of unauthenticated API replies, so null here is the common case, not a data gap on our end. Trust follower_count_known: true before trusting a non-null follower_count.
days (default 30, 1–30) controls the lookback window. It stops at 30 because snapshots older than 30 days are removed by retention; a larger value returns 422. Points come from periodic re-crawls of the creator's profile, not every single video snapshot.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/history?days=30" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator_id": "cookingwithshereen",
"points": []
}
Real, live-captured, and genuinely empty for this creator — she has no periodic profile re-crawl snapshots yet, only per-video discovery data (which the /videos and /profile endpoints below draw on instead). An unknown creator_id returns 404; a known creator with no snapshot history returns 200 with points: [] like this — the two cases look different, so check for the 404 rather than assuming an empty array means "not found."
Follower growth is computed on read from the same snapshot history as /history above (windows: 24h, 7d, 30d); views reuses the entity-velocity rows also used by the trending/niches pages. engagement.likes uses the same windows, computed from real like-count observations taken when the creator is crawled daily. engagement_data_through is the time of the newest such observation, and is null when there is none.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/velocity" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator_id": "cookingwithshereen",
"follower": { "24h": null, "7d": null, "30d": null },
"views": null,
"engagement": { "likes": { "24h": null, "7d": null, "30d": null } },
"data_through": null,
"engagement_data_through": null
}
All-null here follows directly from the empty /history above — no snapshot rows means no growth windows to compute. Pick a creator with an active velocity row (visible via size_tier on the niches/trending pages) to see populated numbers.
limit/offset for paging, sort (discovered_at default, also views, likes), min_views to filter out low performers.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/videos?limit=2" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator_id": "cookingwithshereen", "total": 27,
"videos": [
{ "video_id": "7663193409607224589", "views": 123100, "likes": 9112, "shares": 529, "comments": 82,
"sound_id": "7663193464833673998", "hashtags": ["cookingwithshereen", "foodies", "greenbeans"],
"discovered_at": "2026-07-18T00:32:22Z", "source": "creator_profile",
"relative_score": null, "is_overperforming": null }
]
}
relative_score/is_overperforming come back null when the creator has no row yet in the internal creators summary table this ratio is computed against — real for many creators found through discovery rather than a direct profile crawl.
04 Discovery
Two ways to place a creator relative to everyone else: who looks like them, and which niches they actually fit.
Fast, unseeded similarity from shared hashtag usage. For a deeper, seeded version that also weighs velocity and niche affinity, see the Creator Recommendations page.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/similar?limit=3" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator_id": "cookingwithshereen", "total": 3,
"results": [
{ "creator_id": "soflofoodies", "similarity_score": 0.1228, "shared_hashtag_count": 7,
"shared_hashtags": ["baking", "chef", "food", "homemade", "italianfood"] },
{ "creator_id": "jacksdiningroom", "similarity_score": 0.0909, "shared_hashtag_count": 5,
"shared_hashtags": ["cake", "food", "italianfood", "italy", "steak"] }
]
}
fit_score blends hashtag_coverage (60%, share of the niche's hashtags this creator has used) and calibrated seed_affinity (40%, how close their content sits to the niche's seed topics). sound_coverage remains in the response as 0.0 for compatibility but does not affect the score until a sound-coverage source exists. Results are sorted by fit_score, and the top result is flagged is_primary: true.
curl -s "https://api.metrix.ac/api/v1/creators/cookingwithshereen/niche-fit" \
-H "Authorization: Bearer $TM_API_KEY"
{
"creator_id": "cookingwithshereen", "primary_niche": "food_cooking",
"results": [
{ "topic_id": "food_cooking", "fit_score": 0.4089, "hashtag_coverage": 0.0154,
"sound_coverage": 0.0, "seed_affinity": 0.9991, "is_primary": true }, // ← correctly lands her in food_cooking,
{ "topic_id": "sg_food_miami", "fit_score": 0.04, "hashtag_coverage": 0.0667,
"sound_coverage": 0.0, "seed_affinity": 0.0, "is_primary": false }
]
}
Covers every niche in our taxonomy, not just the ones visible to your account — treat low fit_score topics past the primary as noise, not additional matches.
05 Creator suggestions
The frozen network-wide influence and collaboration rankings were retired. For live, model-relevant discovery, use GET /models/{model_id}/suggested-creators, which ranks creators by current niche affinity and excludes creators the model already follows.
06 Product match
Find TikTok and Instagram videos whose caption or hashtags name a brand, a product, or a related term, with a visible reason on every row.
Send at least one of brand, product, terms or handle (a brand account: its own posts match as brand_account, posts that @mention it as brand_mention; each counts as one term toward min_terms; the account must be crawled first via POST /models/{model_id}/subscriptions/creators) (terms comma-separated; at most 12 distinct terms, each 2+ chars). Also: platform (all default, tiktok, instagram), min_terms (1–12, default 1; 2 = brand plus a product term), published_within_days (1–365), min_views, sort (views default, likes, published), limit (max 50), offset (max 1000).
exclude is a comma-separated ignore list (at most 12). A term that is also in terms, brand or product returns 400. A matched video is hidden when an excluded term is in its caption as whole words or is a substring of any of its hashtags (exclude=dyson hides #dysonairwrapdupe). Inclusion is precise; exclusion errs toward hiding.
Every row has matches[] (term, kind = brand|product|term|brand_account|brand_mention, where, matched) and matched_terms. where is one of:
caption— the term appears in the caption as whole words (matchedis the term).hashtag— the video carries the term's hashtag form (LED strip→#ledstrip).hashtag_prefix— brand only, brand form 4+ chars: a longer hashtag starting with it (skimsreview);matchedis that hashtag.hashtag_joined— reported on a product/term when a brand-prefix hashtag's remainder equals or contains its form or a product word (skimsbra).caption_word— product only, and only when the brand matched: one product word of 3+ letters as a whole word in the caption (bra).
curl -s "https://api.metrix.ac/api/v1/product-match/videos?brand=maloo&terms=airstyler&exclude=dyson,airwrap" \
-H "Authorization: Bearer $TM_API_KEY"
{
"videos": [ { "video_id": "...", "matches": [
{ "term": "maloo", "kind": "brand", "where": "caption", "matched": "maloo" },
{ "term": "airstyler", "kind": "term", "where": "hashtag", "matched": "airstyler" } ],
"matched_terms": 2 } ],
"total": 12, "platform_totals": { "tiktok": 4, "instagram": 8 },
"excluded_totals": { "tiktok": 3, "instagram": 1 }, // ← always present; zeros when exclude is empty
"filters": { "exclude": ["dyson", "airwrap"] }
}
total and platform_totals count shown videos before paging; excluded_totals counts videos that matched but were hidden by exclude. filters echoes exclude only when sent.
Two honest caveats. Coverage: only about 2% of TikTok videos have a stored caption today (hashtag-page rows stored before 2026-10-14 have none; newer ones do), so TikTok results lean on hashtags; Instagram captions are present on about 99% of rows. Meaning: a match is evidence that a video names the product, not a verdict that it advertises or sells it. Instagram shares is always null.
JSON body: brand and/or product (at least one, 80 chars max), optional terms (same limits as the search). One model call. same_product holds other names for this exact product; similar_products holds generic products to compare and never contains the brand. Each list has at most 8 lowercase, deduplicated terms with source: "ai", and never repeats a term you sent. Not cached.
curl -s -X POST "https://api.metrix.ac/api/v1/product-match/suggest-terms" \
-H "Authorization: Bearer $TM_API_KEY" -H "X-End-User: tester-1" -H "Content-Type: application/json" \
-d '{"brand":"Skims","product":"Fits Everybody Bra","terms":["shapewear bra"]}'
{ "same_product": [ { "term": "...", "source": "ai" } ],
"similar_products": [ { "term": "...", "source": "ai" } ],
"model": "..." }
Limits: 5 per minute and 30 per day per X-End-User (the daily cap is skipped when the header is absent), plus a per-client daily ceiling. Any of these returns 429; only the per-client ceiling 429 carries Retry-After. 503 when the model is unavailable or answers unusably — there is no fallback list.