Clients:

Own product — lukeduff.co.uk

Category:

Software Project

AEO Autopilot — Tracking & Fixing Brand Visibility in AI Search

Client: Own product (lukeduff.co.uk) · In development · Multi-tenant SaaS · Next.js 16, Supabase, Clerk, Inngest, Stripe

1 | Brief

More and more buying research now happens inside ChatGPT, Google AI Overviews, Perplexity and Gemini rather than on a page of blue links. A brand can rank perfectly well in traditional search and still never be named in the answer a customer actually reads. AEO Autopilot was built to make that visibility measurable, and then to do something about it.

The product runs a five-step loop: track whether a brand is cited for the questions its buyers are asking, diagnose which prompts it is losing and to whom, generate a publish-ready fix, push that fix live to the customer’s WordPress site, and re-check afterwards to see whether the answer changed. The intended positioning is that most tools in this space stop at monitoring — the fix and publish steps are the reason this one exists.

This is my own product rather than client work, and it is written up here as an engineering case study. The application is built, hardened and deployed, and is currently running in a keyless demonstration mode. It is not yet transacting: the production database wiring is outstanding and authentication is still on test keys.

2 | Key Goals

  • Query four AI answer engines for the same set of buyer prompts and record whether the brand was cited, merely mentioned, or absent.
  • Turn those results into a single 0–100 visibility score, weighted by prompt volume and engine importance, with a delta against the previous scan.
  • Identify which competitor domains the engines are citing instead, so the gap is specific rather than abstract.
  • Generate a publish-ready fix for each failing prompt — a short direct answer block, FAQ JSON-LD and a recommended heading structure.
  • Publish that fix straight into the customer’s WordPress site over the REST API, with a copy-and-paste bundle for anyone not on WordPress.
  • Enforce hard multi-tenant isolation and per-plan quotas, since one account’s scans and stored credentials must never leak into another’s.
  • Keep running costs predictable — engine calls are the unit cost of the product, so caching, concurrency caps and quota accounting had to be correct rather than approximate.

3 | Solution Snapshot

Problem Solution Implemented
Four answer engines, four different APIs, and no shared idea of what a citation is Built one engine interface over Perplexity’s sonar model, the OpenAI Responses API with web search, Gemini with Google Search grounding and Google AI Overviews via DataForSEO, then normalised every response into a single citation record with a cited / mentioned / absent status and the competing domains extracted.
Classifying answers with a language model makes the whole product fail the moment a key is missing or an engine errors Wrote a deterministic fallback judge — word-boundary and subdomain aware — that classifies citations without any model call. Every layer degrades rather than breaks, which is why the app can run live with no engine keys wired at all.
Scan quotas are the billing boundary, and a failing background job plus a stale-scan reaper can easily refund the same scan twice Moved quota accounting into atomic Postgres functions — one to consume a scan, one to fail and refund it — so a refund happens exactly once regardless of which process gets there first. Verified against the real database, along with a self-healing monthly period rollover so free accounts are never locked out.
Publishing means holding a customer’s WordPress credentials and fetching a URL they supplied — a textbook server-side request forgery risk All WordPress traffic goes through a guarded fetch that re-runs the private-address check on every redirect hop, drops the Application Password header on any cross-origin redirect, and blocks loopback, private, link-local, CGNAT, IPv6 ULA and cloud-metadata ranges. Stored credentials are encrypted at rest with AES-256-GCM and never returned to the browser.
WordPress strips JSON-LD script tags for any user without the unfiltered_html capability, so schema silently vanishes Detects each site’s schema capability on connect and picks the right path automatically — admin Application Password, the RankMath schema field, or a companion mu-plugin that prints the block in the head regardless of role. Fixes publish as drafts behind an atomic claim so a double-click cannot create duplicate posts.
A multi-tenant product that handles payments needed more scrutiny than a single developer can give it in one pass Ran several independent adversarial review passes across tenancy, the scan pipeline, WordPress publishing, billing and the code paths that only behave differently once real keys are present. Over twenty issues were fixed and re-verified — quota races, duplicate citations on retry, errored engine calls being scored as absences, and webhook idempotency among them.

4 | Impact

  • A complete, deployed product of roughly 14,900 lines across 147 files, covered by 71 passing tests and a green CI pipeline on every push.
  • The full loop is implemented end to end — track, diagnose, generate, publish, re-check — rather than stopping at a dashboard of numbers.
  • Multi-tenant isolation is enforced at the query layer with row-level security policies behind it, and every stored integration secret is encrypted at rest.
  • An independent security review of the launch build concluded it was fit to handle real customer data and payments, with the remaining items logged as documented fast-follows rather than left unstated.
  • Graceful degradation throughout means the application stays usable with partial or missing configuration, which is what allows it to sit live and demonstrable while the remaining accounts are wired up.
  • The build is complete and hardened; what is left is account setup — the production database, live authentication keys and payment configuration — before it can take its first paying customer.
Want something like this built? Get in touch →

What are you waiting waiting for?

Start Your Project Today
Book a FREE Call
footer shape