MnemonX developer documentation
Overview
The MnemonX API lets AI tools, personal apps, and scripts read and write a user's memory wallet — a structured, encrypted store of personal context: domains of knowledge, professional background, preferences, and more. Wallet data is encrypted with AES-256-GCM on the user's device before it is sent, and the database stores the encrypted data. The user's random encryption key is also kept on our servers, so that the wallet can sync between their devices and so that requests the user or their connected apps make can be answered. This means MnemonX's servers are technically able to decrypt a wallet; they do so only to serve the user's own requests, apps or API keys they connected, and their own export. It is encrypted storage, not zero-knowledge storage.
Base URL
https://mnemonx.ai
Protocol
HTTPS only
Format
JSON (UTF-8)
Encryption notice
Domain values are encrypted with AES-256-GCM using a random per-user key (not derived from a password; accounts sign in by phone). The key is stored on our servers next to the encrypted data. When you read memory through the API, the MCP server or an OAuth token, the server decrypts it for that request and returns plaintext over HTTPS, limited to the scopes the user granted.
The API and the MCP server give your tool access to a person's memory wallet. They are not an AI model: MnemonX does not offer or sublicense a model through the API, and the AI assistants that connect (for example Claude, ChatGPT or Gemini) are run by their own providers under their own terms.
Authentication
All API requests must include an Authorization header. Two credential types are supported:
API Keys (personal access)
Generate API keys from the Wallet → API tab. Keys are prefixed mnx_live_ and grant access to your own wallet only. Available on Pro, Premium, Team, and Enterprise plans.
# Pass the key as a Bearer token
curl https://mnemonx.ai/api/v1/context \
-H "Authorization: Bearer mnx_live_your_key_here"AuthorizationheaderrequiredFormat: "Bearer mnx_live_..." — include on every request.
OAuth Access Tokens (third-party apps)
OAuth tokens are issued after a user authorizes your app (see OAuth section). Tokens look like mxa_xxxxxxxxxxxxxxxxxxxx and are scoped to specific permissions granted by the user.
curl https://mnemonx.ai/api/v1/memory \
-H "Authorization: Bearer mxa_xxxxxxxxxxxxxxxxxxxx"Rate Limits
API access is a Pro, Premium, Team, or Enterprise feature — Free accounts can't generate an API key at all, so there's no rate limit to speak of on Free. For plans that do have access, every rule below is a base limit multiplied by your plan (Pro 1×, Premium 8×, Team 15×, Enterprise unlimited).
Exceeded requests return 429 Too Many Requests with a Retry-After header (seconds).
| Endpoint | Free | Pro (base) | Premium (8×) | Team (15×) | Enterprise |
|---|---|---|---|---|---|
| GET /api/v1/memory, /api/v1/context (reads) | 60/min | 60/min | 480/min | 900/min | Unlimited |
| POST /api/v1/memory (writes) | 10/min | 10/min | 80/min | 150/min | Unlimited |
| POST /api/v1/memory/search | 30/min | 30/min | 240/min | 450/min | Unlimited |
| MCP tool calls (/api/mcp) | 60/min | 60/min | 480/min | 900/min | Unlimited |
| OAuth token exchange (/api/oauth/token) | 10/min | 10/min | 10/min | 10/min | 10/min |
Free accounts get the same base rate as Pro through the built-in "Your AI Tools" connector, but cannot register apps of their own. Limits are counted per account (all keys and apps of one person share them) in a one-minute window, and are the same in every region. A 429 response carries Retry-After (seconds) and X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix time). Skills, goals and focus calls are not rate limited separately.
Memory API
The Memory API gives programmatic read/write access to a user's wallet domains. Requires memory.read or memory.write scope. Available on Pro and above.
Read memory
/api/v1/memoryQuery Parameters
formatstring"json" (default) returns structured array. "text" returns a flat context block for pasting into system prompts.
domainsstringFilter to specific domain IDs, comma-separated. Returns all domains if omitted.
include_metadatabooleanIf true, includes version history counts and last-modified timestamps per domain.
walletIdstringWhich wallet to read from. Only has any effect if this key is scoped to All wallets in Wallet → API Access — a key locked to one specific wallet always uses that one. Omit to use the account's most-recently-updated wallet.
# Return all domains as structured JSON
curl https://mnemonx.ai/api/v1/memory \
-H "Authorization: Bearer mnx_live_your_key"
# Return as plain text (ready for AI system prompt)
curl "https://mnemonx.ai/api/v1/memory?format=text" \
-H "Authorization: Bearer mnx_live_your_key"
# Filter to specific domains
curl "https://mnemonx.ai/api/v1/memory?domains=tech,finance" \
-H "Authorization: Bearer mnx_live_your_key"
# From a key scoped to "All wallets" — pick which one for this call
curl "https://mnemonx.ai/api/v1/memory?walletId=YOUR_WALLET_ID" \
-H "Authorization: Bearer mnx_live_your_key"Response (JSON)
{
"domains": [
{
"id": "tech",
"name": "Technology",
"value": "Senior software engineer...",
"context": "Expert in TypeScript, React, Next.js...",
"order": 0
}
],
"wallet_name": "My Wallet",
"total_domains": 12,
"generated_at": "2026-06-13T12:00:00Z"
}Write memory
/api/v1/memoryUpdate one or more domain values. Every write creates a version history entry (full audit trail). Requires memory.write scope.
Request Body
domainsarrayrequiredArray of domain update objects. Each must have id and at least one of: value, name, context.
sourcestringOptional label for the version history entry (e.g. "chatgpt-plugin", "my-app"). Default: "api".
curl -X POST https://mnemonx.ai/api/v1/memory \
-H "Authorization: Bearer mxa_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"domains": [
{
"id": "tech",
"value": "Principal engineer with 10 years TypeScript experience",
"context": "Currently building MnemonX — AI memory infrastructure"
}
],
"source": "my-ai-tool"
}'Response
{
"success": true,
"updated": 1,
"version_id": "vhst_xxxxxxxxxxxxxxxx",
"timestamp": "2026-06-13T12:00:00Z"
}Context API
The Context API returns a pre-formatted context block ready to insert into any AI system prompt. Requires read:context scope. Available on Pro and above.
Get context
/api/v1/contextdomainsstringComma-separated domain IDs to include. Returns all if omitted.
formatstring"json" (default) or "text". Text returns a plain neural context block.
walletIdstringWhich wallet to read from. Only has any effect if this key is scoped to All wallets in Wallet → API Access — a key locked to one specific wallet always uses that one. Omit to use the account's most-recently-updated wallet.
# JSON (structured)
curl https://mnemonx.ai/api/v1/context \
-H "Authorization: Bearer mnx_live_your_api_key"
# Plain text — paste directly into a system prompt
curl "https://mnemonx.ai/api/v1/context?format=text" \
-H "Authorization: Bearer mnx_live_your_api_key"
# From a key scoped to "All wallets" — pick which one for this call
curl "https://mnemonx.ai/api/v1/context?walletId=YOUR_WALLET_ID" \
-H "Authorization: Bearer mnx_live_your_api_key"Example text output
[CONTEXT: MnemonX User Profile]
Name: Alex Chen
Technology: Principal engineer, 10y TypeScript, React, Node.js
Finance: Long-term investor, ETF focused, risk-averse
Languages: English (native), Mandarin (conversational)
[END CONTEXT]Skills, Goals & Focus
Three small endpoints for apps that only need to know what a person is good at, what they are working toward, or what they are focused on right now. Each works with its own narrow scope, so an app can be granted just that and nothing else from the wallet. They read the wallet the account updated most recently.
Skills
/api/v1/skillsNeeds skills.read or memory.read. Returns every field tagged skill in an active domain, across all domains.
curl https://mnemonx.ai/api/v1/skills \
-H "Authorization: Bearer mnx_live_your_api_key"
{ "skills": [ { "domain": "coding", "domainName": "Coding", "emoji": "💻",
"fieldId": "f_12", "label": "Languages", "value": "TypeScript, Go" } ],
"count": 1 }Goals
/api/v1/goalsNeeds goals.read or memory.read. Same shape as skills, for fields tagged goal: { goals: [...], count }.
Focus
/api/v1/focusFocus is a spotlight on 1 or 2 domains the person already has, plus an optional short task note. An AI tool reads it to decide what to look at first. GET needs focus.read or memory.read. PATCH needs focus.write or memory.write and changes only the fields you send.
activeDomainIdsstring[]Up to 2 real, active domain ids of this account. Anything else is rejected with 400.
currentTaskstringShort note, max 300 characters. Checked by the same safety filter as memory writes.
curl https://mnemonx.ai/api/v1/focus \
-H "Authorization: Bearer mnx_live_your_api_key"
# { "focus": { "activeDomainIds": ["coding"], "currentTask": "Fix the login bug" },
# "activeDomains": [ { "id": "coding", "name": "Coding", "emoji": "💻" } ] }
curl -X PATCH https://mnemonx.ai/api/v1/focus \
-H "Authorization: Bearer mnx_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "activeDomainIds": ["coding"], "currentTask": "Fix the login bug" }'MCP Server
MnemonX is also a remote MCP (Model Context Protocol) server, so AI tools such as Claude, Cursor and other MCP clients can read and write a person's wallet directly, without custom code. It uses the same keys, OAuth tokens, scopes, wallet selection, plan gate and audit log as the REST API. The MCP server exposes wallet memory only: it does not give access to chats, Plans, the Code or Design boards, Twin pages or files.
Connect a client
URLhttps://mnemonx.ai/api/mcp
TransportStreamable HTTP, stateless: every call is one POST with a JSON-RPC body. GET returns 405 (no server-initiated stream). Protocol version 2024-11-05.
AuthenticationAuthorization: Bearer mnx_live_… (API key) or an OAuth access token (mxa_…). Without a valid token a tool call gets 401 with a WWW-Authenticate header that points to the OAuth metadata, so OAuth-aware clients can sign in themselves.
PlanAPI keys and apps can be created on Pro, Premium, Team and Enterprise plans, the same as for the REST API.
{
"mcpServers": {
"mnemonx": {
"url": "https://mnemonx.ai/api/mcp",
"headers": { "Authorization": "Bearer mnx_live_your_api_key" }
}
}
}Clients that only run local commands can use npx mcp-remote https://mnemonx.ai/api/mcp --header "Authorization: Bearer mnx_live_…".
Tools
| Tool | What it does | Scope |
|---|---|---|
| search_memory | Read fields, optionally filtered by domain or tag. | memory.read |
| get_full_context | Everything in the wallet as one block, optionally filtered by domains and tags. | memory.read |
| write_memory | Add or update one field (domain + fieldId or label, value, optional tag). Same safety filter and version history as POST /api/v1/memory. | memory.write |
| search_skills | All skill-tagged fields, across domains. | memory.read or skills.read |
| search_goals | All goal-tagged fields, across domains. | memory.read or goals.read |
| get_focus | The current focus domains and task note. | memory.read or focus.read |
| set_focus | Change the focus (max 2 domains) and task note. | memory.write or focus.write |
Most read tools take an optional walletId. It only has an effect when the key or connection is scoped to All wallets; a connection locked to one wallet always uses that wallet. Without it, the most recently updated wallet is used. Tool errors come back as a normal result with isError: true. Rate limits are in the table above (MCP tool calls); every call is written to the audit log.
OAuth Flow
MnemonX implements OAuth 2.0 Authorization Code flow. Register your app, redirect users to authorize, exchange the code for tokens, and call the API on their behalf. Users can revoke access at any time from Wallet → Apps.
1 · Register your app
App registration is currently invite-only. Email [email protected] with your app name, website, and intended scopes to receive your credentials.
client_idstringPublic identifier for your app. Safe to include in client-side code.
client_secretstringSecret for server-to-server token exchange only. Never expose in browser or mobile code.
redirect_uristringCallback URL registered for your app. Must match exactly on every request (no trailing slashes, no params).
3 · Exchange code for tokens
After the user approves, MnemonX redirects to your redirect_uri with a short-lived code. Exchange it server-side within 10 minutes:
curl -X POST https://mnemonx.ai/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "AUTH_CODE_FROM_CALLBACK",
"redirect_uri": "https://yourapp.com/callback",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'Response
{
"access_token": "mxa_xxxxxxxxxxxxxxxxxxxx",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "mxr_xxxxxxxxxxxxxxxxxxxx",
"scope": "memory.read memory.write"
}4 · Refresh access tokens
Access tokens expire after 1 hour. Use the refresh token (valid 90 days, and replaced each time you use it) to get a new pair:
curl -X POST https://mnemonx.ai/api/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "mxr_xxxxxxxxxxxxxxxxxxxx",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'5 · Revoke access
Users can revoke from the app UI. Your app can also revoke programmatically (e.g. on logout):
curl -X DELETE https://mnemonx.ai/api/oauth/revoke \
-H "Authorization: Bearer mxa_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "token": "mxa_xxxxxxxxxxxxxxxxxxxx" }'After revocation, all subsequent API calls with this token return 401 Unauthorized. Access and refresh tokens are both invalidated atomically.
Scopes Reference
Scopes are requested during the OAuth flow. Users must explicitly grant each scope. Narrower scopes (domain-filtered) improve user trust and are recommended.
| Scope | Access | Notes |
|---|---|---|
| memory.read | Read all domains | Returns domain names, values, and context. |
| memory.write | Write all domains | Create or update domain values. Always creates a version history entry. |
| memory.search | Search within domains | Full-text search across domain values. |
| memory.read:<id> | Read one domain | e.g. memory.read:tech — user can scope access to a single domain. |
| memory.write:<id> | Write one domain | e.g. memory.write:finance — write-access limited to one domain. |
| read:context | Read pre-formatted context | Returns the full formatted context block. Pro and above. |
| profile.read | Read profile metadata | User name, tier, wallet count. No domain values. |
| skills.read | Read skill-tagged fields | Skills from every domain, cross-domain. Works on its own, without memory.read. |
| goals.read | Read goal-tagged fields | Goals from every domain, cross-domain. Works on its own, without memory.read. |
| focus.read | Read current focus | Which 1-2 domains the user is focused on, plus a short task note. |
| focus.write | Set current focus | Change the focus domains and task note. Works on its own, without memory.write. |
Principle of least privilege: Request only the scopes you need. Users are more likely to approve narrowly-scoped requests. Audit logs capture every scope grant and use.
Error Codes
All errors return a JSON body with error (machine-readable code) and message (human-readable description).
{
"error": "invalid_token",
"message": "The access token has expired. Refresh using your refresh token."
}| HTTP | Error code | Description |
|---|---|---|
| 400 | invalid_request | Missing required parameter or malformed JSON body. |
| 401 | unauthorized | No Authorization header provided. |
| 401 | invalid_token | Token is malformed, expired, or revoked. |
| 403 | insufficient_scope | Token lacks required scope for this operation. |
| 403 | plan_required | This endpoint requires a higher plan (Pro or Premium). |
| 404 | not_found | Requested resource or domain does not exist. |
| 409 | conflict | Conflicting write — another update was made concurrently. Retry. |
| 422 | domain_too_large | Domain value exceeds per-domain size limit for your plan. |
| 429 | rate_limited | Rate limit exceeded. See Retry-After header. |
| 500 | internal_error | Unexpected server error. Retry after a short delay. |
| 503 | service_unavailable | Planned maintenance or overload. See mnemonx.ai/status. |
SDKs & Examples
Official TypeScript and Python SDKs are available — thin, dependency-free wrappers over the same REST API documented on this page. Prefer working directly against HTTP instead? Plain-request examples for both languages are further down this section.
Official SDK — TypeScript
Zero dependencies — just native fetch.
import { MnemonXClient } from '@mnemonx/sdk'
const client = new MnemonXClient({ apiKey: process.env.MNEMONX_API_KEY! })
const results = await client.memory.search({ domain: 'coding', tag: 'skill' })
const context = await client.context.get()
const promptText = await client.context.getText()
// Updates an EXISTING field — matched by fieldId or exact label. Can't
// create a brand-new field.
await client.memory.write({ domain: 'writing', label: 'Tone of voice', value: 'direct and warm' })Official SDK — Python
Zero dependencies — just the standard library (urllib, json).
from mnemonx import MnemonXClient
client = MnemonXClient(api_key="mnx_live_...")
results = client.memory.search(domain="coding", tag="skill")
context = client.context.get()
prompt_text = client.context.get_text()
# Updates an EXISTING field — matched by field_id or exact label. Can't
# create a brand-new field.
client.memory.write(domain="writing", label="Tone of voice", value="direct and warm")Plain HTTP (no SDK) — JavaScript / TypeScript
// Fetch user context and inject into a system prompt
const res = await fetch('https://mnemonx.ai/api/v1/context?format=text', {
headers: { Authorization: `Bearer ${process.env.MNEMONX_API_KEY}` },
})
const context = await res.text()
const completion = await openai.chat.completions.create({
model: 'gpt-5.6-sol',
messages: [
{ role: 'system', content: `You are a helpful assistant.\n\n${context}` },
{ role: 'user', content: userMessage },
],
})Plain HTTP (no SDK) — Python
import os, requests
MNEMONX_KEY = os.environ["MNEMONX_API_KEY"]
BASE = "https://mnemonx.ai"
def get_context(format="text"):
r = requests.get(
f"{BASE}/api/v1/context",
params={"format": format},
headers={"Authorization": f"Bearer {MNEMONX_KEY}"},
)
r.raise_for_status()
return r.text if format == "text" else r.json()
def update_domain(domain_id: str, value: str, source="my-app"):
r = requests.post(
f"{BASE}/api/v1/memory",
json={"domains": [{"id": domain_id, "value": value}], "source": source},
headers={"Authorization": f"Bearer {MNEMONX_KEY}"},
)
r.raise_for_status()
return r.json()Shell / cURL quick reference
BASE="https://mnemonx.ai"
KEY="mnx_live_your_key_here"
# Read all domains (JSON)
curl "$BASE/api/v1/memory" -H "Authorization: Bearer $KEY"
# Read as plain text (for system prompt)
curl "$BASE/api/v1/context?format=text" -H "Authorization: Bearer $KEY"
# Write a domain
curl -X POST "$BASE/api/v1/memory" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"domains":[{"id":"tech","value":"Expert in TypeScript and React"}]}'
# Revoke an OAuth token
curl -X DELETE "$BASE/api/oauth/revoke" \
-H "Authorization: Bearer mxa_xxxx" \
-d '{"token":"mxa_xxxx"}'Webhooks
MnemonX can push real-time notifications to your server whenever a user's wallet changes. Register a webhook endpoint to receive events without polling.
Register a webhook
Webhook endpoints are registered per OAuth client, authenticated with the OAuth access token issued to your app after a user completes the authorize flow — not your personal mnx_live_ API key, which is scoped to your own wallet only, not to an OAuth client.
POST https://mnemonx.ai/api/webhooks
Authorization: Bearer <oauth_access_token>
Content-Type: application/json
{
"url": "https://your-app.com/webhooks/mnemonx",
"events": ["memory.update", "user.revoke"]
}urlstringrequiredHTTPS endpoint that will receive POST requests (HTTP allowed only in local dev).
eventsstring[]requiredEvent types to subscribe to — only "memory.update" and "user.revoke" are currently supported.
The signing secret is generated by the server and returned once in the response — you don\'t choose or send your own:
{
"webhook": { "id": "wh_xxxx", "url": "https://your-app.com/webhooks/mnemonx", "events": ["memory.update", "user.revoke"], "is_active": true, "created_at": "2026-06-22T14:30:00Z" },
"secret": "whsec_...",
"note": "Save the secret now — it will not be shown again."
}Max 5 active endpoints per app.
Event types
| Event | When fired |
|---|---|
| memory.update | Your app wrote to the user's wallet (via the memory API) |
| user.revoke | User disconnected/revoked your app's access |
Payload format
{
"event": "memory.update",
"timestamp": "2026-06-22T14:30:00Z",
"data": {
"user_id": "usr_xxxx",
"domain_id": "coding",
"source": "api"
}
}Verifying signatures
Every delivery includes an X-MnemonX-Event header (the event type) and an X-MnemonX-Sig-256 header. Verify the signature to confirm the request is genuine:
// Node.js / TypeScript
import { createHmac } from 'crypto'
function verifyWebhook(
payload: string, // raw request body as string
signature: string, // X-MnemonX-Sig-256 header value
secret: string
): boolean {
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex')
return `sha256=${expected}` === signature
}
// Express example
app.post('/webhooks/mnemonx', express.raw({ type: '*/*' }), (req, res) => {
const sig = req.headers['x-mnemonx-sig-256'] as string
if (!verifyWebhook(req.body.toString(), sig, process.env.WEBHOOK_SECRET!)) {
return res.status(401).send('Invalid signature')
}
const event = JSON.parse(req.body)
// handle event...
res.sendStatus(200)
})Delivery guarantees
Each event is delivered with a single POST attempt — there is no automatic retry yet if your endpoint is down or returns a non-2xx status. Build your handler to be idempotent and keep it fast and reliable; a retry/redelivery mechanism is on our roadmap but not live today.
Data Residency
MnemonX routes every API request to the user's assigned regional database. Encrypted wallet data never crosses regional boundaries. Your API responses include a X-MNX-Region header on every response.
| Region | X-MNX-Region | DB Location | Status |
|---|---|---|---|
| 🇺🇸 United States | us | Supabase us-east-1 (Virginia) | Live |
| 🇪🇺 European Union | eu | Supabase eu-central-1 (Frankfurt) | Live · GDPR |
| 🇦🇺 Australia & Pacific | apac | — (coming soon) | Pipeline |
| 🇸🇬 Southeast Asia | sea | — (coming soon) | Pipeline |
| 🇧🇷 South America | latam | — (coming soon) | Pipeline |
X-MNX-Region response header
Every authenticated API response includes the X-MNX-Region header. Use this to verify the data was served from the expected region, and to enforce your own compliance policies.
HTTP/2 200 OK
Content-Type: application/json
X-MNX-Region: eu
X-MNX-Request-Id: req_01HZ9KXMR7V8A2T
{
"domain": "work",
"fields": { ... }
}If you are building a GDPR-compliant integration, you should verify that EU users always receive X-MNX-Region: eu. Contact [email protected] if a user reports receiving an unexpected region.
API base URL
The MnemonX API uses a single base URL. Regional routing is transparent — the edge function reads the user's mnx_region from their account and connects to the correct Supabase project automatically.
# Single base URL — routing is automatic
BASE_URL=https://mnemonx.ai
# All API calls use the same base regardless of region
curl $BASE_URL/api/v1/memory -H "Authorization: Bearer $ACCESS_TOKEN"
# Response: X-MNX-Region: eu (for EU users)
# Response: X-MNX-Region: us (for US users)Compliance & Privacy
MnemonX is built privacy-first. This section summarises what that means for your integration.
GDPR — API as data processor
Roles
When your application reads or writes to a user's wallet via the API, your app is the data controller for how you use that data. MnemonX is the data processor (GDPR Art. 28). Our DPA governs this relationship.
What we guarantee
- →EU user data stays in eu-central-1 — never transferred to US infrastructure.
- →All wallet data is AES-256-GCM encrypted at rest and decrypted only to serve your authorized request — MnemonX does not read or retain the content you retrieve.
- →Access logged for 90 days — users can request their full API access log via GDPR export.
- →Token revocation is instantaneous — when a user disconnects your app, your token is invalidated server-side immediately.
- →No advertising or profiling from API data — we have no business model that involves monetising wallet content.
Your obligations as controller
- →Request only the scopes you actually use — principle of data minimisation (GDPR Art. 5(1)(c)).
- →Delete wallet data you have stored when a user exercises their right to erasure.
- →Include MnemonX as a data source in your Privacy Policy.
- →Do not store decrypted wallet content longer than necessary for the stated purpose.
CCPA — Service Provider terms
MnemonX qualifies as a Service Provider under CCPA §1798.140(ag). We: (a) process personal information only for specified business purposes; (b) do not sell or share personal information retrieved from the API; (c) do not retain, use, or disclose wallet data outside the service relationship. California-based developers should disclose MnemonX as a Service Provider in their privacy disclosures.
Scope minimisation best practice
Request the minimum scopes required for your use case. The table below shows scope granularity:
| Your use case | Recommended scope | Avoid |
|---|---|---|
| Read work context only | memory.read:work | memory.read (all domains) |
| Personalise AI responses | memory.read:personal + memory.read:work | memory.read |
| Write AI memories | memory.write:[domain] | memory.write (all domains) |
| Search wallet | memory.search | — |
| Full integration | memory.read + memory.write | Use only when truly needed |
Changelog
October 2026
v1.5- Job Hunter (Pro and above) was added to the app. It has no public API endpoints and is not available through API keys, OAuth or MCP.
- Rate limits are now enforced exactly as listed: Premium 8x, Team 15x, Enterprise unlimited, counted per account and shared across all servers. A 429 response carries Retry-After and X-RateLimit headers.
- MCP server documented (https://mnemonx.ai/api/mcp): seven tools for memory, skills, goals and focus, using the same keys, OAuth tokens and scopes.
- Skills, goals and focus endpoints documented, with the narrow scopes skills.read, goals.read, focus.read and focus.write.
- Wallet selection (walletId) documented for keys and connections scoped to All wallets.
July 2026
v1.4- SECURITY: /api/oauth/token now actually verifies client_secret on every exchange (previously accepted but not checked — always send it, per the docs above, and this now matters).
- grant_type=refresh_token is now fully functional with refresh-token rotation (previously documented but not implemented — tokens issued before this date could not be refreshed and required a fresh consent flow).
- SCIM 2.0 provisioning for Enterprise orgs (not a public developer API — see your org Security tab).
June 2026
v1.3- Added POST /api/v1/memory — programmatic domain writes with version history
- OAuth revoke endpoint (DELETE /api/oauth/revoke) — revokes both access and refresh tokens
- OAuth token refresh flow (grant_type: refresh_token)
- Granular domain-level scopes: memory.read:<id>, memory.write:<id>
- Push notification triggers on OAuth grant and revocation
- GDPR data export: GET /api/v1/user/export
- Audit log for all API access (api_access_logs table)
April 2026
v1.2- OAuth 2.0 Authorization Code flow (authorize, token)
- Consent audit log — SMS, email, and push opt-in/opt-out timestamps
- Rate limiting on all endpoints
- Prompt injection safeguards (8-pattern sanitizer)
February 2026
v1.1- GET /api/v1/context — plain-text system prompt injection
- API key management in wallet UI
- Version history on all domain writes
- AES-256-GCM client-side encryption
December 2025
v1.0- Initial API release
- GET /api/v1/memory — read domain wallet
- Bearer token authentication (API keys)
- Basic rate limiting
Coming soon
- OAuth app self-registration portal (currently invite-only)
- Direct integration with ChatGPT memory (pending OpenAI API availability)