Inspiration
San Antonio is full of small, often family-run and Spanish-speaking businesses: tax offices, notaries, immigration helpers, contractors. They lose customers to competitors on Google Maps without knowing why. Their websites are missing basics like a page title, a description, or business info search engines can read. Agencies charge a lot to fix that, and the reports they hand over are written for marketers, not owners.
These same owners are also targets for scams: fake "Google listing" calls, phishing emails, payment requests pretending to be a supplier. We wanted one tool that cracks their website's case open, shows them the money they're missing, fixes it for them, and watches their back.
What it does
SEO Heist (seoheist.app) is a bilingual English and Spanish "case file" for local businesses.
- Free scan: the owner enters their website and business details and gets a Heist Score, with plain-language findings for problems like titles, descriptions, canonical tags, Open Graph tags, business schema, robots and sitemap, and indexing.
- Market check: works out what the business actually offers from its Google Maps categories and website, finds real San Antonio search volume from Google Ads, checks Google Maps rankings for each service, compares them with real competitors, and shows a "what if" money estimate based only on numbers the owner enters.
- The Mastermind (automatic fixes): the owner connects GitHub with one click. Our worker reads the site's code, writes a fix for every page (unique titles and descriptions, social sharing tags, and LocalBusiness schema taken only from facts already in the site), and opens a pull request. Nothing changes until the owner merges it, and Undo closes the pull request.
- The Shield: owners paste a suspicious message, upload a photo, voicemail, video or PDF, or forward an email. They get a scam risk rating with the tactics explained in both languages. It also has a learning library built from FTC, FBI IC3 and Google sources, and a live scam news feed.
- Admin dashboard: customers, sites, audits, worker jobs and system status.
How we built it
- App: built in Lovable on TanStack Start (React 19, Tailwind, shadcn), with Lovable Cloud for sign-in, the database and live updates, running on Cloudflare. It speaks both languages throughout.
- Worker ("The Mastermind"): a Node and TypeScript service on Railway that runs jobs from a Redis queue. Its AI agent runs on the Claude Agent SDK pointed at DeepSeek models. It has an HTTP API and an MCP endpoint, so AI agents can call tools like
repo_scan,propose_fixesandapply_fixtoo. - GitHub fixes: a GitHub App with short-lived install tokens. Fixes are committed with GitHub's API and always land on a new branch as a pull request, never on the main branch.
- Data sources:
- SerpApi for Maps rankings and competitors
- Google Ads Keyword Planner for search volume
- Google PageSpeed for page speed
- Gemini for figuring out services and analyzing uploaded files
- bundle.social for connecting social accounts
- SendGrid for email and for receiving forwarded scam emails
- Security: the app and worker talk over a shared token, and every callback is signed with a secret both sides know. All secrets stay on the server.
Challenges we ran into
- Lovable's new site format: most Lovable sites now keep their SEO tags inside each page's code instead of a single HTML file. We had to teach the worker to read and safely edit that code without breaking the site.
- Getting the facts right: our first business-info fix wrote opening hours in a format Google doesn't accept. We added a strict pass that converts hours to the correct format, and if any value can't be read, it leaves hours out instead of guessing.
- Changing course mid-build: we started with a WordPress plugin, then switched to GitHub pull requests because that's a safer and more universal way to change a site.
- Data rules: we removed Ahrefs from the product after reading its terms. Competitor keywords now come from Google Ads instead.
- Location bugs: we found keyword volume quietly falling back to national numbers, and "near me" searches returning results from the wrong city. We fixed the first, and the second is still on the list.
- Social account limits: working within bundle.social's import limits and keeping each customer's social accounts private on one shared team.
Accomplishments that we're proud of
- A real end-to-end test: on a test site seeded with 38 planted SEO problems, the worker found 68 issues across 12 pages, wrote 37 fixes, and opened a real pull request. The business name, email and address in the fix matched the site's own data exactly.
- Owner control: fixes always arrive as a pull request the owner reviews, and they can undo with one click. Nothing changes without them.
- Grounded data: no made-up sample data anywhere. Every number comes from a real source or from the owner.
- Built for real owners: a scam shield for the people who get targeted most, in their own language.
What we learned
- Most of the work in SEO is in the small details. A title that's 4 characters too long or hours in the wrong format is the difference between helping and hurting.
- AI should write the words, but plain code should make the edits. We let the model write titles and descriptions and assembled everything else with strict rules.
- Pull requests are a great safety net for automated changes: easy to review, easy to undo, and they leave a record.
- Checking a vendor's data terms early saves a rebuild later.
What's next for SEO Heist
- A Fix Queue in the Mastermind, so owners can approve fixes one by one.
- More automatic fixes: headings, image alt text, canonical tags and sitemaps generated from the live site address, and pages blocked from search engines.
- Fixing "near me" searches so they use the business's own city.
- WordPress and other website builders beyond GitHub.
- Scheduled Lookout scans that alert owners when their rankings or site health drop.
- Expanding from San Antonio to other bilingual communities.
Built With
- claude
- github
- lovable
- railway
Log in or sign up for Devpost to join the conversation.