REST API reference
Base URL http://localhost:8787 in development; auth via Authorization: Bearer <key> or session cookie.
Machine-readable
- OpenAPI 3.1 spec — the source of truth; SDKs are generated from this.
- Postman 2.1 collection — generated from the spec; use
{{base_url}}and{{api_key}}variables.
Auth
POST /auth/dev-login dev-only email login -> session cookie GET /auth/oidc/start OIDC start (PMESH_OIDC_* configured) GET /auth/oidc/callback OIDC callback POST /auth/logout clear session POST /auth/invites/:token accept invite
Workspaces, members, keys
POST /v1/workspaces create
GET /v1/workspaces/me current auth context
GET /v1/workspaces/:id/api-keys list (no hash returned)
POST /v1/workspaces/:id/api-keys create (plaintext returned once)
DELETE /v1/workspaces/:id/api-keys/:keyId revoke
GET /v1/members
PATCH /v1/members/:user_id body: { role }
DELETE /v1/members/:user_id
GET /v1/invites
POST /v1/invites body: { email, role, ttl_hours? }
DELETE /v1/invites/:idPersonas + templates
GET /v1/personas
POST /v1/personas body: PersonaSpec
GET /v1/personas/:id
PUT /v1/personas/:id body: Partial<PersonaSpec> (bumps version)
DELETE /v1/personas/:id
GET /v1/templates
GET /v1/templates/:slug
POST /v1/templates/:slug/instantiate body: { name?, ...overrides }Chat
POST /v1/chat
{
"persona_id": "per_...",
"conversation_id": "conv_...", // optional
"message": "...",
"stream": false // true -> text/plain stream + meta trailer
}
GET /v1/chat/conversations/:idMemory
GET /v1/memory/:persona_id
POST /v1/memory/:persona_id body: MemoryWriteInput
POST /v1/memory/:persona_id/recall body: { query, k? }
POST /v1/memory/:persona_id/summarize
DELETE /v1/memory/items/:idKnowledge (RAG)
GET /v1/knowledge/:persona_id
POST /v1/knowledge/:persona_id body: { title, text, source?, mime? }
POST /v1/knowledge/:persona_id/search body: { query, k? }
DELETE /v1/knowledge/documents/:doc_idPatterns of Life + autonomy
POST /v1/pol/:persona_id/generate body: { seed? }
GET /v1/pol/:id
GET /v1/pol/persona/:persona_id/current
PUT /v1/autonomy/:persona_id/config body: AutonomyConfig
GET /v1/autonomy/:persona_id/config
POST /v1/autonomy/:persona_id/tick
GET /v1/autonomy/:persona_id/timelineAudit + replay + billing + events
GET /v1/audit?limit=200 GET /v1/audit/verify GET /v1/replay/:audit_id POST /v1/replay/:audit_id/run GET /v1/billing/usage?days=30 GET /v1/events/stream (SSE; heartbeats every 20s)
Channels
POST /v1/channels/webhook/:persona_id (HMAC if PMESH_WEBHOOK_SECRET set) POST /v1/channels/slack/events (x-slack-signature verified)
Errors
Every failure returns:
{
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": { ... } // optional
}
}