Two weeks ago I watched an agent run a full product launch on Waitlister, my waitlist tool.
It created the waitlist, generated and published a landing page, signed up a test address, checked the signup was real by fetching the public page unauthenticated, then unpublished and deleted everything it had made.
Nobody touched the dashboard.
The interesting part isn't that run. It's what I found while getting there, because almost none of it was visible from a browser.
Why I bothered
My users are pre-launch founders, which is exactly the group now building landing pages by prompting Claude, Cursor, or v0 instead of opening a site builder. "Add a waitlist to my site" is a normal thing to ask an agent to do, and increasingly nobody types my product name at all.
The uncomfortable part is when an agent hits a 404 or installs a package that doesn't exist, it doesn't debug. It picks a different tool in the next sentence and never tells the user it switched. You lose without ever seeing a bounce.
What I shipped, in order of how much it turned out to matter
- Full API coverage for the whole job. Not most of it. More below, because this one was worth the other five combined.
-
A
skill.mdroute. One page written for an agent rather than a person: a decision tree (no API key yet, go this way; account key, go that way), both code paths, and a self-check at the end so the agent can confirm it worked. -
An OpenAPI spec at a fixed URL. Valid 3.0.3 at
/openapi.json, all five endpoints, auth, rate limits, error shapes. Endpoint changes update the spec and the SDK types in the same PR or they don't merge. - A real npm SDK, plus four aliases under the names an agent is likely to reach for.
- An MCP server, 14 tools, so agents that speak MCP get typed calls instead of reading my docs.
-
llms.txtandllms-full.txt, an index of the docs in plain text with a short block at the top saying what this product is and where the golden path starts.
What was broken
Honest list.
The file I wrote for agents was the one file agents couldn't read. My llms.txt is proxied from a vendor, the proxy forwards the caller's user-agent, and the vendor had AI-bot blocking switched on by default. Every AI crawler got a 403 on the document whose only purpose is being read by AI
crawlers. I found it by requesting my own files with eight bot user-agents and diffing the status codes. One vendor toggle can put it back, silently, which is why the check now runs on a schedule.
llms-full.txt is too big to be read at answer time. It's 961 KB and grows with every docs page. It serves from my side in about 1.3 seconds, and Claude's answer-time fetcher still timed out on it at 60 seconds. The small index is the one that actually gets read. I haven't fixed this yet;
the options are trimming it or splitting it, and I've done neither.
Agents guess your package name. waitlister-js, waitlister-sdk, waitlister-node, @waitlister/sdk. Instead of arguing with that, I published all four as real packages that re-export the SDK and carry a deprecation notice pointing at the canonical name. A wrong guess installs and self-corrects.
My email validator rejected valid addresses. Agents test with plus-tags, because that's how you make a disposable address on an account you already own. My validator refused some of them. Human users with Gmail aliases had been hitting the same wall for as long as the rule existed.
My 404s weren't 404s. Unknown doc slugs returned a soft page with a 200. An agent reading status codes concludes the page exists and that it guessed the URL right, then builds on it. Real 404s, plus a 301 from the old getting-started URL.
The single page that would have saved five fetches was labeled for the wrong reader. In the first live test the agent's own friction report said the docs were split across pages with no single page giving the complete picture, so it fetched five. skill.md is that page, and /docs/api linked to it in a callout at the very top. The callout was headed "Integrating with an AI agent," which is a label about who it's for, and the agent was reading through a fetch-summarizer where that reads as a sidebar. Reframed as "Fastest path: complete single-page integration guide," it started landing. The link was never missing. It was filed under the wrong thing.
Every run used to die at the same sentence. The agent could create a waitlist through the API and then had to say "now open the dashboard to build your landing page." That one gap ended the automated path every time, no matter how good the rest of the surface was. Creating, updating, and publishing a landing page over the API is what made an end-to-end run possible at all.
The one thing I'd tell someone starting this
Test with the real fetchers, not with curl. Every failure above lived in the gap between what my server sends and what an agent's toolchain actually receives: a user-agent rewritten in transit, a file that serves fine but times out at answer time, a status code that lies, a link that survives the fetch but not the summary. Curl told me everything was fine. It was, for curl.
Where I've got to: four consecutive live runs with zero wrong guesses, a complete correct integration plan from public surfaces alone in about 90 seconds, and a waitlist created from an empty account in three minutes and eighteen seconds.
Check it yourself
All of it is live. If you want to see what an agent actually receives, point yours at waitlister.me/skill.md and ask it to set up a waitlist.
The same path written for a person is at waitlister.me/growth-hub/guides/set-up-waitlist-with-ai-agent.
Top comments (1)
This is a really interesting direction for SaaS. If AI agents are becoming active users of software rather than just assistants for humans, making a product “installable” and discoverable by agents could become an important part of product architecture.
I also like the shift in thinking from building for a human-only interface to designing workflows that agents can actually understand and execute reliably. It'll be interesting to see how authentication, permissions, and pricing evolve as more software starts being consumed this way.