-
Khruangbin across North America. The globe is lit by Qloo's heatmap; Burlington, Vermont opens the run as a hidden gem.
-
A focused stop with neighbourhood hotspots, rooms and the resolved Qloo locality.
-
The Soundcheck timeline: every agent step and the Qloo calls behind it.
-
Every Qloo request on the run, live or cached.
-
How Qloo powers this: the requests and real results behind each step.
-
The printable booking sheet.
-
The same agent on a phone.
-
AP Dhillon's North American run comes out all-Canadian.
-
Prateek Kuhad across India, booked into theatres.
Inspiration
A first tour is mostly guesswork. Independent artists and small agents route by gut feel, by last tour's ticket counts (which do not exist for a new territory), or by copying the same ten cities every act plays. The expensive mistakes are the obvious markets that are already saturated and the smaller cities where the audience was waiting and nobody booked a show.
Qloo can see something a booking spreadsheet cannot: where an artist's audience over-indexes, before a single ticket is sold, and what else that audience loves. I wanted to turn that into the decision a booking agent actually makes: which cities, which rooms, who shares the bill, and which brands to pitch.
What it does
You pick an artist and a territory (North America, Europe, UK and Ireland, Asia-Pacific, Latin America, India, or a world tour). Headliner:
- Resolves the artist in Qloo and reads one heatmap across the whole territory: thousands of cells, each a percentile of how strongly this artist's fans concentrate there.
- Scores 185 candidate markets from that heatmap, including secondary cities, and labels each one: stronghold, emerging, long shot, or hidden gem (fans rank near the top of the territory and clearly ahead of the local market).
- Finds rooms in each candidate city whose crowd matches the audience, filtered by real Qloo place categories (live music venue, night club, jazz club, performing arts theater, concert hall, arena, amphitheater).
- Builds the bill from acts with overlapping audiences, sized as a co-headliner or a support act.
- Lists brands the fans over-index on, for merch and sponsorship pitches.
- Writes an aggregate audience brief: Qloo's age and gender affinity plus taste tags across music, style, audience descriptors, themes and media.
- Hands that evidence to an LLM agent that chooses the run and writes a booking agent's reason for every stop, then routes it, draws it on a night-lights globe and exports a Markdown, JSON or printable booking sheet.
On the globe, the city lights dim and Qloo's heatmap glows in their place, so the map is lit by fans rather than by population. Six one-click demos replay recorded runs in about two seconds; any other artist runs live.
A few things it found on live data:
- Khruangbin, North America: San Francisco, Portland and Austin lead as expected. Burlington, Vermont is the surprise: fans rank in the top 0.8% of the continent while its market sits lower (affinity 0.992 against 0.976 popularity), a hidden gem. Missoula and Santa Fe read the same way.
- AP Dhillon, North America: the run comes out all-Canadian (Toronto, Winnipeg, Edmonton, Calgary, Vancouver, Victoria), and the strongest cells sit 20 to 25 km outside downtown Toronto and Vancouver, toward Brampton and Surrey. The bill is Diljit Dosanjh, Karan Aujla and Sidhu Moose Wala, and the brands are Mani Jassal, Sabyasachi and Filmfare.
- Prateek Kuhad, India: Goa, Mumbai, Pune, Bengaluru, Kolkata and Shillong, with The Local Train, Tajdar Junaid and The Yellow Diary on the bill and the Royal Opera House Mumbai and Prithvi Theatre as theatre rooms.
- A sanity check: Morgan Wallen's audience peaks in Nashville (0.994) and falls to 0.49 in San Francisco. The signal is taste geography, not population.
How I built it
Headliner is a Next.js 16 App Router app in TypeScript, deployed on Vercel. The agent runs server-side and streams every step to the browser as NDJSON.
The agent. A research pass calls eight Qloo-backed tools. The LLM (gpt-oss-120b on Groq, with gpt-oss-20b and Qwen as fallbacks on rate limits) then receives a compact evidence digest in which Qloo IDs are replaced by short aliases. It can call find_venues with a specific room type or similar_artists for a younger crowd before it calls submit_tour_plan. The last two turns may only submit, so every run ends in a plan.
Grounding. The model can only choose from what Qloo returned. The server checks every city, room, act and brand ID against an evidence ledger, checks that every number in every stop reason is that stop's own Qloo number, and checks that any "hidden gem" or "stronghold" label matches the computed read. A failing draft goes back once for correction. Then the server drops anything unsupported, fills in every figure itself, writes the demographic facts itself (the model may not make age or gender claims), routes the stops with nearest neighbour plus 2-opt, and validates the plan with zod. If the LLM is unavailable, a deterministic planner finishes from the same evidence and the plan says so.
The globe. React Three Fiber with custom GLSL: a NASA Black Marble night texture whose lights cool and dim when the heatmap arrives, instanced glow sprites for the territory's strongest cells, pillars for stops, animated route arcs, magnified neighbourhood hotspots for a focused city, and collision-aware DOM labels. The camera centres the run in the space between the side panels and pulls back on phones.
Quality. 64 unit tests (scoring, city reads, hydration and the anti-hallucination checks, routing, replay, mapping on live payload shapes, caching and quota), a live verification script that exercises every Qloo call, and an end-to-end LLM eval harness that runs ten artist and territory cases through the real API.
How Qloo powers it
Headliner would not work without Qloo. An LLM can guess that Khruangbin plays well in Austin; it cannot measure that Burlington outranks its own market, that AP Dhillon's North American audience is Canadian and suburban, or which Portland rooms match the crowd. These are the calls, in the order a run makes them:
| Step | Qloo request | What Headliner does with it |
|---|---|---|
| Resolve | GET /search?query=…&types=urn:entity:artist |
the entity ID that every later call uses as the taste signal |
| Room categories | GET /v2/tags?filter.query=live music venue&feature.semantic_search=true |
real urn:tag:category:place:* IDs for the room-size filter |
| Score the territory | GET /v2/insights?filter.type=urn:heatmap&signal.interests.entities=<artist>&filter.location=POLYGON(…) |
one call returns about 5,500 geohash cells for North America; each city is read at the cell its centre falls in, and the best cell within 35 km becomes a metro peak |
| Rooms | filter.type=urn:entity:place + filter.location.query=<city> + filter.tags=<room categories> |
rooms whose crowd matches, real rooms before restaurants that only host gigs; the resolved locality (for example "Portland, Multnomah County, Oregon") is shown as proof |
| Hotspots | filter.type=urn:heatmap + filter.location.query=<city> |
about 700 cells of 150 m per city; the strongest 45 become columns on the globe |
| Bill | filter.type=urn:entity:artist + filter.exclude.entities + filter.popularity.min/max (+ signal.demographics.age=24_and_younger) |
peers and support acts with overlapping audiences |
| Brands | filter.type=urn:entity:brand |
merch and sponsor pitches, duplicates merged |
| Audience | filter.type=urn:demographics, and filter.type=urn:tag with filter.tag.types and diversify.by=subtype |
age and gender affinity, plus taste tags across six subtypes in one call |
Reading the numbers. Heatmap affinity and popularity are percentiles across every cell in the queried area, so big cities crowd the top: every primary North American market sits between 0.88 and 1.0. Headliner reads both on a log scale of how far into the top a city sits (top 0.1% scores 0.98, top 1% 0.85, top 3% 0.70) and compares the fan rank with the popularity rank. A hidden gem is a city whose fans rank in the top 3% and clearly ahead of its market; a stronghold is in the top 1%. I calibrated these thresholds on live heatmaps for 12 artists across all six territories. Mainstream acts get no hidden gems, which is the honest answer.
Working within the key. The hackathon key allows 5 requests per second and 10,000 per month, and a full run makes about 25 calls. The client spaces requests, shares identical in-flight calls, watches the monthly quota headers, and caches packed responses for a week (in memory, then Vercel Runtime Cache). Identical runs replay from a seven-day recording that is labelled as a replay, with a "run fresh" button.
Challenges I ran into
- The obvious API path failed. City-level heatmaps (
output.heatmap.boundary=urn:entity:locality) returned a 500 on the hackathon host for every area I tried, and a text query like "Europe" resolved to no cells. I rebuilt city scoring on geohash cells, with WKT polygons for multi-country territories, which turned out better: one call per territory instead of one per city. - Real numbers broke my thresholds. I first built against mock data with documented shapes. Live percentiles put every big city near 1.0, so my original rules called everything a stronghold. The log scale and the calibration across 12 artists fixed it.
- Names do not always resolve. Some city names (Shillong) do not resolve as Qloo localities, so those calls retry with a WKT point and a 20 km radius. Ambiguous names carry a region ("Portland, Oregon"), and the resolved locality is displayed.
- Token budgets. Groq's free tier allows 8,000 tokens a minute per model. My first live eval went 6/10 because multi-turn runs overflowed it. Shrinking the evidence digest, fetching rooms for hidden gems up front and forcing a submission on the last two turns fixed every failed case (4/4 on re-run).
Accomplishments that I'm proud of
- Finding Burlington for Khruangbin, and an all-Canadian, suburban run for AP Dhillon, from live data in about 14 seconds.
- An agent that cannot invent a city, a room, an act or a number: every claim in the plan traces back to a Qloo result, and the timeline shows the request behind it.
- A globe where the map is literally relit by Qloo's heatmap.
- Indian and international artists work as well as American ones, from Goa and Shillong to Brighton and Bali.
What I learned
- Qloo's heatmap is percentile-based, so the interesting signal is relative: the gap between how a city's fans rank and how its market ranks.
- Explainability is 1.0 with a single signal and splits almost evenly across a multi-artist bill, so I show it as provenance rather than as an insight.
- Validation that sends a draft back once, then repairs on the server, beats retrying the model until it is perfect, especially on a tight token budget.
What's next
- Fan-side context per stop: the restaurants and bars that crowd already goes to before a show, from the same place insights.
- Comparing two artists' heatmaps to find the cities where a co-headlining bill adds the most new fans.
- Routing days and travel time between stops, and exporting holds to a booking calendar.
- A larger, editable city catalogue, so any strong cell on the globe can become a stop.
Honest limits
- Scores are Qloo aggregate taste affinities for audiences in a place. They are not ticket-sales forecasts and never describe an individual; no personal data is sent to Qloo.
- "Hidden gem", "stronghold" and the 0 to 100 score are my interpretation of Qloo's numbers, not Qloo metrics.
- Qloo has no venue capacities, so room size is a place-category filter. Availability, capacity and visas still need a human agent.
- Qloo's coverage varies by audience and place. Some audiences are sparse in a territory: Anoushka Shankar's India heatmap returns 13 cells, so fewer cities have a reading.
- The LLM runs on Groq's free tier. When its daily token allowance is used up, plans come from the deterministic planner and the badge says so.
Built during the hackathon
Headliner is a new project: I started it on October 4, 2026, inside the submission period, and wired it to the live Qloo API on October 6.
Built With
- gpt-oss
- groq
- next.js
- playwright
- qloo
- react
- react-three-fiber
- tailwind-css
- three.js
- typescript
- vercel
- vitest
- zod
Log in or sign up for Devpost to join the conversation.