ValoBot

Valorant esports intelligence dashboard — live match, team and player data from VLR.gg plus CYPHER, a Groq-powered conversational analyst grounded in that live context.

Services
Product DesignEngineering
Industries
AI
Tools
Next.jsTypeScriptGroq
Highlight
A model with no cutoff, if it fetches first.
Live
valobot.vercel.app

A model with no cutoff, if it fetches first

Ask any language model who won last night and it will tell you something. It will be fluent, it will be specific, and there is no reason at all for it to be true — the match happened after training and the model has no way to know that it does not know.

Esports is the sharpest version of this problem. Rosters change mid-season, results land hourly, and a confident wrong answer about a match somebody watched is worse than no answer at all.

Scraped from VLR.gg
Context, then answer
Twelve VCT rosters
Live data first, then the model. Never the other way round.

The refusal is the feature

CYPHER fetches live context before answering — matches, rosters, standings — and answers from that. The part worth building was not the retrieval. It was the branch after it: if the fetch fails, it refuses rather than guessing.

That sounds like a small piece of error handling and it is the whole product. A dashboard that says "I could not reach VLR just now" is trustworthy. One that fills the gap with a plausible sentence is worse than a blank page, because you cannot tell the two apart from the outside.

It explicitly refuses to fabricate an answer if the fetch fails, rather than guessing.

Data
VLR.gg, scrapedLive matches and fixturesRegional standings
Model
Groq SDKGrounded on fetched contextRefuses on fetch failure
Coverage
12 VCT partner teamsPlayer roles and agent poolsAmericas · EMEA · Pacific
Stack
Next.js 15React 19GSAPVercel
Fixtures and results
Rosters and agent pools
Ask it anything, grounded

01 / 03

What it cost

Scraping is a maintenance commitment, not a feature. VLR.gg owes us nothing and its markup can change on any day; every selector is a small future outage. That is the honest price of building on a source with no API, and it was worth paying because the alternative was no live data at all.

The playstyle analyses are model-written, and the page should keep being clear about which parts of it are reported and which are generated. Fixtures are facts. A paragraph about how a team likes to play is an opinion a model formed, and those two things should never look the same on a screen.

Where it does not work yet

There is no caching layer worth the name, so a busy page does more fetching than it should — the design trades politeness to the source for freshness, and the balance is not right yet.

And the refusal path, which is the thing this project is actually about, is only as good as the failure detection behind it. A fetch that succeeds and returns stale or partial data is the case that still gets through, and it is the one worth building next.