Understand memory

Hosted Team OS API

The hosted API handles Team OS identity, access, memory, and sync.

The hosted API is the HTTP service behind Team OS.

In the Agentic OS repository, the service is started with:

npm run memory:api

The service is also called memory-api. In hosted Team OS, it does more than memory search. It handles login, permissions, Company and Team admin data, manual imports, workspace file sync, memory capture, memory review, memory status, and health checks.

Health check

The health endpoint does not require auth:

curl https://team.example.com/v1/health

Expected response:

{
  "ok": true,
  "backend": "postgres",
  "embedder": {
    "mode": "client-provided",
    "model": "bge-m3",
    "dim": 1024,
    "serverModeEnabled": false
  }
}

Use /v1/health as the deployment health check in Railway, Coolify, Docker, or a VPS reverse proxy.

Authentication

Normal users sign in with email and password:

npm run team -- login --api-url https://team.example.com --email user@example.com --password "<password>"

The server returns a Team OS session token. The terminal and Command Centre use that token for later requests.

Every deployment must set MEMORY_API_TOKEN because the API checks it at startup. This is a dev fallback credential for smoke tests. It is not the normal user login path.

Private or local access

A public HTTPS URL is convenient, but it is not required for local testing or a private operator setup. You can reach the API through localhost, an SSH tunnel, Tailscale, WireGuard, or another private network path.

Set the auth URLs to the address the operator's browser and terminal will use:

BETTER_AUTH_URL=http://localhost:8787 \
MEMORY_API_PUBLIC_URL=http://localhost:8787 \
MEMORY_API_TOKEN=... \
MEMORY_DATABASE_URL=... \
npm run memory:api

For an SSH tunnel, keep the API bound privately on the server. From the operator's machine, forward the port:

ssh -N -L 8787:127.0.0.1:8787 user@server.example.com

Then sign in through the tunnel:

npm run team -- login --api-url http://localhost:8787 --email owner@example.com --password "<password>"

Owner reset links also need a base URL that the operator's browser can open:

npm run team:owner-reset -- --team demo --email owner@example.com --base-url http://localhost:8787 --ttl 4h

For Tailscale, WireGuard, or a private LAN, use the reachable private API URL instead of localhost in BETTER_AUTH_URL, MEMORY_API_PUBLIC_URL, --api-url, and --base-url.

Do not put MEMORY_DATABASE_URL on member machines. Only the server or container should have the database URL. Members should connect through the Team OS API URL.

Main endpoint groups

Endpoint groupPurpose
/v1/auth/*Login, join, and logout.
/v1/company/*Company roles, Teams, access requests, Company grants, and Team lifecycle.
/v1/team/*Selected Team identity, accessible clients, members, invites, and grants.
/v1/memory/search, /v1/memory/expand, and /v1/memory/ingestSearch, expand a search hit, and direct memory ingest.
/v1/memory/importsManual shared imports, failed import lists, and retries.
/v1/memory/capturesStage automatic Team OS session captures.
/v1/memory/consolidation/*Claim and complete capture consolidation batches.
/v1/memory/memoriesAdmin memory review, published memory library, and published memory edit/delete actions.
/v1/memory/statusMemory health, source, import, job, and capture status.
/v1/workspace/*Permission-scoped file manifest, pull, and push.
/v1/healthDeployment health check.

All protected routes use the server-resolved Team OS identity. The local workspace cannot grant itself access by sending a different Team, client, or user ID. Team routes validate the requested Team for every request. Company management routes require an active Company Owner or Company Admin role. Company invitation acceptance is the exception: it validates the one-time invitation token before creating the new Company Admin session.

Search and expand endpoints

POST /v1/memory/search searches allowed memory for the signed-in user.

By default, the caller sends the query text plus a BGE-M3 query embedding. If the server has MEMORY_API_SERVER_EMBEDDINGS=1, the caller can send embeddingMode: "server" instead. In that mode, the server creates the query embedding from the query text. The server still checks the signed-in user's scope, runs semantic search and keyword search, combines the results, and records a search audit event.

POST /v1/memory/expand takes a chunkId from a previous scoped search. It returns nearby chunks from the same source and same allowed scope. If the chunk is outside the user's scope, the response returns no expansion instead of revealing that another scope has the chunk.

Transcript drill-down is not a hosted endpoint in this phase. It reads local raw transcript files from context/transcripts/.

For the user-facing flow, see Layered recall.

Capture and consolidation endpoints

Automatic Team OS session capture uses staged memory.

POST /v1/memory/captures stores a summarized session block as a capture event. It does not make the text searchable.

POST /v1/memory/consolidation/claim claims a small batch of staged captures. The consolidating workspace reads those captures and prepares durable memory items.

POST /v1/memory/consolidation/complete finishes the batch. Each item is published, sent to review, or discarded.

Published items become searchable memory. Review and discarded items stay out of recall.

Memory review endpoints

Users with Full access use /v1/memory/memories to review memory. This includes the Company Owner, a Team Owner or Team Admin, and a Company Admin with Full access to the selected Team.

GET /v1/memory/memories returns pending review items and published memory for the resolved Team. POST /v1/memory/memories lets a user with Full access:

  • publish a review item;
  • discard a review item;
  • update a published team or client memory;
  • delete a published team or client memory.

Delete archives the memory source and removes its search chunks. It does not erase the audit event.

Command Centre uses this endpoint in Team > Memories.

Startup behavior

At startup, the API:

  • resolves the memory backend;
  • runs memory migrations;
  • runs Better Auth migrations;
  • resolves or bootstraps the configured Team OS server principal;
  • starts listening on MEMORY_API_PORT, PORT, or 8787.

If hosted mode is expected, the health response should show backend: postgres.

If embedder.serverModeEnabled is true, direct search callers can use embeddingMode: "server". If it is false, callers must send queryEmbedding.

Search request embeddings

The default request sends a client-made BGE-M3 query embedding:

{
  "query": "onboarding notes",
  "queryEmbedding": ["<1024 BGE-M3 numbers>"],
  "embeddingModel": "bge-m3",
  "embeddingDim": 1024,
  "scope": {
    "clientId": "acme",
    "include": ["team", "client"]
  },
  "topK": 5,
  "storeQueryText": false
}

When the API server has MEMORY_API_SERVER_EMBEDDINGS=1, a lightweight caller can send text only:

{
  "query": "onboarding notes",
  "embeddingMode": "server",
  "scope": {
    "clientId": "acme",
    "include": ["team", "client"]
  },
  "topK": 5,
  "storeQueryText": false
}

If server-side embeddings are not enabled, this request fails with server_embedding_disabled. In that case, send queryEmbedding or enable MEMORY_API_SERVER_EMBEDDINGS=1 on the API server.

The Agentic OS CLI uses --embedding-mode auto by default. It checks /v1/health. If server-side embeddings are enabled, it sends embeddingMode: "server". Otherwise, it sends a client-made query embedding.

Next: Session capture and review

On this page