REST API.
Every endpoint is JSON over HTTPS. The base URL is http://localhost:4000 in development and https://api.pambase.io in production. Endpoints are grouped below by audience: the OAuth handshake, the app-facing surface, public discovery, the developer portal, and the user-facing Hub.
- App-facing endpoints use
Authorization: Bearer <connection_token>— the token your app received fromPOST /v1/oauth/token. - Developer portal and Hub endpoints use a logged-in session cookie.
- Discovery endpoints are public or accept either credential.
Errors share one envelope — { "error": { "code", "message", "details?" } }. See Errors for the full status → code table, and Limits for the caps that produce 402 limit_exceeded. The shared vocabulary for scopes, event types, and intents lives in the Catalog.
Everything below is also served as an OpenAPI 3.1 document at GET /v1/openapi.json — import it into Postman, Insomnia, or a client generator. These tables render from the same source, kept in lockstep with the live routes by a CI check.
OAuth
The three-legged flow that turns a user's consent into a connection token. Read the end-to-end walkthrough in Connect flow; the concepts behind it are in Permissions and Manifest.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /v1/oauth/preview | public | App + manifest to render a consent screen |
| POST | /v1/oauth/authorize | user session | User approves → one-time code (10 min TTL) |
| POST | /v1/oauth/token | client creds | Exchange the code for a connection token |
GET /v1/oauth/preview
Public. Used to render the consent UI: the requesting app and the scopes its manifest declares.
curl "http://localhost:4000/v1/oauth/preview?slug=my-app"
{"app": { "name": "My App", "slug": "my-app", "iconUrl": "https://..." },"manifest": {"scopes": ["identity:read", "memory:read:fitness", "memory:write:fitness"],"eventTypes": ["workout.completed"],"intents": ["coach"]}}
POST /v1/oauth/token
Exchange the one-time code for a long-lived connection token. Authenticate with your app's client_id and client_secret (never expose the secret in a browser).
curl -X POST http://localhost:4000/v1/oauth/token \-H "Content-Type: application/json" \-d '{"code": "oc_a1b2c3...","client_id": "app_123","client_secret": "sk_live_..."}'
{"connection_token": "ct_9f8e7d...","ai_id": "ai_42","scopes": ["identity:read", "memory:read:fitness", "memory:write:fitness"]}
buildConnectUrl(...) and exchangeCodeForToken(...) wrap the redirect and the token exchange. See the SDK reference.
App-facing
Everything you do with a live connection. All endpoints require Authorization: Bearer <connection_token>. Reads and writes are filtered by the scopes the user granted — a request never sees memory outside its granted scopes, and POST /v1/memories silently drops any memory whose scope you weren't granted to write.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/identity/brief | identity:read | One-paragraph natural-language brief of the user (cached 5 min) |
| GET | /v1/connection | always | This connection: ids, scopes, status, app, and the user's profile |
| GET | /v1/quota | always | getUsage(): hosted-LLM usage + remaining monthly quota for this app's plan |
| POST | /v1/signals | signal:emit | Emit an ephemeral signal — fans out to subscribers, never stored as memory |
| POST | /v1/memories | memory:write:<scope> | remember(): write natural-language memories (accepts Idempotency-Key) |
| GET | /v1/memories | memory:read:<scope> | List/recall memory (?query → relevance search; cursor-paginated) |
| GET | /v1/memories/:id | memory:read:<scope> | Fetch a single memory |
| GET | /v1/memories/:id/graph | memory:read:<scope> | Graph neighbors of a memory |
| PATCH | /v1/memories/:id | memory:write:<scope> | Edit a memory (content, importance, pin, scope) |
| DELETE | /v1/memories/:id | memory:write:<scope> | Delete a memory |
| GET | /v1/context | context:read:<intent> | Assembled context bundle for an intent |
| POST | /v1/gateway/chat | ai:host:chat | ai:host:companion | Hosted chat turn (BYOK alternative) |
| POST | /v1/gateway/chat/stream | ai:host:chat | ai:host:companion | Same, streamed over SSE |
| POST | /v1/schedule | any connection | Create a scheduled trigger |
| GET | /v1/schedule | any connection | List your scheduled triggers |
| DELETE | /v1/schedule/:id | any connection | Cancel a scheduled trigger |
GET /v1/identity/brief
A ready-to-prompt paragraph about the user's assistant — emphasizing the display name and a one-line tone note. Cached for 5 minutes. See Identity brief and Identity.
curl http://localhost:4000/v1/identity/brief \-H "Authorization: Bearer $CONNECTION_TOKEN"
{"brief": "Goes by Nova. Prefers concise, encouraging replies and metric units.","ai_name": "Nova","generated_at": "2026-05-21T10:00:00.000Z","source_memory_count": 37,"cached": true}
POST /v1/memories
The write path — remember(). Submit one or more natural-language memories; PAMbase persists only those whose scope is covered by a memory:write:<scope> grant (the returned memoryIds reflect what landed). A write to an unknown top-level scope is rejected (400); kind, by contrast, is a free-form advisory hint and is never rejected (it defaults to event). See Remember & recall.
curl -X POST http://localhost:4000/v1/memories \-H "Authorization: Bearer $CONNECTION_TOKEN" \-H "Content-Type: application/json" \-d '{ "memories": [{ "content": "Ran 5k in 28:10.", "kind": "event", "scope": "fitness.running" }] }'
{"accepted": true,"memoryIds": ["mem_1c2d..."]}
POST /v1/signals
Emit an ephemeral signal (requires signal:emit). It fans out to subscribed apps' webhooks as signal.created and is never stored as memory. See Signals.
curl -X POST http://localhost:4000/v1/signals \-H "Authorization: Bearer $CONNECTION_TOKEN" \-H "Content-Type: application/json" \-d '{ "type": "calendar.slot_free", "payload": { "start": "14:00" } }'
GET /v1/memories
List memory in a scope, or recall across granted scopes. Pass ?scope= to filter, ?limit= to page, and ?query= to switch to relevance (vector + keyword) search. See Memory and Vector + graph.
curl "http://localhost:4000/v1/memories?scope=fitness&query=marathon&limit=5" \-H "Authorization: Bearer $CONNECTION_TOKEN"
{"memories": [{"id": "mem_1c2d...","type": "goal","scope": "fitness","content": "Training for a spring marathon, target sub-4:00.","importance": 80,"confidence": 90,"pinned": true,"occurredAt": "2026-04-02T09:12:00.000Z","sourceApp": "my-app"}],"next_cursor": null}
GET /v1/context
Returns a context bundle assembled for a named intent: the light identity profile, the most relevant memories, related entities, and adaptation suggestions. See Context.
curl "http://localhost:4000/v1/context?intent=coach&query=today%27s%20plan&limit=8" \-H "Authorization: Bearer $CONNECTION_TOKEN"
{"identity": { "aiId": "ai_42", "name": "Nova" },"memories": [{ "id": "mem_1c2d...", "type": "goal", "scope": "fitness","content": "Sub-4:00 marathon by spring.", "importance": 80,"occurredAt": "2026-04-02T09:12:00.000Z", "sourceApp": "my-app" }],"relationships": [{ "subject": "user", "relation": "trains_with", "object": "running club" }],"suggestions": { "adaptation": "Be concise and encouraging.", "tags": ["concise"] },"generatedAt": "2026-05-21T10:00:00.000Z"}
POST /v1/gateway/chat
The hosted-inference path: PAMbase runs the model with the user's memory injected and records memory candidates from the turn. Use it when you don't bring your own model. Requires ai:host:chat (or ai:host:companion for persona-style hosting). See Gateway and Chat.
curl -X POST http://localhost:4000/v1/gateway/chat \-H "Authorization: Bearer $CONNECTION_TOKEN" \-H "Content-Type: application/json" \-d '{"intent": "coach","userMessage": "How did my week go?","appContext": { "view": "weekly-summary" }}'
{"reply": "Strong week — three runs, 18 km total. One more easy run keeps you on pace.","toneTags": ["encouraging", "concise"],"memoryCandidates": [{ "type": "event", "scope": "fitness","content": "Ran 18 km across three sessions this week.", "importance": 40 }],"usage": { "tokensIn": 812, "tokensOut": 96, "model": "pambase-host-1" }}
POST /v1/gateway/chat/stream emits Server-Sent Events with the same scope. Each frame is one of delta, memory_recorded, done, or error — mirrored by the SDK's chatStream() generator.
POST /v1/schedule
Register a future trigger; when it fires, PAMbase delivers a schedule.fired webhook to your app. See the proactive layer and Webhooks.
curl -X POST http://localhost:4000/v1/schedule \-H "Authorization: Bearer $CONNECTION_TOKEN" \-H "Content-Type: application/json" \-d '{"fireAt": "2026-05-22T07:00:00.000Z","kind": "morning-checkin","payload": { "tip": "Easy run today" }}'
{ "id": "trg_5e6f...", "fireAt": "2026-05-22T07:00:00.000Z" }
Discovery
Public (or any-auth) read-only endpoints describing the shared vocabulary and what a given user has. The Catalog page renders /v1/catalog directly.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /v1/catalog | public | Memory kinds + the extensive scope taxonomy + intents + signal shapes |
| GET | /v1/scopes | connection or user | Scopes present for this user; apps see only readable scopes |
curl http://localhost:4000/v1/catalog
{"version": "1.0.0","memoryKinds": [{ "type": "goal", "description": "..." }],"systemScopes": [{ "scope": "identity:read", "description": "..." }],"standardScopes": [{ "namespace": "fitness", "description": "..." }],"standardEvents": [{ "type": "workout.completed", "payload": [/* ... */] }],"standardIntents": [{ "intent": "coach", "description": "..." }]}
Developer portal
Manage your developer account, apps, credentials, webhook subscriptions, and delivery logs. All require a logged-in developer session (cookie). Credentials and secrets are shown once on creation or rotation — store them securely.
Account
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/dev/auth/signup | Create a developer account |
| POST | /v1/dev/auth/login | Start a developer session |
| POST | /v1/dev/auth/logout | End the session |
| GET | /v1/dev/auth/me | Current developer profile |
| POST | /v1/dev/auth/change-password | Change your developer password |
| DELETE | /v1/dev/auth/me | Delete the developer account |
Apps & credentials
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/dev/apps | List your apps |
| POST | /v1/dev/apps | Register an app (returns client_id + client_secret once) |
| GET | /v1/dev/apps/:id | Fetch one app |
| PATCH | /v1/dev/apps/:id | Update app (manifest, metadata) |
| DELETE | /v1/dev/apps/:id | Delete an app |
| POST | /v1/dev/apps/:id/rotate-secret | Rotate client_secret (returns new secret once) |
| GET | /v1/dev/apps/:id/usage | Per-app usage metrics |
| GET | /v1/dev/apps/:id/audit | Per-app audit log |
Webhook subscriptions & deliveries
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/dev/apps/:id/subscriptions | List webhook subscriptions |
| POST | /v1/dev/apps/:id/subscriptions | Create a subscription (returns signing secret once) |
| POST | /v1/dev/apps/:id/subscriptions/:subId/rotate | Rotate a subscription signing secret |
| DELETE | /v1/dev/apps/:id/subscriptions/:subId | Delete a subscription |
| GET | /v1/dev/apps/:id/deliveries | Recent webhook delivery attempts (debug) |
See Webhooks for signature verification and the X-PAMbase-Delivery idempotency header.
User / Hub
The end-user surface at https://pambase.io, backed by a user session cookie. App developers rarely call these directly — they exist so users can manage their own memory and connections — but they are listed here for completeness.
| Method | Path | Purpose |
|---|---|---|
· | /v1/auth/* | User signup / login / logout / session |
| GET | /v1/identities | The user's identity (exactly one per user) |
| POST | /v1/identities | Idempotent — provisioning is automatic |
| DELETE | /v1/identities/:id | Forbidden — the memory store cannot be deleted |
· | /v1/memories | User-authored memory CRUD |
| GET | /v1/connections | List connected apps and their scopes |
| POST | /v1/connections/:id/revoke | Revoke an app's access |
| GET | /v1/audit | Audit log of reads/writes per app |
| GET | /v1/usage | Plan usage against quotas |
· | /v1/chats* | First-party Hub chat |
Out of scope for app developers
Admin endpoints, billing/subscription management, and inbound connector webhooks (third-party data ingestion) exist but are outside the app-developer surface and are not documented here. App-facing, OAuth, discovery, and the developer portal cover everything you need to build on PAMbase.