Skip to content

Matching & Scoring

How the Brand Match App calculates match scores between creators and brands, and how matches are stored and managed.

Overview

Every creator–brand pair has a match score from 0–100, calculated by the V3 Python scorer (scripts/scoring_v3/scoring_v3.py). Scores are stored in the Neon matches table and served via ca-data. The app never recalculates scores live — it reads pre-computed values.


V3 Scoring Signals

The score is the sum of six weighted signals. Total possible: 100 points.

Signal 1 — Brand Behavioral (0–20 pts)

Measures how well this creator fits the brand's existing sponsorship behavior.

  • View Fit (0–17 pts): Creator's average views vs. the average views of the brand's past sponsors. Closer to the brand's typical reach = higher score.
  • Niche Overlap (0–3 pts): Whether the creator's niches overlap with the niches of other creators who have actually worked with this brand (sourced from brand_creator_deal_history.json). Fuzzy-matched to strip parenthetical suffixes from deal names.

Signal 2 — Niche Precision (0–20 pts)

Two-component signal measuring how well the creator's content niche aligns with the brand.

  • Component A — Roster Niche Overlap (0–12 pts): Creator niches vs. the niches of past CA roster partners for this brand. Scoring: 3+ overlapping niches = 12 pts, 2 niches = 9 pts, 1 niche = 4–7 pts, partial = 2 pts.
  • Component B — Embedding Similarity (0–8 pts): Semantic similarity between the brand's description (augmented with past-partner niches) and the creator's profile using text embeddings. Rescaled to the actual corpus range (0.50–0.75).

Signal 3 — Competitive Intel (flat 20 pts)

Currently disabled. All creators receive the full 20/20. Will be re-enabled when competitive data is more complete.

Signal 4 — Price / Market Fit (0–20 pts)

Measures how well the creator's rate aligns with what this brand typically pays.

  • Creator's rate vs. the brand's average deal rate
  • Tighter alignment = higher score

Signal 5 — Audience Demographics (0–10 pts)

Scores the creator's audience characteristics against what the brand typically looks for:

  • US audience percentage
  • Male/female split
  • Age distribution

Signal 6 — Inventory Momentum (0–10 pts)

Availability and frequency signal:

  • How regularly the creator publishes sponsored content
  • Whether they have open inventory slots

Score Color Coding

ScoreColorLabel
90–100GreenExcellent fit
80–89LimeStrong fit
70–79GoldGood fit
60–69OrangeModerate fit
Below 60GrayWeak fit

Match Status (Pipeline)

Each match has a status field that tracks where it is in the agent's pipeline:

StatusDescription
not_pitchedDefault — not yet contacted
reached_outAgent has sent an initial pitch
in_negotiationActive discussion / deal in progress
wonDeal closed
not_a_fitAgent has marked this as not worth pursuing

Status is updated by the agent via the Pitch / Pass buttons in the UI, which call PATCH /api/matches/:id on ca-data.


Pitch Narrative

Each match record optionally includes a pitch_narrative — a one-paragraph pre-written angle explaining why this specific creator is a good fit for this specific brand. Narratives are generated in batch by scripts/generate_narratives_openai.py.

As of early 2026, ~55% of assigned matches have a narrative. The remaining ~45% show no narrative text in the UI.


Conflict Detection

The conflict_database table tracks creators with active sponsor detections for competing brands. If a creator in a match has a detected conflict with the brand being pitched, a warning badge appears on their match card.

Conflict data is synced separately from the sponsor detection pipeline.


Batch Rescoring

When scores need to be recalculated (e.g. after scoring model changes), the process is:

  1. Run scripts/scoring_v3/run_v3_scoring.py — outputs 1,753 brand JSON files to data/matches_v3/
  2. Run scripts/push_rescored_matches_to_neon.py — bulk UPDATE to Neon (2,000 rows per batch)
  3. ca-data serves the updated scores immediately — no app redeploy needed

The last full rescore updated 107,307 rows to v3 scoring.