API Reference

memory-api FastAPI • port 8000 • 18 route modules

Introduction

The xbrain memory-api is a FastAPI application running on port 8000 inside the Docker Compose stack. It is the single write/read interface for all memory data — whether the source is LibreChat, Open WebUI, a LangGraph agent, or the Chrome extension.

All endpoints (except GET /v1/healthz) require two headers:

Header Value Description
Authorization Bearer {token} Google ID token (from OAuth login) or GitHub OAuth token. Bridge services use BRIDGE_SHARED_SECRET-signed JWTs.
X-Team-Scope {team_scope} Team identifier. Must match the team_scope field in any payload. Requests with mismatched scopes return 400.

Base URL: https://api.grooveos.app (replace with your domain)

Authentication

xbrain supports three authentication mechanisms:

bash — authenticating requests# Google ID token (from frontend after OAuth flow)
curl https://api.grooveos.app/v1/me \
  -H "Authorization: Bearer $GOOGLE_ID_TOKEN" \
  -H "X-Team-Scope: excalibur"

# GitHub token (after GitHub OAuth)
curl https://api.grooveos.app/v1/me/github \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "X-Team-Scope: excalibur"

Health

GET /v1/healthz

Health check endpoint. No authentication required. Used by Docker Compose healthcheck and load balancers.

PropertyValue
Auth requiredNo
Response200 OK
bash — health checkcurl https://api.grooveos.app/v1/healthz

# Response:
{
  "status": "ok",
  "version": "1.0.0"
}

User Profile

GET /v1/me

Returns the authenticated user's profile, including their team memberships and source identity (Google or GitHub).

PropertyValue
Auth requiredYes
Response200 OK
bash — get user profilecurl https://api.grooveos.app/v1/me \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response:
{
  "id": "a1b2c3d4-...",
  "email": "alice@excalibur.game",
  "source_user_id": "google:116249012345678901234",
  "is_admin": false,
  "teams": ["excalibur", "engineering"]
}

GET /v1/me/github

Returns GitHub profile information if the user authenticated via GitHub OAuth. Includes org membership verification result.

bash — get GitHub profilecurl https://api.grooveos.app/v1/me/github \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "X-Team-Scope: excalibur"

# Response:
{
  "github_username": "alicedev",
  "github_id": 8234567,
  "github_avatar_url": "https://avatars.githubusercontent.com/u/8234567",
  "is_org_member": true,
  "org": "excalibur-game"
}

Memory

The memory endpoints implement the core tagging contract. Every item must carry the 7 required fields: team_scope, project_scope, visibility, confidence, truth_level, source, validation_status.

POST /v1/memory/upsert

Create or update a memory item. Returns 201 on creation. If an item with the same source already exists in this team, it is updated in place (vector + metadata).

PropertyValue
Auth requiredYes
Success response201 Created
Error: missing tag field422 Unprocessable Entity
Error: team_scope mismatch400 Bad Request
bash — upsert a memory item (all 7 required fields)curl -X POST https://api.grooveos.app/v1/memory/upsert \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "item": {
      "content": "The Q2 fundraising target is 2M€, confirmed by Alice in the board meeting.",
      "team_scope": "excalibur",
      "project_scope": "fundraising",
      "visibility": "team",
      "confidence": 0.9,
      "truth_level": "WORKING",
      "source": "librechat:conv_abc123:msg_7",
      "validation_status": "pending",
      "metadata": {
        "extracted_by": "librechat-bridge",
        "conversation_id": "conv_abc123"
      }
    }
  }'

# Response (201 Created):
{
  "id": "mem_f7a3b1c9d2e4...",
  "team_scope": "excalibur",
  "truth_level": "WORKING"
}

truth_level is write-once via upsert

You can set truth_level when upserting. To promote a fact from WORKING to VALIDATED or CANONICAL, use the Promotions API — you cannot PATCH truth_level directly (returns 405).

GET /v1/memory/search

Semantic search over the team's memory using Qdrant vector similarity. Filtered by team_scope from the X-Team-Scope header. Optionally filter by project_scope and minimum truth level.

Query ParameterTypeDefaultDescription
qstringrequiredSearch query text (embedded and compared against Qdrant vectors)
project_scopestringFilter to a specific project
truth_level_minstringEPHEMERALMinimum truth level to return (EPHEMERAL, WORKING, VALIDATED, CANONICAL, PUBLIC)
limitinteger10Number of results (max 100)
bash — semantic memory searchcurl "https://api.grooveos.app/v1/memory/search?q=fundraising+target&truth_level_min=WORKING&limit=5" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response:
[
  {
    "id": "mem_f7a3b1c9d2e4...",
    "content": "The Q2 fundraising target is 2M€...",
    "score": 0.947,
    "team_scope": "excalibur",
    "project_scope": "fundraising",
    "truth_level": "WORKING",
    "confidence": 0.9,
    "source": "librechat:conv_abc123:msg_7"
  }
]

GET /v1/memory/{item_id}

Retrieve a single memory item by ID. Returns 404 if the item is not in the requesting team's scope.

bash — get a single memory itemcurl https://api.grooveos.app/v1/memory/mem_f7a3b1c9d2e4 \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

PATCH /v1/memory/{item_id}

Update a memory item's mutable fields: content, project_scope, visibility, confidence, validation_status, metadata.

405 — truth_level cannot be patched directly

Attempting to PATCH truth_level returns 405 Method Not Allowed. Truth level promotion is an explicit workflow — use POST /v1/promotions instead. This is intentional: truth level changes require justification and (for VALIDATED and above) admin approval.

bash — update confidence and validation_statuscurl -X PATCH https://api.grooveos.app/v1/memory/mem_f7a3b1c9d2e4 \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "confidence": 0.95,
    "validation_status": "human_reviewed"
  }'

# Response (200 OK):
{
  "id": "mem_f7a3b1c9d2e4...",
  "updated_fields": ["confidence", "validation_status"]
}

# Attempting to patch truth_level:
curl -X PATCH https://api.grooveos.app/v1/memory/mem_f7a3b1c9d2e4 \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{"truth_level": "VALIDATED"}'

# Response (405 Method Not Allowed):
{
  "detail": "truth_level cannot be patched directly. Use POST /v1/promotions."
}

DELETE /v1/memory/{item_id}

Delete a memory item. Removes from both Qdrant (vector) and PostgreSQL (metadata). Returns 204 No Content on success.

bash — delete a memory itemcurl -X DELETE https://api.grooveos.app/v1/memory/mem_f7a3b1c9d2e4 \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response: 204 No Content

Conversations

POST /v1/conversations

Create a new conversation record. Conversations are the organizational unit for messages — every message belongs to a conversation.

bash — create a conversationcurl -X POST https://api.grooveos.app/v1/conversations \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Q2 Fundraising Strategy Session",
    "project_scope": "fundraising",
    "source": "librechat:conv_abc123"
  }'

# Response (201 Created):
{
  "id": "conv_uuid_...",
  "title": "Q2 Fundraising Strategy Session",
  "team_scope": "excalibur",
  "project_scope": "fundraising",
  "owner_user_id": "a1b2c3d4-...",
  "created_at": "2026-05-06T10:30:00Z"
}

GET /v1/conversations

List conversations for the authenticated team. Results are paginated and scoped to X-Team-Scope. Query params: project_scope, limit (default 20), offset.

bash — list team conversationscurl "https://api.grooveos.app/v1/conversations?project_scope=fundraising&limit=10" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

GET /v1/conversations/{conversation_id}

Retrieve a single conversation with its metadata. Does not include messages — use GET /v1/messages?conversation_id= for messages.

bash — get conversation by IDcurl https://api.grooveos.app/v1/conversations/conv_uuid_123 \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

Messages

POST /v1/messages

Log a message to memory-api. If the referenced conversation does not exist, it is created silently (upsert-silent pattern). Used by librechat-bridge and openwebui-bridge to stream conversation content into xbrain.

bash — log a message (bridge usage)curl -X POST https://api.grooveos.app/v1/messages \
  -H "Authorization: Bearer $BRIDGE_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "conv_abc123",
    "role": "user",
    "content": "What is our fundraising target for Q2?",
    "source": "librechat",
    "user_id": "a1b2c3d4-..."
  }'

# Response (201 Created):
{
  "id": "msg_uuid_...",
  "conversation_id": "conv_abc123"
}

Truth Level Promotions

Truth level promotion is the formal workflow for advancing a fact from EPHEMERAL through WORKING, VALIDATED, CANONICAL, and PUBLIC. Every promotion requires explicit justification. Promotions to VALIDATED and above require admin approval.

POST /v1/promotions

Submit a promotion request for a memory item.

bash — request promotion to VALIDATEDcurl -X POST https://api.grooveos.app/v1/promotions \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": "mem_f7a3b1c9d2e4",
    "target_level": "VALIDATED",
    "justification": "Confirmed in board meeting on 2026-05-01. Three stakeholders present."
  }'

# Response (202 Accepted):
{
  "promotion_id": "promo_uuid_...",
  "item_id": "mem_f7a3b1c9d2e4",
  "target_level": "VALIDATED",
  "status": "pending",
  "created_at": "2026-05-06T10:45:00Z"
}

GET /v1/promotions

List pending promotions. Admin only — requires the user's sub to be in ADMIN_USER_SUBS. Supports query params: status (pending, approved, rejected), item_id.

bash — list pending promotions (admin)curl "https://api.grooveos.app/v1/promotions?status=pending" \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur"

PATCH /v1/promotions/{promotion_id}

Approve or reject a pending promotion. Admin only. On approval, the memory item's truth_level is updated atomically.

bash — approve a promotion (admin)curl -X PATCH https://api.grooveos.app/v1/promotions/promo_uuid_123 \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "approved",
    "note": "Verified in board minutes. Elevating to VALIDATED."
  }'

# Response (200 OK):
{
  "promotion_id": "promo_uuid_123",
  "decision": "approved",
  "item_id": "mem_f7a3b1c9d2e4",
  "new_truth_level": "VALIDATED"
}

System Prompt

GET /v1/system-prompt

Returns CANONICAL facts for the team, pre-formatted for injection into an LLM system prompt. Filtered by X-Team-Scope and truth_level=CANONICAL. Used by librechat-bridge, openwebui-bridge, and agent-runtime to ground every LLM call with verified team knowledge.

bash — fetch team CANONICAL facts for system promptcurl https://api.grooveos.app/v1/system-prompt \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response (200 OK, text/plain):
Team knowledge (CANONICAL, excalibur):
- Q2 fundraising target: 2M€ (confirmed 2026-05-01)
- Tech lead: Alice Dupont (since 2025-06-01)
- Current runway: 18 months (as of 2026-04-15)
- Primary investor: Excalibur Capital (lead), Angel Group (co-lead)

Graph

GET /v1/graph/neighbors

Query the Neo4j temporal knowledge graph for entities connected to a given entity within the team scope. Results include temporal validity of each relationship.

Query ParameterTypeRequiredDescription
entitystringYesEntity name to query (person, project, concept)
team_scopestringYesTeam graph partition to search in
depthintegerNoGraph traversal depth (default: 1, max: 3)
bash — get graph neighbors for an entitycurl "https://api.grooveos.app/v1/graph/neighbors?entity=Alice&team_scope=excalibur" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response:
{
  "entity": "Alice",
  "team_scope": "excalibur",
  "neighbors": [
    {
      "name": "Excalibur.Engineering",
      "relationship": "WAS_TECH_LEAD",
      "valid_from": "2025-01-15",
      "valid_until": "2025-05-31"
    },
    {
      "name": "Q2-Fundraising",
      "relationship": "CONTRIBUTED_TO",
      "valid_from": "2025-03-01",
      "valid_until": null
    },
    {
      "name": "Bob",
      "relationship": "TRANSFERRED_ROLE_TO",
      "valid_from": "2025-06-01",
      "valid_until": null
    }
  ]
}

Audit

GET /v1/audit

Returns the audit log — every write operation (upsert, delete, promotion, admin action) is logged with user, timestamp, action type, and the affected resource. Admin only.

Query ParameterTypeDescription
team_scopestringFilter by team (admin sees all teams; regular user sees own)
actionstringFilter by action type: upsert, delete, promote, approve, reject
user_idstringFilter by actor user ID
limitintegerMax results (default 50, max 500)
offsetintegerPagination offset
bash — fetch audit log for a teamcurl "https://api.grooveos.app/v1/audit?team_scope=excalibur&action=promote&limit=20" \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur"

# Response:
{
  "total": 42,
  "items": [
    {
      "id": "audit_uuid_...",
      "timestamp": "2026-05-06T10:45:00Z",
      "user_id": "a1b2c3d4-...",
      "user_email": "alice@excalibur.game",
      "action": "promote",
      "resource_type": "memory_item",
      "resource_id": "mem_f7a3b1c9d2e4",
      "detail": {"target_level": "VALIDATED", "justification": "..."}
    }
  ]
}

Teams

GET /v1/teams

List teams the authenticated user belongs to.

bash — list user teamscurl https://api.grooveos.app/v1/teams \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Response:
[
  {"scope": "excalibur", "name": "Excalibur Game", "role": "admin"},
  {"scope": "engineering", "name": "Engineering", "role": "member"}
]

POST /v1/admin/teams

Create a new team. Admin only. The team scope must be a unique slug (lowercase, hyphens allowed).

bash — create a team (admin)curl -X POST https://api.grooveos.app/v1/admin/teams \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering",
    "scope": "engineering"
  }'

# Response (201 Created):
{
  "id": "team_uuid_...",
  "scope": "engineering",
  "name": "Engineering",
  "created_at": "2026-05-06T10:00:00Z"
}

Google Drive Integration

GET /v1/admin/drive/auth

Initiates the Google Drive OAuth2 flow. Redirects to Google's consent screen. Admin only. After consent, Google redirects back to the callback URL with an auth code which drive-sync exchanges for tokens.

bash — initiate Drive OAuth (redirect in browser)# This endpoint redirects — open in browser, not curl
GET https://api.grooveos.app/v1/admin/drive/auth
  ?team_scope=excalibur
  &Authorization=Bearer+{admin_jwt}

POST /v1/admin/drive/mappings

Map a Google Drive folder to a team scope and project. Once mapped, drive-sync will watch the folder for changes and upsert new/modified files into memory-api.

bash — map a Drive folder to a projectcurl -X POST https://api.grooveos.app/v1/admin/drive/mappings \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "folder_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
    "team_scope": "excalibur",
    "project_scope": "fundraising",
    "truth_level": "WORKING",
    "label": "Fundraising Deck Folder"
  }'

# Response (201 Created):
{
  "mapping_id": "map_uuid_...",
  "folder_id": "1BxiMVs...",
  "team_scope": "excalibur",
  "label": "Fundraising Deck Folder",
  "status": "active",
  "webhook_registered": true
}

GET /v1/admin/drive/mappings

List all active Drive folder mappings for the team.

bash — list Drive mappingscurl https://api.grooveos.app/v1/admin/drive/mappings \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur"

POST /v1/drive/webhook

Google Drive push notification endpoint. Called by Google when a watched folder changes. This is an internal endpoint — Google calls it automatically after a mapping is registered. Validates the Google push notification signature before processing.

Internal endpoint

POST /v1/drive/webhook is called by Google, not by your application. It is exposed via Nginx at the public URL so Google can reach it. No user auth required — it validates the Google push notification headers instead.

Projects

POST /v1/admin/projects

Create a new project within a team. Projects are used as the project_scope for memory items, conversations, and Drive mappings.

bash — create a project (admin)curl -X POST https://api.grooveos.app/v1/admin/projects \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Series A Fundraising",
    "slug": "fundraising",
    "team_scope": "excalibur",
    "deploy_target": "firebase"
  }'

# Response (201 Created):
{
  "id": "proj_uuid_...",
  "slug": "fundraising",
  "name": "Series A Fundraising",
  "team_scope": "excalibur",
  "status": "active",
  "created_at": "2026-05-06T10:00:00Z"
}

GET /v1/admin/projects

List all projects for the team. Admin only.

bash — list team projectscurl https://api.grooveos.app/v1/admin/projects \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur"

CRM & Contacts Team & Enterprise

Contact management with automatic extraction from memory items and meeting notes. All endpoints require Team or Enterprise plan — Starter returns 403. See CRM & Contacts for full documentation.

GET /v1/crm/contacts

List contacts for the authenticated team with pagination.

bashcurl "https://api.grooveos.app/v1/crm/contacts?limit=50&offset=0" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

POST /v1/crm/contacts

Create a new contact. Email must be unique within the team.

bashcurl -X POST "https://api.grooveos.app/v1/crm/contacts" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","name":"Alice Martin","company":"Acme"}'

PUT /v1/crm/contacts

Upsert a contact by (team_scope, email). Safe to call repeatedly — idempotent.

bashcurl -X PUT "https://api.grooveos.app/v1/crm/contacts" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","role":"VP Engineering"}'

PATCH /v1/crm/contacts/{contact_id}

Update fields of an existing contact.

DELETE /v1/crm/contacts/{contact_id}

Delete a contact. Logged to audit trail.

Tasks Team & Enterprise

Task management with automatic generation from meeting notes and chat messages. All endpoints require Team or Enterprise plan — Starter returns 403. See Task Tracking for full documentation including polling and chat-based task detection.

GET /v1/tasks

List tasks with optional filters. Supports since timestamp for polling.

bash# All tasks for the team
curl "https://api.grooveos.app/v1/tasks" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

# Filter by status + poll for new tasks
curl "https://api.grooveos.app/v1/tasks?status=todo&since=2026-05-07T00:00:00Z" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur"

POST /v1/tasks

Create a task manually. created_by is set to the authenticated user's ID. Bridge JWTs are rejected (401) — this endpoint requires a real user identity.

bashcurl -X POST "https://api.grooveos.app/v1/tasks" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Send deck to investor",
    "project_scope": "fundraising",
    "due_date": "2026-05-14",
    "visibility": "team",
    "confidence": 1.0,
    "truth_level": "WORKING",
    "validation_status": "pending"
  }'

GET /v1/tasks/{task_id}

Retrieve a single task by ID.

PATCH /v1/tasks/{task_id}

Update a task. Status changes generate a differentiated audit entry: task.status_changed (with from/to fields) vs task.updated for non-status changes.

bashcurl -X PATCH "https://api.grooveos.app/v1/tasks/t1a2b3c4..." \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{"status": "done"}'

DELETE /v1/tasks/{task_id}

Delete a task. Logged to audit trail.

Meeting Integration (Granola) Team & Enterprise

Granola meeting notes are automatically polled every 5 minutes and ingested as memory items + contacts + tasks. See Meeting Integration for setup instructions and the full processing pipeline.

POST /v1/admin/granola-integration

Register a Granola API key for the team. Admin only. The key is Fernet-encrypted at rest.

bashcurl -X POST "https://api.grooveos.app/v1/admin/granola-integration" \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{"api_key":"grn_live_...","default_project_scope":"general"}'

GET /v1/admin/granola-integration

Get the current Granola integration config for the team. API key is not returned (write-only).

PATCH /v1/admin/granola-integration

Update the integration (e.g. rotate the API key).

DELETE /v1/admin/granola-integration

Remove the Granola integration. The granola-sync service stops polling this team.

POST /v1/integrations/granola/ingest

Push a Granola note directly without waiting for the 5-minute poll cycle. Atomically writes: memory item + contacts + tasks. Note-level idempotency via source_ref — pushing the same note twice is a no-op.

bashcurl -X POST "https://api.grooveos.app/v1/integrations/granola/ingest" \
  -H "Authorization: Bearer $JWT" \
  -H "X-Team-Scope: excalibur" \
  -H "Content-Type: application/json" \
  -d '{
    "note_id": "grn_note_abc123",
    "title": "Investor call — Series A",
    "summary": "Discussed Q2 targets. Alice will send deck by Friday.",
    "participants": [{"email":"alice@example.com","name":"Alice Martin"}],
    "action_items": [{"title":"Send deck","due_date":"2026-05-09"}],
    "created_at": "2026-05-07T10:00:00Z"
  }'

Error Codes

memory-api uses standard HTTP status codes. All error responses include a detail field with a human-readable message.

Code Meaning Common causes
400 Bad Request team_scope in payload does not match X-Team-Scope header; malformed JSON body
401 Unauthorized Missing or expired Bearer token; invalid Google/GitHub token; invalid bridge JWT signature
403 Forbidden Authenticated user is not a member of the requested team; non-admin attempting an admin-only action
404 Not Found Memory item, conversation, promotion, or project does not exist within this team scope
405 Method Not Allowed Attempted to PATCH truth_level directly — use POST /v1/promotions instead
422 Unprocessable Entity One or more required tagging fields missing from the memory item: team_scope, project_scope, visibility, confidence, truth_level, source, validation_status
500 Internal Server Error Qdrant or PostgreSQL connection failure; unhandled exception. Check docker logs memory-api.
json — example error response{
  "detail": "Missing required field: truth_level. All memory items must carry the 7 tagging contract fields."
}

Quick Reference

Method Path Auth Description
GET/v1/healthzNoneHealth check
GET/v1/meBearerAuthenticated user profile
GET/v1/me/githubBearerGitHub profile + org membership
GET/v1/teamsBearerList user's teams
POST/v1/admin/teamsAdminCreate team
POST/v1/memory/upsertBearerCreate/update memory item
GET/v1/memory/searchBearerSemantic search
GET/v1/memory/{id}BearerGet memory item
PATCH/v1/memory/{id}BearerUpdate memory item (not truth_level)
DELETE/v1/memory/{id}BearerDelete memory item
POST/v1/conversationsBearerCreate conversation
GET/v1/conversationsBearerList conversations
GET/v1/conversations/{id}BearerGet conversation
POST/v1/messagesBearerLog message (upsert-silent)
POST/v1/promotionsBearerRequest truth level promotion
GET/v1/promotionsAdminList promotions
PATCH/v1/promotions/{id}AdminApprove/reject promotion
GET/v1/system-promptBearerCANONICAL facts for LLM prompt
GET/v1/graph/neighborsBearerQuery temporal knowledge graph
GET/v1/auditAdminAudit log
GET/v1/admin/drive/authAdminInitiate Drive OAuth
POST/v1/admin/drive/mappingsAdminMap Drive folder to team/project
GET/v1/admin/drive/mappingsAdminList Drive mappings
POST/v1/drive/webhookGoogleDrive push notification (internal)
POST/v1/admin/projectsAdminCreate project
GET/v1/admin/projectsAdminList team projects