Try it: Khruangbin, 10 stops, North America · Nate Bargatze, comedy · The Rest Is History, live podcast, UK + Ireland · each one also plays as a map tour. No sign-up.

Inspiration

Every live act has an audience in cities it has never played. Tours still get routed on ticket history, streaming counts and gut feel. All three show where an act already sells; none show where an audience is primed and waiting. Ask a general-purpose chatbot and you mostly get the biggest cities on the map, because that is what text on the internet talks about. A wrong stop is expensive: a half-empty room, and the travel days it took to get there.

What a promoter actually needs is taste, located: which cities over-index on the act's audience, who those people are, which local acts share that crowd, which brands they love, and which rooms in town fit them. That is a cross-domain, geographic question, and it is exactly what Qloo's taste graph answers.

What it does

Soundcheck runs a soundcheck on a tour before anyone books a venue. You name an act (a band, a comedian, a podcast), a region and a window. An agent then works Qloo the way a promoter would and hands back a plan a team can act on:

  • Primed but untapped. Every candidate city is scored on the audience's affinity for the act (Qloo heatmaps) and plotted against how popular the act already is there. The top-left quadrant, high affinity and low popularity, is the opening: cities where the taste is there but the act has not broken through.
  • A routed, costed tour. The best cities are ordered into a drivable run with travel days, a travel-and-crew estimate by budget tier (van, bus, production), a suggested room size and a per-city break-even. Every number Soundcheck estimates is labelled as Soundcheck's, never as Qloo's.
  • Every stop explained. Each city card carries its affinity and rank, the audience's age and gender skew against baseline, the act's momentum, openers whose fans overlap the headliner's, sponsors whose audience matches, local venues for an afterparty or pop-up, and a plain-language "why here".
  • A map tour you can present. One click turns the plan into a self-running, full-screen tour: the route draws stop by stop, the camera flies to each city, and a card says why it is there.
  • Revise without a chat. Lock a city, drop one, drag the route, or type a change ("swap Boise for Phoenix, make it 9 stops"). Soundcheck proposes the edits as chips, and nothing re-runs until you confirm; each revision is a new plan linked to its parent.
  • A deliverable. Every plan has a shareable URL, a print-styled PDF view and a CSV export, and a visible agent trace of every Qloo call it made, redacted, with its status.

How we built it

Next.js 16 (App Router, TypeScript) on Railway, with Redis for plans and the Qloo response cache. The agent is a tool-calling loop on Claude through the Vercel AI SDK; the map is MapLibre GL on OpenFreeMap tiles, recoloured to the design system.

The agent. The model decides which cities from a curated regional pool to probe, when an entity is too thin and it should fall back to genre or occupation tags, and which tags fit a venue brief. A deterministic guard wraps it: a step cap, a coverage checklist (a plan is not complete until heatmaps, demographics, openers, sponsors and places have all run), and a status envelope on every tool result (ok, empty, partial, degraded, error, mirroring the official Qloo harness) so thin data is labelled as thin instead of papered over. Plans stream to the browser step by step.

Ten Qloo call types, each answering one promoter question:

Question Qloo call
Who is this act, exactly? GET /search (artist, person or podcast type), candidates confirmed before use
Which tags describe a venue or a fallback seed? GET /v2/tags with typo tolerance
Where is the affinity? /v2/insights, filter.type=urn:heatmap, per city (filter.location.query), seeded by the act
Who is the audience? /v2/insights, filter.type=urn:demographics
Is the act rising or flat? GET /v2/trending over the last eight weeks
Which local acts share the crowd? /v2/insights of the act's own type with signal.location.query, filter.exclude.entities and feature.explainability
How much do the fanbases overlap? GET /v2/analysis/compare, headliner against each opener
Which brands would sponsor? /v2/insights, filter.type=urn:entity:brand, filtered by the tour's age buckets
Where is the afterparty? /v2/insights, filter.type=urn:entity:place with location, tags and a popularity floor
What else does this audience love? /v2/insights, filter.type=urn:tag (the act's taste profile, used in the copy)

The underserved score is 0.6 × affinity + 0.4 × (1 − popularity) once affinity clears 0.5, so a city only counts as "untapped" when the taste is genuinely there.

A request, start to finish (Khruangbin, North America, 10 stops): /search resolves "Khruangbin" to one artist entity, shown with a picture, a description and links to confirm it is the right act → heatmaps score 42 candidate cities → demographics profile the audience → trending reads eight weeks of momentum → the agent routes the top cities with one travel day between stops → for each stop it asks for openers, compares their fanbases, shortlists sponsors and local venues, and writes a "why here" from the numbers. The trace at the bottom of every plan lists each call with its redacted parameters and status.

Built to be judged on. The three demos are pre-run and served from cache, so a click never waits on a rate limit. Qloo responses are cached by full URL server-side and never committed. Anthropic prompt caching on the tool loop cut billed input tokens by roughly 55 to 60 percent in our measurements.

Challenges we ran into

  • Making the model's copy specific. The first pass wrote the same sentence for every city. Rotating a lead angle per stop (momentum, an age skew, the gap between affinity and popularity, the route) and writing from the stop's own numbers fixed it.
  • Recording a WebGL tour honestly. The map tour is driven by JavaScript timers and camera flights, so we built a deterministic, frame-stepped player: a beat sequencer with exact pause and seek, which also gives keyboard control and a reduced-motion mode.
  • Revisions without re-running everything. A reorder recomputes legs and economics in about 20 ms without touching Qloo or the model. A full revision re-probes candidates from the Qloo cache and only asks the model to rewrite copy for stops whose neighbours changed.
  • Structured outputs. Anthropic structured outputs require every property, so optional revision fields travel as nullable on the wire and are mapped back to optional.

Accomplishments that we're proud of

  • The quadrant: one picture that shows the idea, which you cannot draw without Qloo.
  • The same agent plans a band, a comedian and a podcast tour. Only the seed entity changes.
  • Every number on screen says where it came from: Qloo, or a Soundcheck estimate.
  • The tour plays like a presentation, not a dashboard.

What we learned

Affinity and popularity are different signals, and the interesting cities live in the gap between them. Thin data is normal at the edges of a taste graph, so an agent that labels it honestly is more useful than one that fills it in.

What's next

A "without Qloo" side-by-side for the same inputs, author book tours, esports and brand roadshows on the same agent, and act-name autocomplete from /search.

What a plan does not establish

Qloo results are aggregate audience affinities, not predictions about any individual, and affinity is not a forecast of ticket sales. Routing, room sizes, travel costs and break-even figures are Soundcheck's estimates from public distances and editable rates; there are no hotel or flight prices. Coverage is thinner for comedians, podcasts and smaller cities, and the plan says so where it is. No personal data is sent to Qloo: the inputs are a public act, a region and a date window.

Built With

Share this project:

Updates

Submission history