Inspiration

Ask a chatbot "I love Hindia and Spirited Away, what else would I like?" and you get the same safe list it gives everyone: a few famous names it already knows go together. It guesses from stereotypes. Ask the Qloo taste graph the same question and you get Reality Club, Danilla and Rumahsakit for the music, and an affinity score on every one, because it knows what people who love those two things actually love. I wanted to make that difference something you can feel in ten seconds, and something you would want to post.

What it does

  1. Pick up to five favourites. A song, a film, a series, a book, a podcast, a brand. Each one is looked up in Qloo's catalogue as you type, so the reel starts from the exact thing (Hindia the band, not the person) and not from a guess about it.
  2. Roll the reel. Reel asks Qloo what people who love those favourites also love, once for each of six domains: music, film, TV, books, podcasts and brands. A film-leader countdown shows each real call as it finishes.
  3. Watch it play back, card by card, full screen:
    • A title card that names your taste in a few words, like the title of a film ("Melancholy in Soft Light"), with one line about what ties it together.
    • One card per domain: the strongest match shown big with its Qloo affinity score, four runners-up, and one line about why, written from Qloo's own descriptions of those matches.
    • The Thread: the themes and moods Qloo tags on your matches (Identity, Intimate, Atmospheric…), ranked by how many cards they cross.
    • End credits: every match, rolling like the end of a film.
    • Keep it: a 1080 by 1920 story card of your reel, drawn in the browser and saved as an image.
  4. Ask your reel. After the credits, ask anything: "a film for a rainy Sunday", "a gift for a friend with my taste", "something for a long night drive". An agent works out which domain the question needs, turns its mood into Qloo tags, asks Qloo for matches from your favourites, checks whether they fit, tries again if they don't, and answers with poster cards, each with its affinity score and a reason. Every step it takes is shown as it happens.

For a Hindia and Spirited Away reel, "a film for a rainy Sunday" first finds no "rainy" tag for film, switches to Cozy, and comes back with Tune in for Love, 20th Century Girl and Miracle: Letters to the President. For a Phoebe Bridgers reel, "a long night drive" becomes Qloo's "On The Road" tag and returns Adrianne Lenker, Lucy Dacus, Big Thief and Lucinda Williams. An earlier version of the prompt answered the rainy Sunday with Indonesian horror films; reading the tags that came back and retrying is what fixed it.

The landing page is part of the product too. Its full-screen hero is a moving wall of posters and covers that Qloo links to one favourite. Type your own favourite into the hero and the wall recasts to that world: type Hindia and it fills with Indonesian films, series and bands.

What makes it Qloo-powered

Everything on a card comes from Qloo; the language model only names what Qloo found.

Step Qloo endpoint What it gives the reel
Picking favourites GET /search The exact entity with its type and cover art
Rolling the reel GET /v2/insights with signal.interests.entities set to your favourites, one call per domain (artist, movie, tv_show, book, podcast, brand) Up to nine matches per domain, each with an affinity score, Qloo's descriptive tags and its descriptions
The Thread Tags on those matches (theme, style, audience, mood types) The themes that cross the most domains
The hero wall GET /v2/insights for one favourite across four domains The posters behind the headline, recast live when you type

The agent (Ask your reel) runs a tool-calling loop over four tools, and the model decides which to call and in what order:

Tool Qloo endpoint What the agent uses it for
find_tags GET /v2/tags, scoped to a domain with filter.parents.types Turns the mood or occasion in the question into tags for the right domain
search_entities GET /search Looks up anything the question names
get_matches GET /v2/insights: your favourites as signal.interests.entities, plus tags as signal.interests.tags ("lean") or filter.tags ("must") Matches in the domain it chose; it calls again with other tags or another domain when results clash with the request
answer none Ends the loop with 2 to 6 picks. Any id that did not come back from get_matches is rejected, so it cannot invent a title

For the reel itself, a language model (Gemini, through an OpenAI-compatible API) reads Qloo's descriptions and tags of the strongest matches and writes three things: a two-to-four-word name for the taste, one sentence, and one line per card. It is told to write only from that data. Without Qloo there is nothing to name: no matches, no scores, no thread, no wall. If the model is unavailable, the reel still plays, named from the shared tags.

How I built it

  • Next.js 16 (App Router), React 19, TypeScript, plain CSS, deployed on Vercel.
  • A small Qloo client with an in-memory cache and retry with backoff on 429 and 5xx, since the hackathon key is rate limited.
  • The pipeline runs the six insights calls three at a time, removes your own favourites and duplicates from the matches, counts the thread from Qloo's descriptive tag types only (genre, format and market tags stay inside one domain and say little about a person), then names the taste.
  • Progress streams to the browser as NDJSON, so the countdown is real, not a fake loading bar, and the agent's tool calls appear one by one under your question.
  • The agent loop keeps Gemini's tool-call messages exactly as returned (its thought signatures must be echoed back), validates every id against what the tools returned, and retries the model with backoff when the free tier rate-limits a burst of turns.
  • The share card is drawn on a canvas in the browser; posters load through a same-origin proxy limited to images.qloo.com, so the canvas can be exported.
  • The landing wall is server-rendered and refreshed every six hours, with 240px posters, so it starts loading with the HTML. While posters arrive, the tiles flicker like a projector warming up.
  • Design: one burgundy ground and one bubblegum ink, like cinema velvet; Bebas Neue capitals against EB Garamond; posters shown in duotone on the wall and in full colour on the cards.
  • Privacy: reels stay in your browser (localStorage). Qloo responses are cached only in server memory and are never written to the repository.

Challenges I ran into

  • Finding the signal that crosses domains. My first "thread" counted every tag and came back with "Adult", "Audiobook" and "Fiction", all from books. Qloo's tags have types; keeping only theme, style, audience, character and mood tags turned it into "Identity, Intimate, Family, Love, Lyrical, Reflective" for Phoebe Bridgers and Little Women.
  • Making the agent listen to the question. At first it steered by the reel's own themes ("atmospheric") instead of the request, and a rainy Sunday came back as horror. Telling it that the question's mood is the request, giving it one-to-two-word tag queries, and having it read the tags on its results and retry fixed it.
  • Keeping the model honest. Early on it copied the example title from my prompt word for word. I removed every example title and told it to invent the name from the data in front of it.
  • Places and destinations. On the hackathon host, place insights timed out without a location and destinations returned the same list for every input, so the reel sticks to the six domains that answer reliably.
  • A hero that never looks empty. Moving the poster list into the server-rendered page, using Qloo's smaller image size and covering each tile until its poster has loaded removed the blank first second.

Accomplishments that I'm proud of

  • A reel rolls in about 6 to 15 seconds: six Qloo insights calls, run three at a time, plus one short model call.
  • The recommendations are specific in a way an LLM alone does not manage: for a Hindia fan it surfaces Reality Club, Danilla, Rumahsakit and Elephant Kind, with scores.
  • An agent whose every answer can be traced: you see each Qloo call it chose, and every pick is something the taste graph returned.
  • A landing page where the hero is the product: the wall you see is a live Qloo answer, and it changes when you type.

What I learned

How much a taste graph knows that a language model doesn't, and how little the model has to do once it has real data: name it, and get out of the way.

What's next for Reel

  • Compare two reels: see where two people's tastes overlap and what you would both love.
  • Places on the reel: cafés, shops and venues near you that match your taste, once location-based place insights are fast enough.
  • Share links that open someone's reel without sending them an image.

Built With

Share this project:

Updates

Submission history