Install
Add @agentonboard/sdk to your backend and make your first verification call.
1. Install
npm install @agentonboard/sdkOne runtime dependency, jose. The package imports no Node builtin and no framework, so the same code runs on Node, Bun, Deno, Cloudflare Workers, and anywhere else a fetch global exists.
Four entry points:
| Import | Contains |
|---|---|
@agentonboard/sdk | verifyAgentToken, verifyAgentAccount, the types, the error descriptions |
@agentonboard/sdk/next | requireAgentAccount for a Next.js Request |
@agentonboard/sdk/express | requireAgentAccount for an Express (req, res) pair |
@agentonboard/sdk/hono | requireAgentAccount for a Hono Context |
2. Verify your first token
The smallest complete integration. It reads the header, calls the core verifier, and answers with your own status code.
import { verifyAgentToken } from "@agentonboard/sdk";
// `audience` is a literal in your source, never read off the request.
const AUDIENCE = "notes.com";
export async function verifyAgentRequest(request: Request) {
// Pass the header value as-is. A leading `Bearer` is stripped by the SDK.
const result = await verifyAgentToken({
token: request.headers.get("Authorization") ?? "",
audience: AUDIENCE,
});
if (!result.ok) {
// `code` is the stable branch; `error` is one sentence for a human.
return { ok: false as const, code: result.code, error: result.error };
}
return { ok: true as const, email: result.email };
}Wire it into a route:
import { verifyAgentRequest } from "@/auth/agent";
export async function POST(request: Request) {
const session = await verifyAgentRequest(request);
if (!session.ok) {
return Response.json(
{ code: session.code, error: session.error },
{ status: 401 },
);
}
return Response.json({ ok: true, for: session.email });
}This compiles and runs. It is deliberately not the finished integration: it answers 401 for everything, it hands you the email rather than one of your own user ids, and it has no account check. Mapping an identity to an account adds the second, and the error page gives you the status each failure should carry.
3. Check that the key endpoint is reachable
Verification needs our public signing keys, fetched from ${issuer}/.well-known/jwks.json on the first request and then cached for an hour per process. If the first call fails with KEY_SOURCE_UNAVAILABLE, that is a fetch that did not succeed against a cold cache — it is not a bad token.
A cold process fetches, and that fetch is a real request
The SDK owns no socket: it hands a URL to your runtime's fetch. The first verification in a fresh process therefore does make a network call, and a slow key endpoint can add up to 5 seconds to it. Every production page caveat about that is measured from here.
To confirm the wiring end to end before you build on it, mint a token for your own domain with the aon CLI and call your endpoint with it:
TOKEN=$(aon token get notes.com)
curl -i -H "Authorization: Bearer $TOKEN" https://notes.com/api/notesA 200 with a JSON body means the key endpoint was reachable, the signature verified, the audience matched, and the token was inside its 5-minute window. A 401 with a code in the body is the next thing to read: every code and what causes it.
What you have now
- The SDK installed, with one dependency and no runtime assumptions about your host.
- A verified request path that reads one header and makes no callback to AgentOnboard.
- A failure shape —
{ code, error }— that is safe to branch on and safe to show a human.
Overview
What AgentOnboard is, the identity and permissions boundary, the request flow end to end, and the zero-consent model you are inheriting.
Verifying a Token
verifyAgentToken in full — every option, the audience rules, what it returns, and the one documented exception to its non-throwing contract.