Skip to main content

🧠 Synapse Memory API · Help

Persistent memory for AI agents. Never forget again.

πŸ’‘ For LLMs: Call GET /memory/recall first in every session to get all your memories. Poll GET /chat/poll every 10-30 seconds to receive messages from your human.

Authentication

Synapse uses two types of auth:

TypeHeaderUsed for
Mind KeyAuthorization: Bearer <MIND_KEY>Memory + Chat (agent side) + Tools (cron, var)
User JWTAuthorization: Bearer <JWT>User/Mind management, Chat history, Admin

Get a Mind Key: register β†’ login β†’ create Mind. Get a JWT: POST /login.

WebFetch Path-Params (v1.43.0)

Every GET endpoint (and query-form POST actions like /memory/store, /chat/reply, /mind/task) can be called with trailing name:value URL segments instead of query strings β€” WebFetch/URL-only compatible:

https://synapse.schaefer.zone/chat/history/limit:5/key:YOUR_MIND_KEY/
https://synapse.schaefer.zone/memory/search/q:burnout/key:YOUR_MIND_KEY/
https://synapse.schaefer.zone/endpoints/format:text/

A key:MIND_KEY segment authenticates via the Authorization header and never appears in the query string. Only URLs that match no direct route are transformed; the stripped route must exist in /endpoints, otherwise an honest 404 is returned.

Memory Endpoints (Mind Key auth)

MethodPathDescription
GET/memoryList memories (filter by category/tag)
GET/memory/recallGet ALL memories (LLM prompt, sorted by priority, includes trust badges βœ“/~)
GET/memory/recall/:mind_keySame as /memory/recall but Mind Key in URL path (for open-tool LLMs)
GET/memory/search?q=...Full-text search
GET/memory/statsStatistics (counts by category/priority/source, verified/unverified)
GET/memory/:id/relatedRelated memories (by tag association)
GET/memory/by-tag?tag=...Filter memories by tag (explicit alias)
GET/memory/diff?since=epochIncremental sync (only changes since timestamp)
GET/memory/auditAudit log (Mind Key or JWT, ?action=, ?limit=, ?mind_id= for JWT)
GET/memory/bulk-deleteBulk delete (?tag=, ?category=, ?older_than=)
GET/memory/healthMemory Health Score (0-100: confidence + freshness)
GET/memory/expiringMemories with expiry dates (?days=7, 0=all)
GET/memory/semantic-search?q=...Semantic search by meaning (nomic-embed-text embeddings)
POST/memory/embed-batchBackfill embeddings for existing memories ({limit: 100})
GET/memory/embed-batch?limit=100Backfill embeddings via GET
POST/memoryStore new memory (supports source, confidence, Idempotency-Key header)
POST/memory/syncBulk sync (send all, get diff)
GET/mind/exportFull mind export as JSON or CSV (?format=json|csv)
PUT/memory/:idUpdate specific memory
DELETE/memory/:idDelete memory

Memory Object

{
  "id": "uuid",
  "category": "fact|preference|project|context|identity|skill|mistake|note",
  "key": "optional-unique-key",
  "content": "memory text",
  "tags": ["tag1", "tag2"],
  "priority": "critical|high|normal|low",
  "source": "user|agent|tool|system",      // default: agent
  "confidence": 0.0-1.0,                    // default: derived from source
  "verified_at": null or epoch,             // null = unverified
  "verified_by": null or user_id,
  "created_at": 1781960000,
  "updated_at": 1781960000,
  "expires_at": null
}

Trust Model

Not all memories are equally trustworthy. Track the source of each memory:

SourceDefault confidenceWhen to use
user1.0The human told you this directly
tool0.9Observed via a tool (file, API, SSH)
system0.9Auto-generated by Synapse
agent0.5 (default)Inferred or guessed by the LLM

Verified memories (βœ“) are human-confirmed ground truth. They survive upserts. In /memory/recall, verified memories show βœ“, low-confidence agent inferences show ~.

Quick Start

# Recall all memories (DO THIS FIRST in every session)
curl -H "Authorization: Bearer $MIND_KEY" \
  https://synapse.schaefer.zone/memory/recall

# Store a new memory
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category":"fact","key":"user_name","content":"User is Michael SchΓ€fer","tags":["personal"],"priority":"critical"}' \
  https://synapse.schaefer.zone/memory

# Search memories
curl -H "Authorization: Bearer $MIND_KEY" \
  "https://synapse.schaefer.zone/memory/search?q=burnout"

Chat Endpoints (Mind Key or JWT auth)

Async chat between LLM and human. Human sends via web UI, LLM polls.

MethodPathAuthDescription
GET/chat/poll?since=IDMind KeyGet unread messages (?since=message_id, auto-marks as read; Aliase: after, since_id, after_id β€” task f16fe44d; Response-last_id = Cursor-Echo)
GET/backup/export.ndjsonBackup TokenFleet-Backup-Export β€” alle Minds+Memories als NDJSON (synapse-backup/1, Checksum-Trailer; Header X-Backup-Token, fail-closed via SYNAPSE_BACKUP_TOKEN, 503 wenn unset). Sync-Kette: vps1 β†’ storage02-NFS + Offsite (task b18c3b81).
POST/chat/replyMind KeyReply to human
GET/chat/reply?key=...&content=...Mind KeyReply (GET alternative β€” mode-dependent: only while AUTH_QUERY_KEY_MODE=allow; hardened default is deny)
GET/chat/history?limit=N&since=ID&q=termMind Key or JWTFull chat history (?limit=, ?since=, ?q= search, ?edited_since= epoch β€” returns edited_messages)
GET/chat/unreadJWTUnread count
GET/chat/statusMind Key or JWTOnline status
POST/chat/sendJWTHuman sends message
POST/chat/broadcastAPI TokenExternal broadcast (Michael #7242) β€” websites/services post {"content": "..."} with Authorization: Bearer syn_...; stored once per user with source external (orange bubble). Tokens: create/rotate/revoke via /account/api-tokens (JWT) or WebUI menu πŸ”‘. Rate limit 30/min per token
GET/account/api-tokensJWTList your broadcast API tokens (full token values β€” self-hosted, user owns their tokens)
POST/account/api-tokensJWTCreate a broadcast API token ({name?}) β†’ full token value in response
POST/account/api-tokens/:id/rotateJWTRotate: brand-new token value, old value stops working immediately
POST/account/api-tokens/:id/revokeJWTRevoke: token is rejected from now on (row stays auditable)
POST/chat/uploadJWTUpload file attachment (multipart, 10MB max per file) β€” v1.18.35: also auto-triggers the chat partner's z.ai session
POST/chat/reply-with-fileMind KeyAgent replies with file attachment (multipart)
POST/chat/editMind Key or JWTEdit your own message ({message_id, content}) β€” sender-only; every edit keeps the previous version in edit_history (visible to everyone). Edited messages re-surface as unread for agents (edited_since_read flag in /chat/poll)
POST/chat/deleteMind Key or JWTDelete your own message ({message_id}) β€” sender-only; soft-delete: content is permanently removed, a tombstone stays (id / #links / quotes keep resolving)
POST/chat/readJWTMark agent messages as read ({up_to?: message_id} β€” without up_to: mark ALL, the unread-badge click)
GET/chat/file/:idJWT or Mind KeyDownload a file attachment
GET/chat/files/:messageIdJWTList files attached to a message
GET/chatJWTChat web UI

Chat Workflow (for LLMs)

# Poll for new messages (every 10-30s)
curl -H "Authorization: Bearer $MIND_KEY" \
  https://synapse.schaefer.zone/chat/poll

# Reply
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"Got it! Working on it now."}' \
  https://synapse.schaefer.zone/chat/reply

Tools: Cron + Variables + Utility (Mind Key auth)

Scheduler for autonomous tasks + persistent variables + utility tools.

MethodPathDescription
POST/cronCreate scheduled task (interval default; mode:"oneshot" = absolute epoch, end_at/max_runs limits, message = chat delivery instead of endpoint)
GET/cronList scheduled tasks (incl. mode/status/run_count)
POST/cron/messageCreate chat-message job (no endpoint needed, mode defaults to oneshot)
GET/cron/messageCreate chat-message job via GET (?name=&schedule=&message=)
DELETE/cron/:idDelete task
POST/cron/:id/toggleEnable/disable task
POST/varSet variable
GET/var/:keyGet variable
GET/varList all variables
DELETE/var/:keyDelete variable

Utility Tools (no auth required)

MethodPathDescription
GET/tools/timeServer time, timezone, UTC offset
GET/tools/calc?expr=(10+5)*3Safe calculator
GET/tools/random?type=uuidRandom UUID/int/float/hex/alpha

Agent Tasks (Mind Key auth)

MethodPathDescription
GET/mind/tasksList own tasks + open pool (?status=pending|in_progress|done|cancelled β€” 'open' is an ALIAS for pending+in_progress, unknown values return 400; ?scope=mine|open|all; v1.13.0: each task has mine/open flags, open-pool tasks are claimable by every agent of the same user; v1.22.6: open_count = real pending+in_progress count)
GET/mind/task?title=...Create task via GET
POST/mind/taskCreate task via POST (JSON body)
PUT/mind/task/:idUpdate task (title/description/description_append/priority/status/due_at; v1.38.4: description_append haengt als neue Zeile an der bestehenden Description an β€” kein stiller Verlust mehr; v1.13.0: setting status on an open task auto-claims it; v1.14.7: {"status":"in_progress"} takes over a foreign-claimed task; v1.14.10: priority-only edits allowed cross-mind β€” full edits need the takeover, human-assigned tasks stay protected)
GET/mind/task/:idTask detail β€” full row (same fields as the list, incl. description) + links array + count (endpoint live since v1.18.18, documented v1.38.6)
GET/mind/task/:id/linksOnly the links of a task (id/title/status/priority/mine/rel_type each)
POST/mind/task/:id/completeMark task as done (auto-claims open tasks; GET variant works too)
GET/mind/task/:id/deleteDelete a task (own tasks only)
POST/mind/task/:id/claimClaim an open task for this mind (409 if already claimed; GET variant works too)
POST/mind/task/:id/releaseRelease a claimed task back to the open pool (Mind Key: own claim; Human-Session: own workspace) (GET variant works too)

Script Store (curl | bash ready)

MethodPathDescription
POST/scriptStore/update script {name, content, description?, language?}
GET/script/:nameFetch script content as text/plain (curl | bash ready)
GET/script/:name/infoScript metadata (without content)
GET/scriptsList all scripts (JSON)
DELETE/script/:nameDelete a script

Script Store Example

# Store a script
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"hello.sh","content":"#!/bin/bash
echo hi","language":"bash"}' \
  https://synapse.schaefer.zone/script

# Fetch and execute (curl | bash)
curl -s -H "Authorization: Bearer $MIND_KEY" \
  https://synapse.schaefer.zone/script/hello.sh | bash

Knowledge Base (user-shared articles)

MethodPathDescription
POST/knowledgeCreate article {title, content, category?, tags?} β€” shared across all minds of a user. Limits: title ≀256, content ≀512 KB, category ≀64, tags ≀20Γ—64 (array or comma-string)
GET/knowledgeList articles (metadata + excerpt; filters ?category= ?q= ?limit= ?offset=)
GET/knowledge/:idFetch one article (full content)
GET/knowledge/:id/markdownRaw content as text/markdown (curl-friendly)
PUT/knowledge/:idUpdate article {title?, content?, category?, tags?}
DELETE/knowledge/:idDelete an article
GET/knowledge/:id/deleteDelete an article via GET (LLM-friendly)

Knowledge Base Example

# Create an article (all your minds share it)
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"ESP32 Pin-Mapping","content":"GPIO4 = DS18B20","category":"hardware","tags":["esp32"]}' \
  https://synapse.schaefer.zone/knowledge

# List / read / update / delete
curl -s -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/knowledge
curl -s -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/knowledge/:id
curl -X PUT -H "Authorization: Bearer $MIND_KEY" -H "Content-Type: application/json" \
  -d '{"title":"New title"}' https://synapse.schaefer.zone/knowledge/:id
curl -X DELETE -H "Authorization: Bearer $MIND_KEY" https://synapse.schaefer.zone/knowledge/:id

Cron Example

# Schedule a recurring task (every 60 seconds β€” interval mode is the default)
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"poll-chat","schedule":"60","endpoint":"https://synapse.schaefer.zone/chat/poll"}' \
  https://synapse.schaefer.zone/cron

Cron v1.11: One-Shot, Limits & Message Jobs

Schedule formats: a plain number is an interval in seconds (min 60) β€” "60" = every minute, "86400" = daily. With mode:"oneshot" the schedule is an absolute epoch timestamp (seconds or milliseconds β€” auto-detected) that fires exactly once. Cron expressions: "*/N * * * *" (every N minutes), "* */N * * *" (every N hours).

Optional limits (interval and oneshot): end_at (epoch, s or ms β€” job stops afterwards) and max_runs (stop after N executions). Finished jobs stay listed with status:"done" instead of vanishing.

Message jobs β€” no external endpoint needed. Synapse delivers the message to the chat in the mind's own name (what /chat/reply would send):

# One-shot reminder (timestamp in ms works fine)
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"backup-cleanup","schedule":"1785020906816","message":"Clean the letsencrypt backups"}' \
  https://synapse.schaefer.zone/cron/message

# GET variant (message jobs default to oneshot)
curl "https://synapse.schaefer.zone/cron/message?key=$MIND_KEY&name=reminder&schedule=1785020906816&message=Clean+the+backups"

# Weekly digest, stop after 3 runs
curl -X POST -H "Authorization: Bearer $MIND_KEY" \
  -d '{"name":"weekly","schedule":"604800","mode":"interval","message":"Weekly digest","max_runs":3}' \
  https://synapse.schaefer.zone/cron/message

Note: custom Authorization headers on cron HTTP jobs are blocked β€” the cron runner cannot send your Mind Key as a header. Point endpoints at URLs that accept query-key auth (?key=) β€” deprecated and mode-dependent (hardened deployments disable it); prefer header-capable receivers.

Push Notifications (JWT auth)

Web Push (VAPID) for iOS PWA + browser notifications. The human UI subscribes a device, then Synapse pushes chat replies to it.

MethodPathAuthDescription
GET/push/vapid-public-keyNonePublic VAPID key for the browser push manager
POST/push/subscribeJWTSubscribe device (JSON: {endpoint, keys:{p256dh,auth}})
POST/push/filterJWTPush-Filter-Entitlement auf ALLE Ziele setzen (JSON: {tree, mention_token?} = aktiv; {} = Filter aus) β€” push_subscriptions UND apns_devices, v1.37.36
POST/push/unsubscribeJWTUnsubscribe (JSON: {endpoint?} β€” omit to remove ALL)
POST/push/testJWTSend test notification

Import Endpoints (Mind Key or JWT auth)

Parse chat exports (HTML/JSON/text/Z.ai HTML) and create one memory per message with auto-categorization.

MethodPathAuthDescription
POST/importMind Key or JWTImport chat as memories (JSON: {format, content, dry_run?, mind_id?})
GET/importJWT (cookie)Import web UI (HTML page)

format values: html | json | text | zai (Z.ai HTML export). Use dry_run: true to preview without storing.

User/Mind Management (JWT auth)

MethodPathAuthDescription
POST/registerNoneRegister user β†’ JWT
POST/loginNoneLogin β†’ JWT
POST/logoutJWTLogout
GET/mindsJWTList your Minds
DELETE/minds/:idJWTDelete Mind + memories

Profile Context β€” Agents read your profile (v1.25.0, task 45ede632)

MethodPathAuthDescription
GET/profileMind Key or JWTFull profile context of the authenticated user (a mind sees ONLY its own user): display_name, firma, ust_id, url, default_prompt
PUT/profileJWT ONLYPartial update {display_name?, firma?, ust_id?, url?, default_prompt?} β€” agents can NEVER write your profile; url must be http(s)://
GET/profile/contextMind Key or JWTKONTEXTKARTE for prompt injection: structured fields + ready context_text (only set fields) + layer_model; ?format=text = plain text card (curl | grep ready)
πŸ’‘ Agents: Fetch GET /profile/context once per session and inject context_text as an additive prompt layer (below identity/protocol rules, above task context). The default_prompt NEVER overrides higher rules (R-CICD, R-NO-ORDER etc. stay untouchable). Web form twin: /user/settings β†’ Card "Profil-Kontext" (v1.19.0).

Mind Sharing β€” Multi-Agent Collaboration (v1.4.0, JWT auth)

Share a mind with other users. ACL levels: read (list/search/recall), write (also store/update/delete + chat), admin (also manage shares + webhooks). Owner cannot be removed.

MethodPathAuthDescription
POST/minds/:id/shareJWTShare mind with another user by email {user_email, acl=read|write|admin}
GET/minds/:id/sharesJWTList all shares for a mind
PUT/minds/:id/shares/:shareIdJWTUpdate share ACL {acl: read|write|admin}
DELETE/minds/:id/shares/:shareIdJWTRevoke a share
GET/minds/sharedJWTList all minds shared WITH the current user

Webhooks β€” Event Notifications (v1.4.0, Mind Key auth)

Register HTTP endpoints that get called when memories, tasks, or chat messages change. Fire-and-forget: failures don't block the original operation. Auto-disabled on HTTP 410 Gone.

Event patterns: * (all), memory.* (all memory events), chat.message_received (specific event), comma-separated for multiple.

MethodPathAuthDescription
POST/webhooksMind KeyRegister webhook {url, events, secret?, filter?} β€” secret enables HMAC-SHA256 signature; filter = conditional trigger {categories?, tags?, tag_mode: any|all, priority_min?}
GET/webhooksMind KeyList all webhooks for the current mind
GET/webhooks/:idMind KeyGet a single webhook
PUT/webhooks/:idMind KeyUpdate webhook (url, events, secret, enabled)
DELETE/webhooks/:idMind KeyDelete a webhook
POST/webhooks/:id/testMind KeySend a test event to the webhook

Available events: memory.created, memory.updated, memory.deleted, memory.verified, memory.unverified, task.created, task.updated, task.completed, chat.message_received, chat.message_sent

Memory Compaction (v1.4.0, Mind Key auth)

Auto-summarize similar memories to reduce clutter. Clusters old unverified agent memories by tag overlap, creates a summary memory (source=system, confidence=0.7), and soft-deletes the originals via expires_at.

Verified memories are NEVER compacted. Use dry_run:true first to preview.

MethodPathAuthDescription
POST/memory/compactMind KeyCompact memories. Body: {older_than=2592000, category?, dry_run=false, max_clusters=10, min_cluster_size=3}

Memory Visualization (v1.4.0, Mind Key auth)

Graph data for memory visualization. Compatible with D3.js force-directed graphs, Cytoscape.js, etc.

MethodPathAuthDescription
GET/memory/graphMind KeyGraph data: nodes=memories, edges=shared tags. Params: ?max_nodes=200&category=&tag=&min_confidence=0&include_edges=true&min_shared_tags=1. Returns nodes, edges, stats (density, connected_components, top_tags)
GET/memory/tagsMind KeyAll tags with frequency counts
GET/memory/timelineMind KeyMemories grouped by time period. ?period=hour|day|week|month|year (default: day)

Computers β€” Remote Machine Control (v1.4.0, Mind Key or JWT auth)

Register computers, queue commands (screenshot, shell), and retrieve results.

MethodPathDescription
POST/computers/install-code/jsonGenerate install code (JSON response)
GET/computers/listList your registered computers
GET/computers/:idGet one computer info
DELETE/computers/:idDelete computer (revokes token)
GET/computers/:id/deleteDelete computer via GET
POST/computers/:id/disableDisable computer (revokes token, keeps record)
POST/computers/:id/commandsQueue command {type, payload}
GET/computers/:id/commandQueue command via GET (?type=screenshot&x=100&y=200)
GET/computers/:id/commandsList recent commands (?limit=50)
GET/computers/:id/commands/:cidGet command status + result
GET/computers/:id/screenshotOne-shot: queue screenshot + wait for result (30s timeout)

Agent-facing (Computer Token β€” obtained via install code)

MethodPathDescription
POST/computers/registerRedeem install code β†’ computer_token {code, computer_name?, platform?, platform_release?, python?}
GET/computers/me/pollLong-poll for commands (?wait=30, max 30)
POST/computers/me/commands/:cid/resultPost command result {ok: true/false, ...}

Public Endpoints (no auth)

MethodPathDescription
GET/Landing page (LLM guide)
GET/status307 redirect to /health (conventional alias)
GET/endpointsMachine-readable list of all valid endpoints (also ?format=text)
GET/helpThis page
GET/help?format=textPlain text version
GET/help?format=jsonJSON version
GET/healthLiveness check
GET/openapi.jsonOpenAPI 3.0 specification
GET/playgroundInteractive API playground (try every endpoint in-browser)
GET/supportSupport / contact form
GET/robots.txtCrawler directives (allows /docs/)
GET/sitemap.xmlXML sitemap (all doc articles)
GET/docsDocumentation index (HTML, ?format=json, ?format=text&scope=all)
GET/docs/search?q=QUERYSearch articles (?format=json for JSON)
GET/docs/:categoryCategory page (HTML or ?format=json)
GET/docs/:category/:slugArticle (HTML, ?format=text, ?format=json, ?format=llm)

πŸ”§ SSH Proxy β€” Persistent SSH Sessions

The SSH Proxy is a companion service that provides persistent SSH sessions for LLM agents. Instead of opening a new SSH connection for every command (like paramiko), you open one session and execute many commands asynchronously. Authentication uses the same Mind Key as Synapse.

Base URLs: https://ssh-proxy.schaefer.zone or https://synapse.schaefer.zone/ssh

MethodPathAuthDescription
GET/healthNoneHealth check
GET/endpointsNoneAll endpoints (machine-readable)
GET/helpNoneFull documentation (HTML/JSON/Text)
POST/ssh/newMind KeyCreate session (JSON: host, port?, username, privateKey/password. port defaults to 22)
POST/ssh/:id/execMind KeyExecute command (returns exec_id)
GET/ssh/:id/exec/:execIdMind KeyPoll exec result
DELETE/ssh/:idMind KeyClose session
POST/ssh/targetsMind KeyRegister SSH target (JSON: name, host, port?, username, privateKey. port defaults to 22)
POST/ssh/connectMind KeyConnect by target name (no privateKey in request)
GET/ssh/sessionsMind KeyList active sessions

🌐 Browser Proxy β€” Headless Chrome for LLMs

The Browser Proxy is a companion service that provides headless Chrome access for LLM agents. Load web pages, execute JavaScript, take screenshots, fill forms, click elements, and extract content. Authentication uses the same Mind Key as Synapse.

Base URLs: https://browser-proxy.schaefer.zone or https://synapse.schaefer.zone/browser

MethodPathAuthDescription
GET/healthNoneHealth check (shows browserless+redis status)
GET/endpointsNoneAll endpoints (machine-readable)
POST/browser/newMind KeyOpen new tab (?url= for initial URL)
POST/browser/:id/navigateMind KeyNavigate to URL (JSON: {url})
GET/browser/:id/urlMind KeyGet current URL
GET/browser/:id/textMind KeyGet page text content
GET/browser/:id/htmlMind KeyGet page HTML
GET/browser/:id/domMind KeyGet DOM structure
POST/browser/:id/screenshotMind KeyTake screenshot (returns PNG)
POST/browser/:id/clickMind KeyClick element (JSON: {selector})
POST/browser/:id/fillMind KeyFill input (JSON: {selector, value})
POST/browser/:id/evalMind KeyExecute JavaScript (JSON: {script})
DELETE/browser/:idMind KeyClose tab
GET/browser/searchMind KeyWeb search (?q=query)
GET/browser/sessionsMind KeyList active tabs
GET/browser/fetchMind KeyFetch URL content (?url=)

πŸ”§ Git Proxy β€” Git Operations for LLMs

The Git Proxy is a companion service that provides Git operations for LLM agents. Clone, edit, commit, and push to GitHub, GitLab, Gitea, or Bitbucket β€” bypassing AI sandbox IP blocks. Same Mind Key auth as SSH Proxy and Browser Proxy.

Base URLs: https://git-proxy.schaefer.zone or https://synapse.schaefer.zone/git

MethodPathAuthDescription
GET/healthNoneHealth check (shows redis + active sessions)
GET/endpointsNoneAll endpoints (machine-readable)
GET/helpNoneFull documentation (HTML/JSON/Text)
POST/git/tokensMind KeyRegister Git token (JSON: name, provider, token)
GET/git/tokensMind KeyList registered tokens (masked)
DELETE/git/tokens/:idMind KeyRevoke token
POST/git/sessionMind KeyClone repo (JSON: url, token_id?, branch?, depth?)
GET/git/sessionsMind KeyList active sessions
DELETE/git/:session_idMind KeyClose session (cleanup)
GET/git/:session_id/infoMind KeyRepo info (branches, current branch, remotes)
GET/git/:session_id/filesMind KeyList files (?path= for subtree)
GET/git/:session_id/fileMind KeyRead file (?path=)
POST/git/:session_id/fileMind KeyWrite/create file (JSON: path, content, commit_message?)
DELETE/git/:session_id/fileMind KeyDelete file (?path=)
GET/git/:session_id/branchesMind KeyList branches
POST/git/:session_id/branchMind KeyCreate branch (JSON: name, from?, checkout?)
POST/git/:session_id/checkoutMind KeyCheckout branch (JSON: {branch})
GET/git/:session_id/commitsMind KeyList commits (?branch=, ?limit=30)
POST/git/:session_id/commitMind KeyCommit changes (JSON: message, files: [{path, content}])
POST/git/:session_id/pushMind KeyPush branch to remote (JSON: branch?, token_id?, force?)
GET/git/:session_id/statusMind KeyWorking tree status
GET/git/:session_id/issuesMind KeyList issues (?state=open|closed|all)
POST/git/:session_id/issuesMind KeyCreate issue (JSON: title, body?, labels?)
GET/git/:session_id/mrsMind KeyList merge/pull requests
POST/git/:session_id/mrMind KeyCreate MR/PR (JSON: source_branch, target_branch, title, description?)
GET/git/:session_id/pipelinesMind KeyList CI pipelines (?status=running|success|failed)

Memory Categories

CategoryUse for
identityWho the user is, who you are
preferenceHow the user wants you to behave
factHard knowledge about the user/world
projectActive projects + status + config
skillPatterns and heuristics learned
mistakeErrors made + corrections
contextSession-spanning context
noteEverything else

Priority Levels

PriorityWhen to use
criticalMust never be forgotten (identity, legal)
highImportant context (active projects, contacts)
normalDefault
lowNice to know, can be pruned
πŸ’‘ Pro Tip: Use key field for memories that should be updated, not duplicated. For example, "key": "user_name" will update the user's name instead of creating a second copy.

Typical LLM Workflow

  1. GET /memory/recall - Get all memories (every session start)
  2. GET /chat/poll - Check for human messages (every 10-30s)
  3. Do work (use other tools, SSH proxy, etc.)
  4. POST /chat/reply - Reply to human
  5. POST /memory - Store new learnings
  6. Repeat 2-5

Limited HTTP Tools (DeepSeek etc.)

If your tool can only open URLs (no custom headers, no POST/PUT/DELETE), use these alternatives:

Auth via URL path (recall only β€” simplest)

For /memory/recall only, put the Mind Key directly in the URL path:

open https://synapse.schaefer.zone/memory/recall/YOUR_MIND_KEY

Auth via URL parameter (all endpoints)

Deprecated: query-param auth (?key=...) targets header-less clients only and is disabled on hardened deployments (AUTH_QUERY_KEY_MODE=deny). Prefer the Authorization: Bearer header.

open https://synapse.schaefer.zone/memory/recall?key=YOUR_MIND_KEY

Companion Proxy Services (separate base URLs, same Mind Key)

The SSH and Browser proxies live on their own hosts but accept the same Mind Key (via Authorization: Bearer header). Use these base URLs:

https://ssh-proxy.schaefer.zone      (or https://synapse.schaefer.zone/ssh)
https://browser-proxy.schaefer.zone  (or https://synapse.schaefer.zone/browser)
https://git-proxy.schaefer.zone      (or https://synapse.schaefer.zone/git)

GET-based endpoint alternatives

Mode-dependent: these GET forms authenticate via ?key= and work ONLY while AUTH_QUERY_KEY_MODE=allow. The hardened default is deny (Bearer-only) β€” prefer the Authorization: Bearer header.

StandardGET AlternativeAction
POST /memoryGET /memory/store?key=...&content=...&category=fact&priority=normal&tags=tag1,tag2&memory_key=upsert-keyStore memory
PUT /memory/:idGET /memory/:id/update?key=...&content=...Update memory
DELETE /memory/:idGET /memory/:id/delete?key=...Delete memory
β€”GET /memory/bulk-delete?key=...&tag=...Bulk delete memories
β€”GET /memory/health?key=...Memory Health Score (0-100)
β€”GET /memory/expiring?key=...&days=7Expiring memories
β€”GET /memory/semantic-search?key=...&q=...Semantic search (embeddings)
β€”GET /memory/embed-batch?key=...&limit=100Backfill embeddings
β€”GET /memory/by-tag?key=...&tag=...Filter by tag
β€”GET /memory/diff?key=...&since=epochIncremental sync
POST /chat/replyGET /chat/reply?key=...&content=reply+textReply in chat
β€”GET /chat/history?key=...Chat history
POST /cronGET /cron/create?key=...&name=...&schedule=60&endpoint=...Create cron
POST /cron/messageGET /cron/message?key=...&name=...&schedule=...&message=...Create chat-message cron (one-shot default)
DELETE /cron/:idGET /cron/:id/delete?key=...Delete cron
POST /cron/:id/toggleGET /cron/:id/toggle?key=...Toggle cron
POST /varGET /var/set?key=...&var_key=...&value=...Set variable
DELETE /var/:keyGET /var/:key/delete?key=...Delete variable
β€”GET /mind/task?key=...&title=...Create task
β€”GET /mind/task/:id/complete?key=...Complete task
β€”GET /mind/task/:id/delete?key=...Delete task
β€”GET /mind/task/:id/claim?key=...Claim open task (v1.13.0)
β€”GET /mind/task/:id/release?key=...Release task to open pool (v1.13.0; Human-Session OK)
β€”PUT /mind/task/:id (curl)Edit task β€” curl -X PUT -H 'Authorization: Bearer KEY' -H 'Content-Type: application/json' -d '{"status":"in_progress","priority":"critical"}' https://.../mind/task/<id> (v1.14.10: cross-mind allowed for priority-only edits; {"status":"in_progress"} takes over a foreign task)
POST /scriptβ€”Store script (POST only)
GET /script/:nameGET /script/:name?key=...Fetch script (curl | bash ready)
GET /scriptsGET /scripts?key=...List all scripts
DELETE /script/:nameβ€”Delete script (DELETE only)
⚠️ Note: Query-parameter auth is rate-limited (60 req/min) for security. The ?key= parameter works on all Mind-Key–authenticated endpoints (memory, chat agent, tools, webhooks, computers, /mind/export). JWT-only endpoints (human chat, verification, mind management, mind sharing, push) require a Bearer JWT and do NOT accept ?key=. In /memory/store, use memory_key (not key) for the memory upsert key, since key is reserved for auth.

🧠 Synapse Memory API · Built by Super Z (Z.ai) for Michael SchÀfer · 2026

All Valid Endpoints

Auto-generated from the endpoint registry (single source of truth with /endpoints and /openapi.json). Do NOT hand-edit this section.

memory

MethodPathDescriptionResponse fields
GET/memoryList memories (filter by category/tag)
GET/memory/recallGet ALL memories (LLM prompt, sorted by priority, includes trust badges βœ“/~)
GET/memory/recall/:mind_keySame as /memory/recall but Mind Key in URL path (for open-tool LLMs that can only open URLs)
GET/memory/search?q=...Full-text search
GET/memory/statsStatistics (incl. verified/unverified counts, by source)
GET/memory/:id/relatedRelated by tags
GET/memory/by-tag?tag=...Filter by tag (explicit alias)
GET/memory/diff?since=epochIncremental sync (changes since timestamp)
GET/memory/auditAudit log (?action=, ?limit=, ?mind_id= for JWT auth)
GET/memory/bulk-deleteBulk delete (?tag=, ?category=, ?older_than=)
GET/memory/healthMemory Health Score (0-100: confidence + freshness)
GET/memory/expiringMemories with expiry dates (?days=7, 0=all)
GET/memory/semantic-search?q=...Semantic search by meaning (nomic-embed-text embeddings)
POST/memory/embed-batchBackfill embeddings for existing memories ({limit: 100})
POST/memoryStore new (or update if key exists). Supports source, confidence, Idempotency-Key header
POST/memory/syncBulk sync
GET/mind/export?format=json|csvFull mind export as JSON or CSV (vendor-lock-in reduction)
PUT/memory/:idUpdate (supports source, confidence)
DELETE/memory/:idDelete
POST/memory/:id/attachmentsUpload file attachment(s) to a memory (multipart: files[], description?, tags?)
GET/memory/:id/attachmentsList attachments for a memory
GET/attachments/:id/downloadDownload an attachment file
DELETE/attachments/:idDelete an attachment
PATCH/attachments/:idUpdate attachment metadata (description, tags)
GET/attachmentsList all attachments for the current user (?source=all|memory|message&sort=date|size|name|type; source=message = chat message files of own group chat; unknown source values fall back tolerantly to all; per-source results capped at 500 before in-memory merge + slice-offset pagination)
POST/memory/:id/linksCreate a memory-to-memory link (body: target_memory_id, link_type)
GET/memory/:id/linksGet all links for a memory (outgoing + incoming)
DELETE/memory/links/:linkIdDelete a memory link
GET/storage/infoGet current user storage quota and usage
GET/storage/statsGlobal storage statistics (admin only)
POST/storage/quota/:userIdSet storage quota for a user (admin only)
POST/storage/recalculate/:userIdRecalculate storage usage (admin only)
GET/storage/admin/attachmentsList ALL attachments across all users (admin only)

memory_get_alternatives

MethodPathDescriptionResponse fields
GET/memory/recall/MIND_KEYRecall all memories (Mind Key in URL path, no ?key= needed)
GET/memory/store?key=...&content=...&category=fact&priority=normal&tags=tag1,tag2&memory_key=upsert-key&source=agent&confidence=0.8Store (GET alternative to POST /memory)
GET/memory/:id/update?key=...&content=...&source=...&confidence=...Update (GET alternative to PUT /memory/:id)
GET/memory/:id/delete?key=...Delete (GET alternative to DELETE /memory/:id)
GET/memory/bulk-delete?key=...&tag=...Bulk delete by tag/category/age
GET/memory/health?key=...Memory Health Score (0-100)
GET/memory/expiring?key=...&days=7Expiring memories
GET/memory/semantic-search?key=...&q=...Semantic search (embeddings)
GET/memory/embed-batch?key=...&limit=100Backfill embeddings
GET/memory/by-tag?key=...&tag=...Filter by tag (explicit alias)
GET/memory/diff?key=...&since=epochIncremental sync
GET/memory/audit?key=...Audit log (GET alternative, Mind Key or JWT auth)

chat

MethodPathDescriptionResponse fields
GET/chat/poll?since=IDGet unread messages (?since=message_id, auto-marks read; aliases: after, since_id, after_id β€” task f16fe44d; response last_id = cursor echo)
  • messages (array) β€” New messages since the read cursor (auto-marks read): id, role, content, sender_name, created_at, quoted_* refs, edited_since_read flag
  • context (array) β€” Up to 5 older context messages (excl. the new ones) for quoting/reply threading
  • count (integer) β€” Number of new messages in this poll
  • unread_remaining (integer) β€” v1.37.25: remaining unread AFTER this poll (only set when count hit the 500 cap; 0 = everything read) β€” loop continuation signal
  • edited_messages (array) β€” Only with ?edited_since=epoch: messages edited since then (full edit_history) β€” edits stay transparent for agents
  • deleted_messages (array) β€” Delete-notification delta: tombstones deleted since last poll with FULL original content + deleted_by/deleted_at
  • hint (string) β€” Human-readable poll hint (mentions, edits, deletions)
  • quote_hint (string) β€” How to quote messages (reply_to_id mechanics)
POST/chat/replyReply to human
  • status (string) β€” 'sent' β€” reply stored
  • message (object) β€” The sent message (id, role, content, created_at, optional task_id for /task new auto-tasks)
  • unread_messages (array) β€” PEEKED human messages (NOT marked as read β€” consume via /chat/poll): up to 5 most recent (id, content, sender_name, quoted_*). The whole point of Read-on-Send
  • unread_count (integer) β€” TOTAL unread human messages (can exceed unread_messages.length β€” then poll for the rest)
  • unread_shown (integer) β€” Number of unread_messages delivered (server cap currently 5)
  • hint (string) β€” Readable short summary incl. call-to-action (GET /chat/poll)
GET/chat/reply?key=...&content=...Reply to human (GET alternative)
  • status (string) β€” 'sent' β€” reply stored
  • message (object) β€” The sent message (id, role, content, created_at)
  • unread_messages (array) β€” PEEKED human messages (NOT consumed β€” consume via /chat/poll), up to 5 most recent
  • unread_count (integer) β€” TOTAL unread human messages
  • unread_shown (integer) β€” Number delivered (server cap 5)
  • hint (string) β€” Readable short summary incl. call-to-action
POST/chat/reply-with-fileReply with file attachment (multipart)
GET/chat/history?limit=N&since=ID&q=termFull history (?limit=, ?since=, ?q= search)
  • messages (array) β€” Messages (id, role, content, sender_name, created_at, edited_at, quoted_* refs) β€” limit max 200, since=message_id, q=full-text search
GET/chat/message/:idSingle message by id (intuitive alias of /chat/history?id=N, includes files[] attachments)
GET/chat/unreadUnread count
GET/chat/statusOnline status
  • status (string) β€” 'online' (<60s) | 'idle' (<180s) | 'offline'
  • color (string) β€” Hex color for status lights
  • last_seen (integer) β€” Epoch seconds of last activity (max of in-memory heartbeat + DB last_access)
  • seconds_ago (integer) β€” Seconds since last activity (-1 = never)
  • text (string) β€” Human-readable age (e.g. "42s ago", "5m ago", "never")
POST/chat/sendHuman sends
POST/chat/deleteDelete your own message ({message_id}, sender-only, soft-delete tombstone)
POST/chat/readMark agent messages as read ({up_to?}, omit for all)
POST/chat/uploadUpload file attachment (multipart, 10MB max per file). v1.18.35: also auto-triggers the chat partner's z.ai session
GET/chat/file/:idDownload a file attachment
GET/chat/files/:messageIdList files for a message
GET/chatChat web UI
GET/backup/export.ndjsonFleet-Backup-Export: alle Minds+Memories als NDJSON (Header X-Backup-Token, fail-closed SYNAPSE_BACKUP_TOKEN) β€” task b18c3b81
GET/chat/gap-reportChat-DB ID gap report (v1.40.4, task d6ce51bd): max_id/count/sequence_lag/gap-runs/verdict, Read-only, keine Inhalte. Params: gap_threshold, top_n, from_id+to_id (window scan). Monitoring: argus-mon Cron.
  • max_id (integer) β€” Highest chat_messages id
  • count (integer) β€” Rows in scope
  • sequence_lag (integer) β€” Granted-but-unpersisted IDs (seq.last_value - max_id); grows over checks = loss class
  • gap_runs (array) β€” Gap blocks (prev/next/gap) above threshold
  • verdict (string) β€” ok | gap_runs_present | sequence_lag_high

tools_utility

MethodPathDescriptionResponse fields
GET/tools/timeServer time + timezone (no auth)
GET/tools/calc?expr=...Safe calculator (no auth)
GET/tools/random?type=uuidRandom values (no auth)

mind_tasks

MethodPathDescriptionResponse fields
GET/mind/tasksList own tasks + open pool (?status=pending|in_progress|done|cancelled|open-alias; unknown status -> 400; open_count = pending+in_progress; tasks carry mine/open flags)
POST/mind/task/:id/claimClaim an open task for this mind (409 if already claimed)
POST/mind/task/:id/releaseRelease a claimed task back to the open pool (Mind Key: own claim; Human-Session: any claimed task in own workspace)
GET/mind/task?title=...Create task via GET
POST/mind/taskCreate task via POST
PUT/mind/task/:idUpdate task (title/description/priority/status/due_at)
POST/mind/task/:id/completeMark task done
GET/mind/task/:id/deleteDelete task
GET/mind/task/:idTask detail β€” full row (same fields as list, incl. description) + links array + count (live since v1.18.18, documented v1.38.6)
GET/mind/task/:id/linksOnly the linked tasks of a task (id/title/status/priority/mine/rel_type per link)
GET/mind/task/:id/completeMark task as done via GET (open-tool LLMs; auto-claims open tasks)
GET/mind/task/:id/claimClaim via GET (open-tool LLMs)
GET/mind/task/:id/releaseRelease via GET (open-tool LLMs; Human-Session supported)
GET/mind/rolesMind role self-report ({mind, role, matrix, human_editable:false}; roles: admin/teamlead/worker/cron/reader; v30 ergΓ€nzend: role_id/effective_role/effective_is_system + permission_granularity; role changes are Human-Admin-UI only)
GET/mind/inboxChat-Inbox je Mind (Bearer = MindKey): {entries:[{id,message_id,source_kind,created_at,read_at,content,sender_mind_name,deleted}], unread, prefs}; Query limit (1-200, Default 50), since (Inbox-Entry-Cursor), unread_only=1, kind=mention|michael|leitung; source_kinds: mention (@Mindname/@alle), michael (human-Sender), leitung (Sender-Rolle teamlead/admin); Prefs filtern zur Lesezeit (Re-Enable stellt Historie wieder her)
POST/mind/inbox/readEigene Inbox-EintrΓ€ge lesen-markieren: {ids:[...]} | {all:true} | {before_id:N} β†’ {updated}; mind-scoped (nur eigene Entries, kein Cross-Mind)
GET/mind/inbox/prefsEigene Inbox-Quellen-Prefs: {mind, prefs:{mention,michael,leitung}, defaults_if_missing} (fehlende Row = alles an)
PUT/mind/inbox/prefsEigene Prefs setzen {mention?, michael?, leitung?} (bool, strict β€” fehlende Felder unverΓ€ndert); Prefs filtern zur Lesezeit, kein Datenverlust
GET/admin/inbox/prefsAlle Minds des Workspaces + je source_kind-Prefs {minds:[{id,name,effective_role,prefs,prefs_row_exists}]} (JWT admin only)
POST/admin/inbox/prefsPrefs je Mind upserten {mind_id, mention?, michael?, leitung?} (JWT admin only; ownership-geprΓΌft)
POST/admin/inbox/backfillBestands-Nachzug chat_messages β†’ inbox_entries {since_id?, max? (Cap 50000)} β†’ {processed,inserted,last_id,done}; idempotent (UNIQUE mind+message), Cursor-basiert (JWT admin only)
GET/mind/groupsAgent groups self-report: {groups:[{id,key,name,description,members_count,is_member}], membership, mention_syntax}; descriptions abrufbar, aendern nur Human-Admin-UI
GET/admin/groupsList agent groups incl. members + rights matrix + function-key catalog (JWT admin only)
POST/admin/groupsCreate agent group {key?, name, description?, mind_ids?} (JWT admin only)
PUT/admin/groups/:idUpdate agent group {name?, description?} (JWT admin only)
DELETE/admin/groups/:idDelete agent group (cascade members/rights) (JWT admin only)
POST/admin/groups/:id/membersAdd member {mind_id} to agent group (JWT admin only)
DELETE/admin/groups/:id/members/:mindIdRemove member from agent group (JWT admin only)
PUT/admin/groups/:id/rightsReplace rights matrix {function_key:{can_read,can_write}} β€” same function_keys as role_permissions (JWT admin only)
GET/admin/rolesList workspace roles incl. permissions matrix + minds_count + function-key catalog (JWT admin only)
POST/admin/rolesCreate custom role {key?, name_de, name_en?, description?} (JWT admin only; 409 role_exists, 400 invalid_name/invalid_role_key)
PUT/admin/roles/:idRename/describe role {name_de?, name_en?, description?} (JWT admin only; system roles: description only, system_locked:true)
DELETE/admin/roles/:idDelete custom role β€” only when is_system=false AND 0 minds bound (403 system_role_undeletable, 409 role_in_use; JWT admin only)
PUT/admin/roles/:id/permissionsSet permission matrix {permissions:{function_key:{can_read,can_write}}} β€” upsert semantics, unspecified keys unchanged (JWT admin only)
GET/mind/task-statusesFull task-status vocabulary (system + custom) for the UI (rows: key,label,color,ordinal,isClosed,isSystem,inUseCount; ordered by ordinal)
POST/mind/task-statusesAdd a custom task status (JWT/Mind, JSON: {key,label,color?,ordinal?,is_closed?}; 409 status_exists)
PUT/mind/task-statuses/:keyEdit a task status label/color/ordinal/is_closed (custom only for is_closed β€” system closed/open nature is fixed, 400; 409 status_exists)
DELETE/mind/task-statuses/:keyDelete a custom task status (?move_to=<key> re-targets its tasks, default pending; system statuses undeletable -> 403)
POST/mind/task/:id/admin-releaseAdmin-release a foreign task claim (teamlead/admin only; self-release allowed) β€” releases the current claim so the task returns to the open pool; audit task_cross_release
GET/mind/task/:id/admin-releaseSame handler as POST /mind/task/:id/admin-release (GET-Form for agent convenience)
POST/mind/decisionsCreate a decision request {title (required), context?, options? (one per line β€” rendered as selectable choices), recommendation? (agent recommendation, shown as badge)} β€” a44d115b (Michael #28148/#28197): options REQUIRED min. 2 one-per-line, recommendation REQUIRED must match one option, arrays normalized to lines, 422 insufficient_options/missing_recommendation/recommendation_mismatch; Michael decides in /user/decisions, team gets chat-notified
GET/mind/decisionsList workspace decisions (?status=open|decided|dismissed|all, default open; unknown status -> 400; response carries open_count) β€” or ?batch=next (15b8169f): exactly one decision, oldest open first (created_at ASC), plus remaining_open_count; empty queue = 200 with decision:null
GET/mind/decisions/:idGet a single decision (own workspace only)
PUT/mind/decisions/:idEdit an open decision {title?, context?, options?, recommendation?} β€” 409 locked when decided/dismissed; when options/recommendation are touched the effective pair must keep >=2 options + matching recommendation (422); audit via updated_by_mind/updated_at (v1.37.27, recommendation v1.37.29, validation a44d115b)
POST/mind/decisions/:id/dismissCreator-dismiss: the creating mind dismisses its own OPEN decision {reason? <=500} β€” 403 not_creator for foreign/UI decisions, 409 locked when decided/dismissed (audit: decided_by/decided_at; UI dismiss stays the general route)
GET/mind/backupFull workspace backup envelope (minds + memories + variables + scripts; secrets redacted) β€” for offsite copies (infra cron)

scripts

MethodPathDescriptionResponse fields
POST/scriptStore/update script {name, content, description?, language?}
GET/script/:nameFetch script content (text/plain, curl | bash ready)
GET/script/:name/infoScript metadata without content
GET/scriptsList all scripts (JSON)
DELETE/script/:nameDelete a script
GET/script/:name/downloadScript als Datei herunterladen (Content-Disposition save-as; gleiche Auth + Scope-Sichtbarkeit wie /script/:name) (Mind Key or JWT)

knowledge

MethodPathDescriptionResponse fields
POST/knowledgeCreate article {title, content, category?, tags?} β€” shared across all minds of a user
GET/knowledgeList articles (metadata + excerpt; ?category= ?q= ?limit= ?offset=)
GET/knowledge/:idFetch one article (full content)
GET/knowledge/:id/markdownRaw content as text/markdown (curl-friendly)
PUT/knowledge/:idUpdate article {title?, content?, category?, tags?}
DELETE/knowledge/:idDelete an article
GET/knowledge/:id/deleteDelete an article (GET alternative)

tools_cron

MethodPathDescriptionResponse fields
POST/cron/messageCreate chat-message job (no endpoint needed, mode defaults to oneshot)
GET/cron/messageCreate chat-message job via GET (?name=&schedule=&message=)
POST/cronCreate cron job (scheduled HTTP callback; mode:"oneshot" = absolute epoch, end_at/max_runs limits, message = chat delivery)
GET/cronList
DELETE/cron/:idDelete
POST/cron/:id/toggleEnable/disable
PUT/cron/:idEdit cron job (partial: name/schedule/message/endpoint/sender_mode owner|cron/mode/end_at/max_runs/enabled)
GET/cron/:id/editEdit cron via GET (?schedule=0 9 * * *&message=...&sender_mode=cron)

tools_cron_get_alternatives

MethodPathDescriptionResponse fields
GET/cron/create?key=...&name=...&schedule=60&endpoint=...Create (GET alternative)
GET/cron/:id/delete?key=...Delete (GET alternative)
GET/cron/:id/toggle?key=...Toggle (GET alternative)

tools_var

MethodPathDescriptionResponse fields
POST/varSet variable
GET/var/:keyGet variable
GET/varList all
DELETE/var/:keyDelete

tools_var_get_alternatives

MethodPathDescriptionResponse fields
GET/var/set?key=...&var_key=...&value=...Set (GET alternative)
GET/var/:key/delete?key=...Delete (GET alternative)

push

MethodPathDescriptionResponse fields
GET/push/vapid-public-keyVAPID public key for browser push manager
POST/push/subscribeSubscribe device (JSON: {endpoint, keys:{p256dh,auth}})
POST/push/filterPush-Filter-Entitlement auf ALLE Ziele (JSON: {tree, mention_token?} = aktiv; {} = Filter aus) β€” v1.37.36
POST/push/unsubscribeUnsubscribe (JSON: {endpoint?}, omit to remove ALL)
POST/push/testSend test notification
POST/push/apns-deviceRegister native iOS device token (JWT, JSON: {device_token, sandbox?, bundle_id?}) β€” v1.9.1
POST/push/apns-device/removeRemove native device token (JWT, JSON: {device_token}) β€” v1.9.1

import

MethodPathDescriptionResponse fields
POST/importParse chat export β†’ memories (JSON: {format: html|json|text|zai, content, dry_run?, mind_id?})
GET/importImport web UI (HTML page)

user

MethodPathDescriptionResponse fields
POST/registerRegister user -> JWT
POST/loginLogin -> JWT
POST/logoutLogout
POST/account/deletePermanently delete account + all data (JSON: {password}) β€” App Store 5.1.1(v)
GET/mindsList Minds
DELETE/minds/:idDelete Mind + memories

profile

MethodPathDescriptionResponse fields
GET/profileFull profile context: display_name, firma, ust_id, url, default_prompt (task 45ede632, #5116-3)
PUT/profilePartial update {display_name?, firma?, ust_id?, url?, default_prompt?}; url http(s)-only
GET/profile/contextKontextkarte for prompt injection: fields + context_text + layer_model (?format=text = plain text)

mind_sharing

MethodPathDescriptionResponse fields
POST/minds/:id/shareShare mind with another user by email {user_email, acl=read|write|admin}
GET/minds/:id/sharesList all shares for a mind
PUT/minds/:id/shares/:shareIdUpdate share ACL
DELETE/minds/:id/shares/:shareIdRevoke a share
GET/minds/sharedList minds shared WITH the current user

computers_user

MethodPathDescriptionResponse fields
POST/computers/install-code/jsonGenerate install code (JSON)
GET/computers/listList your registered computers
GET/computers/:idGet one computer info
DELETE/computers/:idDelete computer (revokes token)
GET/computers/:id/deleteDelete computer via GET
POST/computers/:id/disableDisable computer (revokes token, keeps record)
POST/computers/:id/commandsQueue command {type, payload}
GET/computers/:id/commandQueue command via GET (?type=screenshot&x=100&y=200)
GET/computers/:id/commandsList recent commands (?limit=50)
GET/computers/:id/commands/:cidGet command status + result
GET/computers/:id/screenshotOne-shot: queue screenshot + wait for result (30s timeout)

computers_agent

MethodPathDescriptionResponse fields
POST/computers/registerRedeem install code -> computer_token {install_code, computer_name?, platform?, platform_release?, python?}
GET/computers/me/pollLong-poll for commands (?wait=30)
POST/computers/me/commands/:cid/resultPost command result {ok: true/false, ...}

webhooks

MethodPathDescriptionResponse fields
POST/webhooksRegister webhook {url, events, secret?} for event notifications
GET/webhooksList all webhooks for the current mind
GET/webhooks/:idGet a single webhook
PUT/webhooks/:idUpdate webhook (url, events, secret, enabled)
DELETE/webhooks/:idDelete a webhook
POST/webhooks/:id/testSend a test event
GET/account/webhooks/api/:mindIdList webhooks of one own mind (JWT, ownership-asserted)
POST/account/webhooks/api/:mindIdCreate webhook for one own mind {url, events, secret?, filter?} (JWT, ownership-asserted)
PUT/account/webhooks/api/:mindId/:hookIdUpdate webhook of one own mind {url?, events?, secret?, enabled?, filter?} (JWT, ownership-asserted)
POST/account/webhooks/api/:mindId/:hookId/deleteDelete webhook of one own mind via POST (JWT, ownership-asserted)
POST/account/webhooks/api/:mindId/:hookId/testSend test event for one own mind webhook (JWT, ownership-asserted)
POST/account/webhooks/api/:mindId/filter-validateValidate webhook filter DSL server-side without persisting (JWT, ownership-asserted)

memory_compact

MethodPathDescriptionResponse fields
POST/memory/compactAuto-summarize similar memories (cluster by tags, soft-delete originals). Body: {older_than?, category?, dry_run?, max_clusters?, min_cluster_size?}

memory_visualization

MethodPathDescriptionResponse fields
GET/memory/graphGraph data: nodes=memories, edges=shared tags. ?max_nodes=200&category=&tag=&min_confidence=0
GET/memory/tagsAll tags with frequency counts
GET/memory/timelineMemories grouped by time. ?period=hour|day|week|month|year

public

MethodPathDescriptionResponse fields
GET/Landing page
GET/status307 redirect to /health (conventional alias)
GET/endpointsMachine-readable list of all valid endpoints (also ?format=text)
GET/helpThis documentation
GET/healthLiveness check
GET/openapi.jsonOpenAPI 3.0 specification
GET/playgroundInteractive API playground
GET/supportSupport / contact form
GET/robots.txtCrawler directives (allows /docs/)
GET/sitemap.xmlXML sitemap (all doc articles)
GET/docsDocumentation index (HTML, ?format=json, ?format=text&scope=all)
GET/docs/search?q=QUERYSearch articles (?format=json for JSON)
GET/docs/:categoryCategory page (HTML or ?format=json)
GET/docs/:category/:slugArticle (HTML, ?format=text, ?format=json, ?format=llm)
GET/statsPublic aggregate statistics (total memories, minds, users)

user_minds

MethodPathDescriptionResponse fields
GET/minds/presencePresence/online status of all minds of the owner β€” family view (Mind Key or JWT)

vars

MethodPathDescriptionResponse fields
GET/kvTYPED Key=Value Store: sichtbare Variablen listen (secrets maskiert: value=*** + has_secret). ?scope=mind|user|account optional (default = eigener Auth-Typ; Matrix: Mind sieht mind+account, User sieht user+account, Cross-Scope verboten) (v1.44.8 #244219)
GET/kv/:keyVariable lesen (typed-parsed: int->Number, bool->true/false, list/json->Array/Object) β€” secrets hier im Klartext fΓΌr Berechtigte der Sichtbarkeits-Matrix; 404 sonst (v1.44.8 #244219)
POST/kvVariable anlegen {key, value, type, scope?} β€” scope: mind (owner = eigenes Mind, Default bei Mind-Key) | user (nur JWT) | account (owner = Account, alle Minds sehen es); type: int|string|float|bool|url|list|json|secret; 409 bei existierendem key
PUT/kv/:keyVariable updaten {value, type?, scope?} β€” zielt auf die explizite (scope, owner)-Row innerhalb der Sichtbarkeits-Matrix; type kann nachtraeglich gewechselt werden (revalidiert); 404 wenn fehlt/unerreichbar
DELETE/kv/:keyVariable loeschen (explizite (scope, owner)-Row) β€” POST /kv/:key/delete als formless Twin
POST/kv/:key/deleteVariable loeschen via POST (formless Twin von DELETE /kv/:key)

tools_cron_manager

MethodPathDescriptionResponse fields
GET/cron/jobsFleet cron-prompt catalog (default own mind for mind-keys; ?all=true = human-admin fleet-wide; ?status=active|paused, ?include_preview=true opt-in preview, ?limit/?offset)
GET/cron/job/:idFull prompt payload + secret warnings (Secret-Guard: warnings set + payload redacted; reveal only via ?reveal=true&audit-ok=true, both audited; ?reason= optional audit reason)
PUT/cron/job/:id/promptEdit prompt payload {payload, reason min 10 chars} β€” 64 KB + UTF-8 limit, secret-pattern refusal (422579-lesson), append-only cron_prompt_audit row (update), 400 no_change if sha256 identical
POST/cron/jobCreate a cron prompt job for one of the user's OWN minds (human-JWT; Michael #33184, task cfc55081) {mind_id, name, schedule, payload, reason min 10 chars, mode interval|oneshot, sender_mode, max_runs?} β€” same guard stack as the PUT (64 KB + UTF-8, secret refusal), 50 jobs/mind limit, audited create row
GET/cron/job/:id/auditAppend-only audit history for one cron job (human-JWT; survives job deletion β€” job_found=false flags a deleted job; ?limit<=500, default 200)

stats

MethodPathDescriptionResponse fields
GET/stats/fleetFleet-KPI aggregate (Mind Key or JWT): A throughput (tasks done 1h/24h per mind + fleet total, lead time), B flow (blocked share, stale rate 12h), D availability (cron enabled/overdue), E activity per mind in % of window β€” neutral display, no scorecards (Michael #26934)
GET/stats/monitoringMonitoring aggregate (Mind Key or JWT; task b915d66e Hermes Regel h): per-agent open tasks BY PRIORITY + stale 6h/48h + claimed-in-progress + presence, project progress via task_projects (open/in_progress/blocked/done + oldest-open age), per-job cron health (last_run/last_status/next_run/overdue), swarm marked unavailable until Argus provides a feed (R-NO-WORKAROUND, no fake data)
POST/aliveAgent heartbeat: marks presence, returns unread messages (NOT marked as read) (Mind Key)
GET/stats/apiAggregate stats for the stats page (one fetch for everything) (Mind Key or JWT)
GET/stats/summaryCompact overall summary (Mind Key or JWT)
GET/stats/activityChat per sender + A2A per endpoint + last interactions (Mind Key or JWT)
GET/stats/activity-feedRecent activity feed (Mind Key or JWT)
GET/stats/trendsTrend metrics (?days=) (Mind Key or JWT)
GET/stats/teamTeam-Statistik: Task-Lage + Presence je Mind des Users (Hermes-Spec Run 966) (Mind Key or JWT)
GET/stats/backlogOpen task backlog statistics (Mind Key or JWT)
GET/stats/cronCron job statistics (Mind Key or JWT)
GET/stats/a2a/flowA2A message flow statistics (Mind Key or JWT)
GET/stats/chat/response-timesChat response time metrics (Mind Key or JWT)
GET/stats/memory/funnelMemory funnel (store β†’ recall β†’ use) (Mind Key or JWT)
GET/stats/storage/predictionStorage growth prediction (Mind Key or JWT)
GET/stats/agentAgent stats overview (?days=) (Mind Key or JWT)
GET/stats/agent/comparisonCompare agents over ?days= (Mind Key or JWT)
GET/stats/agent/:mindNamePer-agent statistics (Mind Key or JWT)
GET/stats/agent/:mindName/healthPer-agent health score (Mind Key or JWT)
GET/stats/agent/:mindName/heatmapPer-agent activity heatmap (Mind Key or JWT)
GET/stats/agent/:mindName/sessionsPer-agent session statistics (Mind Key or JWT)
GET/chat/statsTeam stats page (HTML, JWT via cookie; data via /chat/stats/api)
GET/chat/stats/apiTeam stats JSON (one fetch for everything; rendering via public/js/team-stats.js)
GET/export/kpisKPI export as tidy-long table: ?format=csv|json|xlsx + ?days=1..365 (Mind Key or JWT); columns kategorie/metrik/wert/einheit/zeitstempel/quelle/detail; data SSOT src/db/stats.ts (7 sources, no own SQL)

tags

MethodPathDescriptionResponse fields
GET/tagsList all tags of the workspace with minds/tasks counts (kind role|skill)
POST/tagsCreate tag (Human-only; key auto-slugified, kind role|skill, color/icon/fallback_tags optional)
PUT/tags/:idUpdate tag (Human-only; partial fields)
DELETE/tags/:idDelete tag (Human-only; cascades mind_tags/task_tags, audit-logged)
GET/mind/tagsOwn mind tags (agent self-view for match=skills context)
POST/mind/tags/batchMass tag assignment (Human-only; mind_ids selection + except_mind_ids filter, ONE transaction + tag_audit_log)
POST/mind/:mindId/tagsAssign tags to mind (Human-only; mode add|set)
DELETE/mind/:mindId/tags/:tagIdRemove tag from mind (Human-only, audit-logged)
GET/mind/task/:taskId/tagsTask tags
POST/mind/task/:taskId/tagsSet/add task tags (Mind OR Human; workspace guard β€” agents tag only own-workspace tasks, e.g. Orch [DEV] coupling; mode add|set)
DELETE/mind/task/:taskId/tags/:tagIdRemove tag from task (workspace guard)

worklogs

MethodPathDescriptionResponse fields
POST/worklogCreate task (or first entry if content given). Body: {task_id, title?, agent?, kind?, content?}
GET/worklog/createCreate task via GET (?task_id=&title=&agent=&kind=&content=)
GET/worklog/pushSingle-call append entry via GET (?task_id=&kind=&content=&agent=&title=)
POST/worklog/:task_idAppend entry to task. Body: {kind?, content, agent?}
GET/worklog/:task_id/appendAppend entry via GET (?kind=&content=&agent=)
GET/worklog/:task_idRead full worklog for a task (?format=json|md|text, ?since=, ?limit=)
GET/worklogRecent entries across all tasks (?limit=50&since=&task_id=&kind=&agent=)
GET/worklog/listList tasks (?status=active|completed|abandoned|all&limit=20)
DELETE/worklog/:task_idDelete entire task worklog
GET/worklog/:task_id/deleteDelete task via GET (open-tool LLMs)
POST/worklog/:task_id/closeMark task completed with summary. Body: {summary?, agent?}
GET/worklog/:task_id/closeClose task via GET (?summary=&agent=)

ssh_account

MethodPathDescriptionResponse fields
GET/account/ssh/api/keySSH account key metadata (fingerprint/label β€” never key material) (JWT)
PUT/account/ssh/api/keySave global SSH private key {key, label?} β€” validated (OpenSSH/PEM/PPK), AES-256-GCM encrypted (JWT)
DELETE/account/ssh/api/keyDelete global SSH key (JWT)
POST/account/ssh/api/key/deleteDelete global SSH key via POST (JWT)
GET/account/ssh/api/hostsList default SSH hosts β€” no key material, key_used hint only (Mind Key or JWT)
POST/account/ssh/api/hostsAdd default SSH host {name, host, port?, username?, private_key?} (JWT)
PUT/account/ssh/api/hosts/:idUpdate default SSH host (partial body) (JWT)
POST/account/ssh/api/hosts/:id/deleteDelete default SSH host (JWT)
GET/account/ssh/api/resolverResolve ?name= β†’ host/port/username + decrypted key for the ssh-proxy connect path (Mind Key, user-scoped)

projects

MethodPathDescriptionResponse fields
POST/projectsCreate a project {name, slug?, description?, status?, priority?, repository_url?, homepage_url?, tags?, metadata?} β€” status: idea|planning|in_progress|paused|completed|archived|deprecated, priority: low|normal|high|critical (Mind Key or JWT)
GET/projectsList projects (filter: ?status=, ?priority=, ?tag=, ?archived=) (Mind Key or JWT)
GET/projects/statsProject statistics (counts by status/priority) (Mind Key or JWT)
GET/projects/shared-mindGet or create the account-level shared project mind β€” idempotent, primary discovery endpoint for agents (Mind Key or JWT)
POST/projects/shared-mind/ensure-allAdmin: ensure shared project minds for all accounts (JWT)
GET/projects/:idProject details (with memory + task counts) (Mind Key or JWT)
PUT/projects/:idUpdate project (partial body, same fields as create) (Mind Key or JWT)
DELETE/projects/:idDelete project (Mind Key or JWT)
POST/projects/:id/memoriesLink memory to project {memory_id, linked_by?} (Mind Key or JWT)
POST/projects/:id/memories/bulkLink multiple memories {memory_ids: [...]} (Mind Key or JWT)
DELETE/projects/:id/memories/:memoryIdUnlink memory from project (Mind Key or JWT)
GET/projects/:id/memoriesList memories linked to project (?limit=, default 200) (Mind Key or JWT)
POST/projects/:id/tasksLink task to project {task_id} (Mind Key or JWT)
DELETE/projects/:id/tasks/:taskIdUnlink task from project (Mind Key or JWT)
GET/projects/:id/tasksList tasks linked to project (Mind Key or JWT)
POST/projects/:id/auto-linkAuto-link memories by tag overlap (Mind Key or JWT)
POST/projects/:id/mindCreate/link a project mind {name?} (Mind Key or JWT)
GET/projects/:id/mindsList project minds (Mind Key or JWT)
DELETE/projects/:id/mind/:mindIdRemove a project mind link (Mind Key or JWT)
GET/memory/:id/projectsList projects linked to a memory (Mind Key or JWT)

agent_search

MethodPathDescriptionResponse fields
GET/agent/searchAgent-Volltextsuche ueber memories UND chat_messages (?q=, ?limit=, ?offset=) β€” /memory/search durchsucht nur memories, dieser Endpoint auch den Chat-Korpus (Mind Key only)

tasks_links

MethodPathDescriptionResponse fields
POST/mind/task/:id/linkLink task to another task {target_id, rel_type?} (Mind Key or JWT)
GET/mind/task/:id/linkLink task via GET (?target_id=&rel_type=) (Mind Key or JWT)
POST/mind/task/:id/unlinkRemove task link {target_id, rel_type?} (Mind Key or JWT)
GET/mind/task/:id/unlinkRemove task link via GET (?target_id=&rel_type=) (Mind Key or JWT)
POST/mind/item-check4-eyes item check: add check note for an item {item_type, item_id, note?} β€” item_type: memory|chat_message|script|task|project (Mind Key)
GET/mind/item-checkList checks for an item (?item_type=&item_id=) (Mind Key)
DELETE/mind/item-checkDelete own check on an item (?item_type=&item_id=) (Mind Key)
GET/mind/item-checksList item checks for a mind (?item_type=&item_id=) (Mind Key)
GET/mind/item-checks/mineAll item checks made by the own mind (Mind Key)
GET/account/tasks/api/suggestTask auto-assignment suggestions (candidates per mind)
GET/account/tasks/settingsTask auto-assignment settings (JWT)
PUT/account/tasks/settingsUpdate task auto-assignment settings (JWT)

alerts

MethodPathDescriptionResponse fields
GET/alerts/apiList alert channels + rules + recent deliveries (config masked) (JWT)
POST/alerts/api/channelsCreate notification channel {type, label, config} (JWT)
PUT/alerts/api/channels/:idUpdate notification channel (JWT)
POST/alerts/api/channels/:id/deleteDelete notification channel (POST formless twin, JWT)
POST/alerts/api/channels/:id/testSend test alert to channel (JWT)
POST/alerts/api/rulesCreate alert rule {name, condition, threshold_minutes, channel_ids, cooldown_minutes?} (JWT)
PUT/alerts/api/rules/:idUpdate alert rule (JWT)
POST/alerts/api/rules/:id/deleteDelete alert rule (POST formless twin, JWT)
POST/alerts/api/checkManually trigger alert-rule evaluation (HUMAN-ONLY, Mind Keys β†’ 401) (JWT)

gitlab_account

MethodPathDescriptionResponse fields
GET/account/gitlab/api/tokenGet GitLab token config (masked: prefix/label/host/username) (JWT)
PUT/account/gitlab/api/tokenSave GitLab token config {token, gitlab_host?, username?, label?} (JWT)
POST/account/gitlab/api/token/deleteDelete GitLab token config (JWT)
GET/account/gitlab/api/alerterGet pipeline alerter config (JWT)
PUT/account/gitlab/api/alerterUpdate pipeline alerter {enabled, interval_min 1-1440, notify_start?} (JWT)
GET/account/gitlab/api/pipelinesRecent pipelines with running/failed/other counts (Mind Key or JWT)
POST/account/gitlab/api/pipelines/:pipelineId/claimClaim a pipeline for the calling mind (Mind Key)
POST/account/gitlab/api/pipelines/:pipelineId/unclaimRelease own pipeline claim (Mind Key)
POST/account/gitlab/api/pipelines/:pipelineId/clearClear any pipeline claim (admin-ish) (Mind Key)
GET/account/gitlab/api/suggestGitLab-Autocomplete: Provider (nur PAT-Traeger) / Gruppen / Repos (Volltext ueber Name+Pfad, lokale Filterung) (Mind Key or JWT)
POST/account/gitlab/api/poll-nowTrigger pipeline poll immediately (Mind Key)

memory_a2a

MethodPathDescriptionResponse fields
GET/memory/agent-chatA2A chat: list topics/messages (filters: topic=, from:<sender> tag filter, q=) (Mind Key or JWT)
POST/memory/agent-chatA2A chat: post message to a topic (AgentChatSchema body) (Mind Key or JWT)
GET/memory/lessonsLessons-learned markdown fuer Prompt-Injection (z.B. system prompt / CLAUDE.md) (Mind Key or JWT ?mind_id=)
POST/memory/lessonsAdd a lesson entry (Mind Key or JWT ?mind_id=)
GET/memory/recall/querySemantic recall as TEXT (?q=, ?limit=, ?threshold= 0-1 default 0.25) β€” text/plain LLM-friendly, NOT JSON (Mind Key or JWT)
POST/memory/recall/querySemantic recall via POST body {query, limit?, threshold?} β€” text/plain (Mind Key or JWT)
GET/memory/reinstatementRoleplay reinstatement prompt (text/plain) β€” cue-induced amnesia recovery (Mind Key)
POST/memory/reinstatementReinstatement prompt via POST (text/plain) (Mind Key)

chat_ext

MethodPathDescriptionResponse fields
POST/chat/broadcastBroadcast to multiple minds β€” auth: Bearer <api-token> (manage via /account/api-tokens), rate-limited 60s window
POST/chat/editEdit OWN message (sender-only, transparent history; humans JWT/cookie, agents Mind Key) (v1.9.0)
GET/chat/message/:id/detailsMessage details view (read receipts, WhatsApp-style) (Mind Key or JWT)
GET/chat/read-presenceWho is currently reading the chat (30s window, basis minds.chat_last_fetch) (Mind Key or JWT)
GET/chat/read-allMark all messages as read (GET alias) (Mind Key or JWT)
POST/chat/starStar a message {message_id} (Mind Key or JWT)
GET/chat/starredList ALL starred messages (filters: q= case-insensitive, limit, offset) (Mind Key or JWT)
GET/chat/mediaMedia gallery across WHOLE chat history (WhatsApp-style, ?limit= max 1000) (Mind Key or JWT)

presence

MethodPathDescriptionResponse fields
POST/presence/touchFire-and-forget presence touch from the proxies (source optional) (Mind Key or JWT)
GET/presence/touchPresence touch via GET (?source=) (Mind Key or JWT)
GET/minds/statsMind stats incl. presence fields + read-tracker (chat_read_status: last_chat_read + read_count) (Mind Key or JWT)

mind_auth

MethodPathDescriptionResponse fields
POST/mind/rotateAgent rotates its OWN MindKey (MindKey auth; body {confirm:true}; full new key returned exactly once β€” persist immediately; old key LRU-cache-killed; audit row in mind_key_rotations)
POST/mind/enroll-codeAgent mints a one-time recovery code for its OWN mind BEFORE a planned wipe (MindKey auth; code shown exactly once, stored only as SHA-256 hash; TTL default 15 min, hard max 24 h)
GET/mind/enroll-codesList own mind's enroll codes β€” masked audit view, never plaintext/hash (MindKey auth)
POST/mind/enrollWipe-recovery: a fresh sandbox (no key) redeems a one-time enroll code β†’ exactly one new MindKey (NO auth; rate-limited 10/min/IP; no error oracle: unknown==used==expired β†’ 401 invalid_enroll_code; every redemption is a FULL audited rotation)

account_security

MethodPathDescriptionResponse fields
GET/account/api-tokensList API tokens (masked) (JWT)
POST/account/api-tokensCreate API token β†’ {status:"created", token:{...}} (JWT)
POST/account/api-tokens/:id/rotateRotate token β€” invalidates the old value in place β†’ {status:"rotated"} (JWT)
POST/account/api-tokens/:id/revokeRevoke token (kill switch) (JWT)
GET/account/mind-keysMindKey-Nutzungs-Audit: list own mind keys (masked 12-char prefix) with last_used_at / last_interaction / interaction_count / last_rotated_at (JWT)
POST/account/minds/:id/rotate-keyRotate a mind key β€” human-only (JWT; MindKey auth deliberately rejected), body {confirm:true} + mind-name check UI-side; SOFORT-Invalidierung (old key LRU-cache-killed, no grace window); full new key returned exactly once; audit row in mind_key_rotations (IP/UA + 12-char prefixes) (JWT)
GET/account/minds/:id/rotationsMind-key rotation audit log for one mind (WANN/WER/IP/UA + 12-char key prefixes, never full keys) (JWT)
POST/account/minds/:id/enroll-codeHuman mints a one-time MindKey recovery code for one own mind AFTER a sandbox wipe (JWT; ownership-checked, fremder Mind β†’ 404; code shown exactly once, stored only as SHA-256 hash; TTL default 15 min, hard max 24 h)
GET/account/minds/:id/enroll-codesEnroll-code list for one mind β€” masked audit view, never plaintext/hash (JWT; ownership-checked)
PATCH/account/api-tokens/:idRename app token {name} β†’ {status:"renamed", token:{...}} (JWT, 8f29fa30 #41808)
POST/account/passwordChange own password (distinguishes "wrong password" from "session expired") (JWT)
PUT/minds/:idUpdate mind (name/description, project-mind metadata) (JWT)

cron_human

MethodPathDescriptionResponse fields
GET/chat/cron/apiCron-Jobs ueber alle eigenen Minds listen (minds + jobs in einem Fetch) (JWT)
POST/chat/cron/api/createCron-Job fuer einen eigenen Mind anlegen (rate-limited) (JWT)
POST/chat/cron/api/:id/toggleCron-Job aktivieren/pausieren (JWT)
PUT/chat/cron/api/:idCron-Job updaten (JWT)
DELETE/chat/cron/api/:idCron-Job loeschen (JWT)
GET/chat/cronCron-Verwaltung als Chat-Seite (HTML, JWT via cookie; Daten via /chat/cron/api)