Skip to main content
The adapter exposes the runtime’s entire route table on whatever routePrefix you configure (default: /api/persona). The middleware is a single catch-all: PersonaMiddleware handles every request under the prefix and forwards it to runtime.handle(). The runtime owns matching, params, and 404/405 — the adapter adds no routes of its own.

Always-on routes (end-user scoped)

Every route except GET /health requires an authenticated user (401 when the resolver returns null or throws). For the exact SDK call each route proxies to, see the Runtime routes reference.

Opt-in admin routes

The Project-level admin surface (agents CRUD, providers, skills, knowledge, stores, MCPs, audit logs, architect) is off by default — it’s gated behind capabilities.* on the runtime. When a capability is disabled, its routes are simply absent (a request 404s or 405s, never 403). See Runtime capabilities. To expose the admin surface, register a second module with capabilities on and stricter auth:
In practice, for the admin surface you’d create a second PersonaModule.forRoot() with routePrefix: '/api/admin/persona' and stricter resolveUser in a separate feature module, or use PersonaService.runtime.handle() directly in an admin controller.

How the middleware translates a request

PersonaMiddleware translates the NestJS request to the runtime’s framework-neutral contract before runtime.handle() runs:

Error responses

  • Runtime responses — including sanitized error envelopes {"error":{code,message}} — are forwarded verbatim (status, headers, body).
  • Adapter translation failures (malformed JSON, unparsable multipart) respond 400 INVALID_REQUEST in the same envelope shape.
  • Any other adapter-side error is forwarded to NestJS’s exception filter — unless headers are already sent, in which case the connection is ended cleanly.
See Runtime errors for the two detail modes (development vs production).