A public "get your free scorecard" product. The analysis engine digests homepage positioning, selects competitors, fans out across data APIs (Moz and other SEO/authority sources, plus search context), and renders a personalized AI search readiness scorecard. It generated $700K in pipeline in a few weeks. This page is about the plumbing I built around that engine so thousands of signups couldn't crash it, double-bill it, or expose it.
The analysis engine takes a long time per company and costs real money every time it runs: it digests homepage positioning, picks competitors, hits external APIs (Moz and similar SEO/authority endpoints, search context), scores AI search readiness, and renders the scorecard views. None of that site-reading / competitor-picking is secret sauce — anybody can do those steps. Marketing wanted the whole thing as a public lead magnet. Putting a slow, expensive multi-API engine directly on the public internet is how you get abuse, double-billing, and timeouts.
The answer was a deliberately small connector that owns intake, queueing, storage, and projection — and explicitly does not own how the engine analyzes a company. Clear ownership boundaries meant the frontend designer, the backend owner, and I could all ship independently. What follows is the connector story, not a blueprint of the scoring product.
flowchart TD
IN[Lead form + operator requests] --> Q[Connector queue]
Q --> DEDUPE{Already running
for this domain?}
DEDUPE -->|Yes| REUSE[Reuse it
no double billing]
DEDUPE -->|No| ENG[Analysis engine]
subgraph WORK["Inside a run"]
SITE[Digest homepage positioning]
COMP[Select competitors]
APIS[Moz + SEO APIs + search context]
end
ENG --> WORK
WORK --> CHECK[Periodic check-in
until done or failed]
REUSE --> CHECK
CHECK --> OUT[Public scorecard
+ team dashboard]
style ENG stroke:#10b981,stroke-width:2px
style OUT stroke:#8b5cf6
In plain English: on a schedule, the connector checks on running analyses, revives ones that got stuck, gives up on lost causes, and feeds new requests to the engine at a pace it can handle. A burst of signups can never overwhelm it.
flowchart LR
WAIT[Waiting] --> RUN[Running]
RUN --> DONE[Done]
RUN --> RETRY[Stuck? retry]
RETRY --> RUN
RUN --> FAIL[Give up]
WAIT -.->|paced| RUN
style DONE stroke:#10b981,stroke-width:2px
style FAIL stroke:#f59e0b