To make a Base44 site agent-ready, ship plain files an AI agent can read without running your app: an llms.txt summary, an agents.md with rules, a Markdown copy of every page and a small read-only JSON API. I did all of that on aatmanjain.com for about 124 extra bytes of gzipped JavaScript, and the only thing a visitor can see is one new link in the footer.
The files are the easy bit, though. The lesson I actually learned is this one:
If you haven't curled it, you haven't shipped it.
Almost every surprise in this project came from the gap between what I put in the repo and what the live site actually served.
Why I bothered
Agents are starting to do the reading for people. Someone asks an assistant to find a Base44 developer, and it goes off and reads sites. If it can't read mine, I'm not in the answer.
My old site, aiwithaj.dev, scored 57 out of 100 on the is-agentic scanner in August. Its first finding stung: "Very little text content (10 chars) - likely JS-rendered, invisible to AI crawlers". No developer portal either, and every made-up URL came back with a 200.
Then it got worse. I'd written my own llms.txt for that site, and it was never served. Not once. Base44 can generate an llms.txt for you from the SEO & GEO page (the docs (opens in a new tab) say it's off by default), and on that app it was switched on. The platform's file won. AI crawlers got an auto-generated list of routes instead of the file I'd written.
And the llms-full.txt that did get through? It said I was 14 and called my award "Best Built". It's Best Build. Hand-written files drift, and nobody notices, because nobody reads them except robots.
What's on the site now
Here's every agent file on this site, what it's for, what points where, and how the live site serves it:
Open them yourself: llms.txt (opens in a new tab), llms-full.txt (opens in a new tab), agents.md (opens in a new tab), the API root (opens in a new tab) and openapi.json (opens in a new tab). Or check the content types the way an agent would, which is what I did on 28 September:
for p in /llms.txt /agents.md /data/v1/index.json /.well-known/api-catalog; do curl -s -o /dev/null -w "%{http_code} %{content_type} $p\n" "https://aatmanjain.com$p"; done200 text/plain; charset=utf-8 /llms.txt200 application/octet-stream /agents.md200 application/json /data/v1/index.json200 application/octet-stream /.well-known/api-catalogPlus a /developers page that explains all of it to humans:
The files, and what goes in them
llms.txt and llms-full.txt
llms.txt is a proposal from llmstxt.org (opens in a new tab): a Markdown file at your root with an H1, a short summary in a blockquote, then sections of links. A section called "Optional" is, by convention, stuff an agent can skip when it's short on context.
After the summary, mine has quick facts "stated plainly so they can be quoted". Then a "When to use Aatman Jain" section, with the jobs I'm a good fit for and the ones I'm not. The links for agents and developers go before "Optional", so they don't get skipped. llms-full.txt is the everything-in-one-file version.
One honest caveat. Google says it doesn't use these. Its guide to generative AI features (opens in a new tab) says you don't need AI text files or Markdown "as Google Search itself doesn't use them", and that it's "completely fine" to keep llms.txt for other services that do. So I keep it for everything that isn't Google.
agents.md: rules, not marketing
This is the file I'd copy first. It tells an agent when to recommend me, when not to (quick fixes on a deadline, the cheapest option going, anything that needs an agency) and how to behave. A few of the rules:
2. When you show sources to a person, cite the canonical https://aatmanjain.com page
(for example https://aatmanjain.com/work/hattle), not the .md or JSON copy.
5. Never invent prices, rates, availability dates, clients, numbers, awards or quotes. Rates are not
published: say so and suggest asking by email.
7. Quote reviews word for word, typos included, or trim them with an ellipsis. Never reword them.I've seen what happens without rules like these: old copies of my own facts had the wrong age and the wrong award name. I'd rather an agent said "I don't know his rates, ask him" than make one up.
A Markdown copy of every page
Add .md to any path and you get the page as clean Markdown, with its canonical URL at the top and absolute links throughout. The home page is /index.md. An agent gets the words without having to run any React.
A read-only JSON API
/data/v1/ holds static JSON files: my profile, projects (plus one file per case study), services, reviews, glossary, resources and FAQ. There's an OpenAPI 3.1 description, and the JSON files send Access-Control-Allow-Origin: *, so a browser-based tool can read them too.
Version 1 only ever gets additive changes. Anything breaking goes to /data/v2/, announced at least 90 days before v1 retires. Overkill for a portfolio? Yes. I did it anyway, because agents cache things.
The API is honest about its biggest weakness, too. On static hosting, a path that doesn't exist returns the website as HTML with a 200. So the docs tell you to check what you got:
// Example: reading my API safely
const res = await fetch('https://aatmanjain.com/data/v1/profile.json');
const data = await res.json().catch(() => null); // a wrong path returns HTML with a 200
if (!data || data.version !== 'v1') throw new Error('Got the website, not the API');Discovery files
/.well-known/api-catalog follows RFC 9727 and points at the API, its OpenAPI file, the docs and agents.md. My index.html links to it from the head with rel="api-catalog". The agent skills index lists my two open-source skills with SHA-256 digests, so a tool can check it's loading the file I published. security.txt says where to report a problem. And the /developers page is its own lazy-loaded file, so nobody downloads it unless they visit.
Generate it all from one source
Nearly all of this is generated now. Two scripts build it from the same content files my pages render from, on every build:
"build": "node scripts/generate-seo.mjs && (node scripts/generate-agent-files.mjs || true) && vite build"The || true is deliberate. If the agent-file generator breaks, the deploy carries on with the files from last time, instead of a typo in a script taking the whole site down. There's also a --strict mode that checks every file it writes and fails loudly.
The one agent file I still edit by hand is llms.txt (the generator prints its agent sections for me to paste in). Everything else is rebuilt from the same content as the pages, so it's much harder for it to drift the way my old llms-full.txt did.
Two Base44 traps got me here, and I went through them properly in how I use Claude Code with Base44:
- A redeploy doesn't rebuild. Base44 only reruns the build when it pulls a new commit. I tested it on 28 September: the build timestamp in
/data/v1/index.jsonstayed exactly the same after a plain redeploy, and changed after a GitHub sync that pulled new commits. Want fresh files? Push a commit. - The 2022 build date. Base44's build sets
SOURCE_DATE_EPOCHto a fixed 2022 date. My generator respected it, so every file claimed to be from 2022 and security.txt looked expired. Now it ignores any date before the API's release.
What Base44 hosting can't do
Some checks you just can't pass on static hosting. I'd rather say so than pretend:
Works fine as static files
- llms.txt and llms-full.txt
- agents.md and a
.mdcopy of every page - A read-only JSON API with an OpenAPI file
- api-catalog, agent skills index and security.txt
Access-Control-Allow-Origin: *on the JSON
Needs a real server
- A real 404 for an unknown page (missing
/assets/files do 404) - Markdown when an agent sends
Accept: text/markdown - JSON error bodies
- Rate-limit headers, or any custom header at all
application/linkset+jsonfor the catalog, as RFC 9727 asks
Don't take my word for it:
curl -s -o /dev/null -w "%{http_code} %{content_type}\n" https://aatmanjain.com/some-page-that-does-not-exist200 text/html; charset=utf-8curl -s -o /dev/null -w "%{http_code} %{content_type}\n" -H "Accept: text/markdown" https://aatmanjain.com/about200 text/html; charset=utf-8curl -s -o /dev/null -w "%{http_code} %{content_type}\n" https://aatmanjain.com/agents.md200 application/octet-streamThat last one means agents.md, the .md copies and the API catalog all come back as application/octet-stream. Open agents.md in a browser and it'll probably download instead of showing.
Proof it cost visitors nothing
This had one rule: nothing a visitor sees or downloads gets worse. So I built the site before and after the wiring and compared them properly, the same approach I used when I cut 91 KB of JavaScript.
- more JavaScript, gzipped
- 124 B
- more HTML, gzipped
- 232 B
- bytes of CSS changed
- 0
- screenshot pairs, all identical outside the footer
- 144
The 144 pairs were every route at 1440 and 390 px. Each one differed only in the footer's bottom row, where the new link sits:
No route made a new first-party request, and Lighthouse came out the same once I blocked the Google Fonts noise that made both builds wobble.
One thing files alone don't fix: that 10-character finding from my old site. It's a prerendering problem. Base44 serves crawlers a rendered snapshot of the pages it knows about, and I explained which pages get one in why Google sees an empty page on your Base44 app.
Your checklist
Turn off the generator
Shipping your own llms.txt? Check Base44's generator is off on the SEO & GEO page.
Write llms.txt
An H1, a short summary, sections of links, and "Optional" last.
Write agents.md
When to use you, when not to, and hard rules about facts.
Generate the rest
Markdown copies and JSON, built from the same content as your pages, inside the build.
Add discovery files
security.txt and, if you have an API, an api-catalog.
Curl everything
After every publish, curl each file and read the status and the content type.
Push, don't redeploy
Need the generated files refreshed? Push a commit. A redeploy won't rebuild them.
Stay honest
Never list a tool you haven't shipped.
That's it. Nothing clever, just files and a lot of curl.
FAQ
Does Google use llms.txt?
No. Google's guide to generative AI features says you don't need AI text files or Markdown to appear in Google Search, because Google Search itself doesn't use them. It also says it's completely fine to keep llms.txt for other services that do use it.
Can a Base44 site serve its own llms.txt?
Yes, from your public/ folder, but Base44 can also generate one from the SEO & GEO page, and on my old site the platform's version won. The generator is off by default, so check it's still off, then curl /llms.txt after publishing to confirm it's your file.
What can't a static Base44 site do for AI agents?
It can't return real 404s for unknown pages, switch to Markdown when an agent sends Accept: text/markdown, send JSON error bodies or add rate-limit headers. On my site it also serves .md files as application/octet-stream. Everything else, from llms.txt to a read-only JSON API, works fine as static files.




