PAMbaseDocs
How-to

Discover the vocabulary.

The PAMbase contract — the scope taxonomy (the domains you write into) and the consent scopes — is discoverable at runtime, so you never hard-code assumptions. Two views answer two questions.

You build against a stable contract
The standard scope taxonomy is the shared world: build against it and you interoperate with every app, today and as new ones launch — you never have to track what other developers invent. These views just help you adapt to a given user.

The two views

QuestionCallAuth
What vocabulary exists?getCatalog()Public
What does this user have?listUserScopes()Token

1. The catalog — what exists

Public, no auth. The memory kinds, the full scope taxonomy (grouped), intents, and webhook shapes — the same data rendered on the Catalog page.

EndpointSDKReturns
GET /v1/cataloggetCatalog()memoryKinds, scopeGroups, standardScopes, standardIntents, webhookEvents + version
typescript
const catalog = await pambase.getCatalog();
// catalog.version, catalog.standardScopes, catalog.scopeGroups, catalog.memoryKinds
// Public — also reachable without a token:
// GET http://localhost:4000/v1/catalog

2. This user's scopes — what you can actually use

listUserScopes() returns the scopes this connection holds (filtered to what your app may read), each with a memory count and a standard flag. Adapt your UI to what's really there — don't offer a feature for data the user doesn't have.

EndpointSDKReturns
GET /v1/scopeslistUserScopes(){ scopes: [{ scope, count, standard }] }
margin/adapt-features.ts
const { scopes } = await pambase.listUserScopes();
const has = (ns: string) => scopes.some(s => s.scope.startsWith(ns) && s.count > 0);
// Margin only shows the "Your highlights" shelf if the user actually has note.* memories.
if (has("note")) showHighlightsShelf();
else showEmptyState("Save your first highlight to start your shelf.");
// And only surfaces taste-based picks if it can read preferences with data behind them.
const canPersonalize = has("preference");
Adapt, don't assume
A user might grant memory:read:note.* but have an empty store, or grant fewer scopes than your manifest requested. Check counts here before rendering a feature. This is also the first thing to check when a recall() comes back empty — see Troubleshooting.

Types for autocomplete

The SDK ships STANDARD_SCOPE_NAMESPACES (and the MemoryScope type) so your editor autocompletes the standard domains when you remember(). Sub-scopes under a standard namespace are free.

typescript
import { STANDARD_SCOPE_NAMESPACES } from "@pambase/sdk";
await pambase.remember({ content: "Trains for trail runs.", kind: "goal", scope: "fitness.trail" });
// "fitness" is a standard namespace; ".trail" is your free sub-scope.

What to expect next