-
-
Friday, Nov 27 is Kirk Franklin’s night in Nashville, shown with how robust the call is, the headcount’s pick and Qloo match coverage
-
A headcount picks the quietest date, Dec 10 – Qloo affinity flips the ranking and Nov 27 comes out best, the lines cross
-
Every date side by side: clash score, nearby shows, the biggest pull, and a timeline of each show’s pull on his audience
-
Why Dec 10 ranks last: Jodeci, Dave Barnes and Little Big Town play that night, each score broken into affinity, popularity, timing
-
Qloo’s heatmap of where Kirk Franklin’s audience is concentrated around Nashville, with the venues pulling hardest on Dec 10 pinned
-
Where to play: venues ranked by how concentrated his audience is around them and how little competition sits within 1 km
-
Support acts from Qloo recommendations whose fans overlap his, leaving out anyone already playing nearby that fortnight
-
Find a night: every Friday and Saturday shaded by pull, the best three numbered, the headcount’s pick underlined, holidays skipped
-
Plan a run: one night per city across Nashville, Chicago and Atlanta, so no two shows are too close and the run carries the least pull
-
A watch alert using labelled demo data: a new show and a cancellation move the best night, with a Gemini summary checked against facts
-
Ask in plain language: the Gemini agent calls the same scoring tools, never invents a number, and its answer is checked against the engine
-
Works on mobile and in dark mode, with the same verdict and the headcount-vs-Qloo comparison
-
Pick the night your fans are free: enter an artist, a city and the dates you can hold, or let Tidate find the night
Inspiration: the quietest night can be the worst one
Promoters and talent buyers usually have a handful of dates they can hold for a show, and they have to pick one. The usual check is a headcount: open the calendar, see how many other concerts are near each date, and pick the quietest.
A headcount misses the point. A heavy metal show across town doesn't compete with a gospel artist's fans, but one R&B headliner the same night does. Whether two shows compete depends on whether they draw the same audience, not on how many shows are on the calendar. That's a taste question, and it's what Qloo answers. Today that judgment lives in spreadsheets, phone calls and memory.
The challenge's line, "If your submission would work the same without Qloo, you're building the wrong thing," sealed it. Tidate would be just a headcount without Qloo.
What it does
Give Tidate an artist, a city and the dates you can hold. It pulls every music event within two weeks of each date from Ticketmaster, matches each act to Qloo, and asks Qloo how close each act's audience is to your artist's. It then ranks your dates by how much the competition pulls on your fans and shows exactly which shows cause it.
A real example from the demo (a hypothetical hold for Kirk Franklin in Nashville):
- A headcount picks Thu, Dec 10. It's the quietest date, with 156 nearby shows.
- Tidate picks Fri, Nov 27, even though it's the busiest (238 shows). Its shows mostly draw other crowds.
- Dec 10 ranks last. Jodeci, Dave Barnes and Little Big Town all play that same night, and Jodeci's audience is closer to Kirk Franklin's than 99% of acts nearby.
The "Does Qloo change the answer?" chart puts both rankings side by side, so you can see the lines cross.
Around that core:
- Find a night: no dates yet? Score every Friday and Saturday (or every night) in a range and see them on a shaded calendar. Skip a night and the ranking updates instantly. Nights that are quiet for everyone, like Christmas, are flagged rather than recommended.
- Plan a run: pick one night per city across several cities so no two shows are too close together and the whole run carries the least pull. It explains each trade-off and shows where a headcount would route it differently.
- Watch dates: one click saves a watch. A daily job re-checks the dates with the same engine and records new shows, cancellations and a changing best night. Gemini writes a short summary, and it's rejected if it contains any number that isn't in the change list.
- Who could open: Qloo recommendations suggest support acts whose fans overlap the artist's, leaving out anyone already playing nearby.
- Fan map and venue picks: Qloo's heatmap shows where the artist's audience is concentrated around the city, with venues ranked by how many fans live nearby.
- Shared taste: Qloo tags explain why two acts overlap (Kirk Franklin and Jodeci share Rhythm & Blues and Soul). When they share no genre and Qloo still ranks the audiences close, Tidate says so, because that's exactly what a genre filter would miss.
- Ask: a Gemini agent answers plain-language questions ("Which of these three nights is least crowded for his fans?") by calling the same scoring tools.
- MCP server: the same tools (
score_candidate_dates,find_best_nights) are available to any MCP client athttps://tidate.vercel.app/api/mcp. - Share link: send an analysis to the artist's agent or your team.
How Qloo drives it
Qloo is used in six different ways, each for what it does best:
| Qloo feature | What Tidate uses it for |
|---|---|
/search |
Matching every Ticketmaster performer to a Qloo artist (exact or clear-namesake matches only) |
/v2/insights with signal.interests.entities + filter.results.entities |
The affinity of every competing act toward the target artist: the core of the score |
| Popularity | How big each competing act is |
Heatmap (urn:heatmap around a point and radius) |
The fan map and venue picks |
/entities tags |
The shared-taste explanation (genre, lineage, influences) |
| Recommendations with a location signal | Support-act ideas |
The score
For each candidate date \( d \), every competing show \( i \) within 14 days contributes:
$$ C(d) = \sum_{i} K_i \cdot S_i \cdot W(|d - d_i|), \qquad K_i = r_i^{\,4} $$
- \( r_i \) is the percentile rank of act \( i \)'s Qloo affinity among all acts playing nearby.
- \( S_i \) is the act's Qloo popularity. Missing values default to 0.5 and are flagged.
- \( W \) is a timing weight: 1 on the same day, 0.7 within two days, 0.4 within a week, 0.15 within two weeks.
Lower is better. The baseline is the same sum with every show counted alike: \( B(d) = \sum_i W(|d - d_i|) \).
Why a rank instead of the raw affinity? Live testing showed artist-to-artist affinity is compressed. With Clairo as the signal, Slipknot scores 0.74 and beabadoobee 0.98, so used raw, every act counts at least three quarters as much as the closest one. Ranking keeps Qloo's ordering and drops the compressed scale. The fourth power makes close acts dominate: a top-10% act counts about \( 0.9^4 / 0.5^4 \approx 10.5 \) times a median one. I fixed that exponent from first principles before collecting any evaluation data; it isn't fitted to the results.
Every number is traceable. Each show's row breaks down into affinity, rank, popularity and timing, and multiplying them out gives its share of the score.
Does it actually work?
I wrote the evaluation plan and committed it before collecting any data. Then I ran it on live data from six cities (Chicago, New York, Los Angeles, Austin, Nashville, Atlanta).
- Does Qloo affinity track shared audiences? I used Ticketmaster genre as an independent label. Over 146 artists and 37,913 artist–competitor pairs, Qloo affinity ranks a same-genre competitor above a different-genre one with an AUC of 0.618 (95% CI 0.590–0.647). Popularity alone scores 0.556. Affinity beats the popularity control in all six cities.
- Does Qloo change the decision? In 150 real scenarios (three Saturdays each), Tidate recommends a different date than the headcount 27% of the time and orders the dates differently 56% of the time.
- Do clashes predict cancellations? There were only 17 cancelled events in the window, below my pre-set minimum of 30, so I report insufficient evidence and claim nothing.
There's no ticket-sales data to prove the changed decisions are better, and Tidate says so.
How I built it
- App: Next.js 16 (App Router) and React 19 in TypeScript, deployed on Vercel. Every request and API response is validated at runtime with zod.
- Engine: a deterministic scoring engine. The language model never computes a number; it can only call tools that run the engine.
- Agent: Vercel AI SDK 7
ToolLoopAgentwith Gemini, tools to find an artist, analyse dates, explain a date, compare two dates and test what happens if a show moves. Its final answer is checked against the engine's own recommendation. - MCP: an MCP server exposing the same tools over Streamable HTTP.
- Data: Qloo Insights and Ticketmaster Discovery v2.
- Storage and scheduling: Upstash Redis (free tier) for watches and a shared cache of performer matches, and Vercel Cron for the daily watch check and cache warming.
- Tests: 92 Vitest tests covering scoring properties, pipeline failure modes, agent orchestration with a scripted model, and MCP over JSON-RPC.
Challenges I ran into
- Compressed affinity. Raw affinity scores made every act look relevant. Switching to a rank within the local market was the single biggest improvement.
- Matching real listings. About a third of performers in real Ticketmaster data are local acts, tributes ("THE DECEMBERISTS Tribute By The Dozen Buzzin' Cousins") or venue series with no exact Qloo match. Rather than guess, Tidate only scores exact matches. It then checks twice whether the unmatched shows could flip the answer: once in the worst case (each counts as a perfect match) and once in the typical case.
- Ticketmaster's 1,000-result limit. New York has around 2,500 music events in ten weeks. Search windows that hit the limit are split in half recursively and merged.
- Speed. A cold run looks up hundreds of performers. I added a time budget that looks up the most important acts first, a provisional ranking that streams in while lookups run, and a shared match cache that a daily job pre-fills. After warming, repeat runs take well under a second.
- Keeping the AI honest. The agent, the alert summaries and the explanations can't invent numbers. Every figure has to come from the engine, and the alert summary is rejected if it contains a number that isn't in the change list.
- Nights that are quiet for everyone. A night search kept recommending Christmas. Instead of hard-coding holidays, Tidate flags any night far quieter than the market's typical night and lets you skip it.
Accomplishments that I'm proud of
- The headcount-vs-Qloo slope chart: one picture that shows why Qloo matters.
- A pre-registered evaluation with an honest null result reported next to the positive ones.
- One engine behind the web app, the agent, the MCP server and the daily watch, so the numbers are always the same everywhere.
- A complete product, not a demo: shareable links, watches, a multi-city planner, mobile and dark mode.
What I learned
- Qloo's affinity is most useful as an ordering within a context, not as an absolute scale.
- Writing down the hypotheses and thresholds before touching the data kept me honest, especially when the cancellation test came back empty.
- The best split between agent and engine: the engine decides, the agent explains and navigates, and every claim gets checked.
What's next for Tidate
- Venue capacity and ticket price tiers, so a 20,000-seat arena and a 300-cap club aren't weighed the same.
- Testing against real outcomes (sell-through, attendance) with a promoter partner.
- Watch alerts by email or Slack, and team workspaces for shared holds.
- More cities and smarter tour routing that accounts for travel days and costs.
Built With
- gemini
- mcp
- model-context-protocol
- next.js
- node.js
- playwright
- qloo
- react
- redis
- ticketmaster-discovery-api
- typescript
- upstash
- vercel
- vercel-ai-sdk
- vercel-cron
- vitest
- zod
Log in or sign up for Devpost to join the conversation.