
Demo video
Watch the product walkthrough
Outfox
Competitor research for marketing teams. It watches rival ads, videos, search and news, tags each finding by hook and audience stage, and links every claim to the public page it came from
Timeline
October 2026
Role
Creator
Team
Solo
Status
In-progressTechnology Stack
Key Challenges
- Citing Every Claim
- Honest Gaps in Public Data
- Bounded Search Budget
- Failure-Isolated Runs
- Ask Agent Guardrails
- Read-only Board Sharing
Key Learnings
- Evidence-first Data Modeling
- Guardrails Outside the Prompt
- Convex Actions and Crons
- Cost Accounting per LLM Call
- Designing for Missing Data
- Product Video Production
Outfox: competitor research with the receipts
Overview
Outfox is a competitor-research tool for marketing teams. It watches a rival's ads, YouTube videos, search results and news, tags each finding with the hook it uses and the audience stage it targets, and links every claim to the public page it came from.
A claim is one sourced fact, such as "this ad has run for 137 days". A brief is a short written summary built only from claims. Outfox stores claims first and builds everything else on top of them.
The first market is Indian D2C beauty. The demo workspace tracks Plum, Minimalist, SUGAR Cosmetics, WOW Skin Science and Mamaearth. The model is built to work for other categories, but only beauty is demonstrated so far.
Why I built this
Ad spend, reach and conversion figures for a rival are not in public data. Tools that show them are estimating, and I rarely saw the estimate labelled as one.
Outfox starts from the opposite rule: if public data cannot prove something, the product says so. A missing number shows as unavailable instead of a guess.
What it does
| Area | What you get |
|---|---|
| Brands | Track your own brand and rivals. Each brand page has Overview, Insights, Position, Placement, People and Evidence tabs. |
| Ads | Ads from the Google Ads Transparency Center, with format and how many days each has run. |
| Evidence | Every claim is a card that links to its source. Filter by source, hook, stage, date and freshness. |
| Tags | A hook type, such as discount offer, social proof, founder story or explainer, and an audience stage from "doesn't know the problem" to "ready to buy". |
| Signals | Reads pooled across all tracked brands, including what changed since the last check. |
| Ask | An agent that answers questions like "Which of SUGAR's ads ran the longest?" from stored claims. It shows each step it takes and cites the claims behind each sentence. |
| Boards | Save claims, arrange them on a canvas and share a read-only link. |
| Runs | Every check is a run with its plan, per-source status, request count and cost. |
How it works
Core components, runtime flow, and durability boundaries.
The six sources are Google search, Google Ads Transparency Center, YouTube search, YouTube video detail, Google News and Google Trends. Each one is a SerpApi call. Extraction turns each raw response into claims.
Engineering decisions
Every sentence has to cite a claim
The brief and Ask models only receive claims and may only cite their ids. A guardrail then checks the output and drops any sentence that cites an unknown claim or states a number that is not in its claim. The check runs in code, so it does not depend on the model following a prompt.
Runs fail one source at a time
A run is created first, and every raw response and claim attaches to it. A bounded worker pool fetches the sources, so one failing source never aborts the others. A run closes as complete, partial or failed, and a cron closes any run left open past 30 minutes.
Gaps are shown as gaps
"Not checked yet", "nothing found" and "check failed" are three different states, and the interface renders them differently. Competitor ad spend, reach, follower counts and conversion numbers are shown as unavailable because public data cannot support them.
Search credits are a hard budget
SerpApi gives a fixed monthly allowance, and the app header shows the credits left. A live refresh needs an explicit confirmation, runs through a bounded pool and records its request count on the run. Development runs against stored data and a cached seed, which cost no credits.
LLM calls have a fallback and a cost record
The model path goes through the Vercel AI SDK with OpenRouter, AI Gateway or Google as providers. With no key set, tagging falls back to keyword rules and briefs fall back to a template. Each call records its cost: exact for OpenRouter, estimated for Google.
Testing
The repo has 116 verification scripts that run as plain Node checks with injected stubs, so they make no live SerpApi calls. A single command runs them all and reports each as pass, fail or skipped, with no silent skips.
Access and source code
The live app is closed to public sign-up, so new users come in through a request-access form. The demo video above shows the full flow.
The public repository is a view-only snapshot of the interface: the landing page, the app screens and the component library. The backend, agent prompts and tools, tests and planning documents are private.