Building a Public API for My Personal Hub (and AI Agents)
If an AI system is going to summarize your work, give it structured context instead of making it scrape and guess.
I added a public v1 API to my personal hub because I wanted the site to be readable by more than browsers.
HTML is great for people. JSON is better for tools.
If an AI agent, search system, recruiter workflow, or developer script wants to understand my work, it should not need to scrape UI text, guess which sections matter, or infer data from layout.
It should be able to ask for structured context directly.
The design constraint
This API is not a SaaS platform API. It is a public context API.
That changes the priorities:
- clarity over cleverness
- stable fields over maximal flexibility
- summaries over raw data dumps
- low-friction access over complex authentication
- rate limits and attribution over gatekeeping
The API is there to make public content on the site easier to consume, not to expose private business logic.
The response envelope
Every public content endpoint returns a consistent shape.
Collection responses include:
{
"api_version": "1.0.0",
"ai_summary": "Found 3 products. Statuses: active, in_development.",
"meta": {
"total": 3,
"returned": 3,
"locale": "en",
"generated_at": "2026-06-05T00:00:00.000Z"
},
"data": []
}
Single-item responses use the same idea, but return one object in data.
That envelope gives clients a few important guarantees:
api_versionmakes changes trackableai_summarygives agents a readable interpretationmetaexplains when and how the response was generateddatastays clean and predictable
Why include ai_summary?
Most APIs are built for clients that already know what they want — a script, an app, a dashboard.
Agent-facing APIs have a second consumer: the model.
The model can read the raw JSON, but raw JSON does not always communicate intent. A short summary helps the agent understand what the endpoint returned and how to use it.
For example, a projects response can say:
Found 4 project(s) tagged "ai". Returning 4. Technologies featured: TypeScript, Python, Next.js.
Each project includes a why_it_matters field that explains the motivation behind it.
That is useful context. It tells the agent what is included, what filters applied, and which fields matter.
The endpoint map
The API currently exposes:
GET /api/v1/me
GET /api/v1/projects
GET /api/v1/projects/:slug
GET /api/v1/products
GET /api/v1/products/:slug
GET /api/v1/notes
GET /api/v1/notes/:slug
POST /api/v1/newsletter/subscribe
POST /api/v1/inquiries
POST /api/products/feedback
The read endpoints are designed for public discovery.
The write endpoints support product operations: newsletter capture, inquiries, and product feedback. Product feedback lives outside the public v1 discovery surface because those records are operational data, not portfolio context.
Filters that match real discovery
The useful filters are intentionally plain:
localefor localized public contenttagfor projects and productsstatusfor active or archived workfeatured=truefor product highlightstopicandcategoryfor noteslimitandoffsetfor pagination
These are the filters I expect real consumers to use.
Someone might ask:
- "Show me active AI projects."
- "Find notes about Chrome extensions."
- "List featured products."
- "Summarize Orlando's work in Spanish."
The API shape follows those use cases.
Rate limits and public trust
The API uses a simple free-tier rate limit: 60 requests per minute per IP for public reads.
Feedback and inquiry submissions use stricter limits.
Rate limits aren't there to block anyone. They just keep the API stable for everyone using it.
Rate-limit headers communicate the rules without making the client guess.
The agent-friendly lesson
The main lesson is that agent-readable design is mostly normal API design with a little extra empathy.
You still need:
- stable schemas
- validation
- pagination
- CORS
- clear errors
- rate limits
But you also need to ask:
- Where could an AI get confused or miss the point?
- Which fields explain why this thing matters?
- Can the response summarize itself?
- Can a tool use this without scraping a rendered page?
That last question is the one I care about most.
I think that's where things are heading — pages for people, structured data for everything else. At least, that's the bet I'm making with my own site.
Notes from the build
More from the AI engineering trenches
Evals, observability, prompt design, and real lessons from shipping AI products. No fluff.
By subscribing, you agree to receive Orlando's emails. No spam. Unsubscribe anytime.