Example app: Overview
The notes app (github.com/atpaawej/notes-app) — a real, deployed reference implementation of an AgentOnboard partner API
Example app: Overview
The notes app is a real, deployed note-taking service that exposes its data to AI agents through AgentOnboard. It is the reference implementation for this guide: the full source is at github.com/atpaawej/notes-app and the live app runs at notes.aawej.in.
What it is
Notes is a personal notebook with a Notion-like block editor, tag-based organisation, and full-text search. Humans use it through a normal web app; AI agents use it through two programmatic surfaces:
| Surface | Who uses it | Auth |
|---|---|---|
REST API (/api/*) | AI agents | AgentOnboard session token in the x-session-token header |
| MCP server (SSE) | AI clients like Claude | API keys (nt_…) with read / read_write scopes |
The REST API is the AgentOnboard integration and the subject of the next two pages. The MCP server authenticates with its own API keys and is independent of AgentOnboard.
Stack
| Layer | Technology |
|---|---|
| Web app | Next.js 16 (App Router) + TypeScript + React 19 |
| Editor | BlockNote (ProseMirror blocks, stored as JSON + plain text) |
| UI | shadcn/ui, dark mode only |
| Database | Neon Postgres via Drizzle ORM |
| Human auth | Firebase Auth (Google OAuth) + session cookies |
| Agent auth (REST) | AgentOnboard session tokens via @agentonboard/sdk |
| Agent auth (MCP) | API keys hashed with bcrypt |
| Deploy | Vercel (web + REST API), Cloud Run (MCP server) |
The architecture
Notes is a monorepo with two packages that matter here: apps/web (the Next.js app, including the /api/* routes) and packages/db (Drizzle schema and business-logic services shared by both surfaces).
The AgentOnboard flow through the REST API:
The agent gets a session token
The user mints a 5-minute session token with aon token get.
The agent calls the notes API
The token travels in the x-session-token header — for example GET https://notes.aawej.in/api/notes.
Notes verifies the token
The route handler reads the header and calls verify() from @agentonboard/sdk with the app's partner key (in the AGENTONBOARD_PARTNER_KEY environment variable). AgentOnboard returns the user's email.
Notes resolves the user
The email is looked up in the notes database. Every note belongs to a user, so the email decides whose notes the agent can see — and a token whose email has no local account is rejected.
Notes serves the data
The handler runs the query for that user and returns the result.
Two details make this work and are worth copying:
- Email is the join key. The session token maps to an AgentOnboard email, and Notes maps that email to a local user. There is no auto-provisioning — the person must sign up at notes.aawej.in first. This is the same email-is-the-join-key policy every partner relies on.
- Auth is a shared check, not per-route. Every
/api/*route runs the sameverifySessionToken()helper before touching data, and maps failures through oneauthFailureResponse()function — the next page covers both in detail.
Pages in this section
- REST API integration — the
x-session-tokenheader, theTokenVerifyResultunion, and how error codes become HTTP responses - The action: create & read notes —
GETandPOST /api/notes, the exact endpoints an agent calls, with a worked end-to-end example
Next steps
SDK & verify
The complete POST /api/verify contract — request shape, every HTTP status and error message, response shapes, and the @agentonboard/sdk client
Example app: REST API integration
How the notes app authenticates agents — the x-session-token header, verifySessionToken, the TokenVerifyResult union, and the authFailureResponse HTTP mapping