-
-
Rank lift at a glance: Qloo moves Denver ChopHouse & Brewery up 13 places when it knows members' brands — with brand shares and a map.
-
Setup: a fictional Denver credit union enters the brands its members already love (aggregated, e.g. from card spend).
-
The agent resolves each brand in Qloo and proposes categories. Every category cites a real Qloo tag as evidence — you confirm.
-
Research runs per branch and category: Qloo ranks nearby places with and without member brands, then code filters and scores.
-
Act on the list: Independents only, follow-up status, Copy pitch, and Export CSV — no login needed.
Inspiration
Small credit-union marketers need local member perks, but each quarter they can only call a few shops — and “popular nearby” is not the same as “our members will love this.” Perk Desk uses Qloo’s taste graph to turn member brand lists into a shortlist of unsigned local merchants, ranked by how much each shop rises when Qloo knows those brands.
Card-linked platforms mostly push national brands. Community credit unions compete on neighborhood. Spend reports show where members already shop; they do not say which unsigned independent to call next. That gap is a taste problem. Qloo connects brands people love to real places, so we built an agent around that signal — not around another generic “recommend something” LLM demo.
What it does
Perk Desk is a research agent for the person who runs the member-perks program at a small credit union (often one part-time marketer).
- Set up once (no login): name, city, 1–5 branches (Find branches via Qloo, type an address, or click the map). Optional signed-merchant and business-member lists. Profile stays in the browser only.
- Member taste: paste 1–10 aggregated brand names (for example top brands from card spend) or pick a quick segment.
- Plan: the agent resolves each brand in Qloo and proposes 2–6 place categories. Every category shows evidence — a real Qloo tag from one of those brands.
- Confirm: the user edits categories (up to 5) and clicks Confirm & find merchants. Nothing is searched before that.
- Research: for each branch and category, Qloo ranks nearby places twice — once seeded with member brands (with explainability), once as a plain baseline. Code filters closed places, noise (malls, supermarkets, …), national chains, and already-signed names, then scores the rest.
- Shortlist: about 10 merchants with rank lift (for example
+13 places vs. baselinefor Denver ChopHouse & Brewery in the Denver demo), which member brands drive the match, distance, ratings, map pin, a short recruiting pitch (Copy pitch), Independents only, follow-up status (To contact / Contacted / Signed / Not a fit), and Export CSV.
What makes it Qloo-powered: without signal.interests.entities there is no rank lift, no brand shares, and no category evidence — only “popular places nearby.” An LLM alone cannot know that members of this credit union are more likely to love this shop than the one next door.
Demos (Try Denver demo / Try Austin demo) use fictional credit unions. Unchanged demos may show “Replaying a cached research result.” This is intentional, so judges can try the full flow in seconds.
How we built it
- Next.js 16 + React + TypeScript on Vercel; Leaflet + OpenStreetMap for the map.
- Agent: Vercel AI SDK tool-calling with DeepSeek (temperature 0). Two endpoints so a human can confirm in the middle:
/api/plan(brands → categories + evidence) and/api/run(merchants → score → pitches), streamed as NDJSON. - Qloo API:
/search(brands + branch lookup),/v2/tags(place categories),/v2/insights(places with location, radius, category tag, brand signals, explainability, and a baseline without signals). - Deterministic scoring in unit-tested code (
0.40affinity +0.25rank lift +0.20distance +0.15rating). The LLM never ranks merchants. - Guards: categories must come from this run’s Qloo results and cite a real brand tag; pitches are checked in code (≤3 sentences, must name the merchant, every number must appear on the card); failing pitches fall back to a template; if DeepSeek is down, Fallback mode still runs on Qloo.
- Upstash Redis for shared cache and daily rate limits so the public demo stays free and within API budget.
- 1,457 offline unit tests in 102 files (no live API calls in
npm test), plus lint, TypeScript, a privacy scanner, and a 15-case live category eval.
Challenges we ran into
- Ambiguous brands. “REI” also matches sports clubs and fashion labels. We keep top Qloo candidates, prefer exact/prefix matches, let the agent decide, and let the user switch in the UI.
- Keeping the LLM honest. Weak category reasons and invented pitch numbers showed up early. Evidence checks, human confirm, and the pitch number guard fixed that.
- Noisy place results. Category queries return supermarkets, stadium stores, and chains. Genre filters, a chain list, same-name detection, and a Qloo brand check on shortlisted names cut the noise.
- Location without a separate geocoder. Qloo locality queries are approximate, so we added map picking, branch lookup by institution name, and a bundled table of US city centers for common
City, STinputs. - Free public demo, limited API budget. Per-request Qloo caps, daily per-IP and global limits, and caching — cached demos never count.
Accomplishments that we're proud of
- A complete Monday-morning workflow: setup → explained shortlist → pitch → status → CSV, with no account.
- A taste signal a non-engineer can trust: “member taste moved this shop up N places, mostly because of these brands.”
- Clear split of labor: the agent resolves ambiguity, picks categories, and writes pitches; code filters, scores, and fact-checks.
- Privacy by design: aggregated brands only, demographic brand tags filtered out, profile only in the browser.
What we learned
- Taste graph value shows up in differences. Seeded vs baseline turned Qloo output into a metric marketers understand.
- A confirm step in the middle builds more trust than full autonomy for a business call list.
- Small API details matter: typed query helpers and unit tests catch silent ignored parameters.
What's next
- Pilot with a real credit union using its own aggregated top brands from card spend.
- Shared team workspaces and synced statuses (today statuses are per-browser).
- Quarterly re-runs that highlight merchants new since last time.
- Light outreach help: contact workflow and offer templates.
Testing instructions for judges
No login or access code. Desktop and mobile browsers.
- Open https://perk-desk.vercel.app.
- Under Or explore a demo with a fictional credit union, click Try Denver demo (or Try Austin demo).
- Click Plan merchant categories. Check Recognized brands and category evidence, then Confirm & find merchants.
- Watch Research progress. On Your merchant shortlist, open a card: rank lift, brand shares, Recruiting pitch. Try the map, Independents only, a Follow-up status, Copy pitch, and Export CSV.
- Optional live research: Start with my credit union, enter a name and
City, ST, Find branches (or add a branch on the map), enter brands, then plan and confirm. Examples: Bellco Credit Union /Denver, CO, or University Federal Credit Union /Austin, TX.
Notes: unchanged demos replay cache in about 5 seconds and are unlimited. Live research has shared daily limits (10 runs/IP, 150 global); demos still work when live research pauses. All demo institutions and brand lists are fictional.
Built With
- deepseek
- leaflet.js
- next.js
- openstreetmap
- qloo-api
- react
- tailwindcss
- typescript
- upstash-redis
- vercel
- vercel-ai-sdk
- vitest
- zod

Log in or sign up for Devpost to join the conversation.