Base URL
Authentication
All/v1/* endpoints require a Bearer token:
Memory — Core
POST /v1/add
Add memories from a conversation. Automatically extracts entities, facts, episodes, and procedures in the background.
Response:
{"status": "accepted", "job_id": "job-..."}
POST /v1/add_text
Add memories from plain text instead of chat messages./v1/add (including source and metadata).
POST /v1/add_file
Upload a file (PDF, DOCX, TXT, MD) and extract structured memories. PDFs use two-pass vision AI extraction. Each page/chunk counts as 1 add from your quota. Content-Type:multipart/form-data (not JSON)
File size limits: Free 10MB, Pro 50MB, Business 100MB.
Response (202):
GET /v1/memories
List all entities for a user. Supports pagination.GET /v1/memories/full
Get all memories with full facts, relations, and knowledge in a single request.GET /v1/memory/:name
Get details for a specific entity including facts, relations, knowledge, and metadata. Response includes ametadata object with provenance information (source, agent_id, etc.).
DELETE /v1/memory/:name
Delete a specific entity and all its data.DELETE /v1/account
Permanently delete your account and all associated data — entities, facts, relations, knowledge, embeddings, episodes, procedures, conversation chunks, webhooks, teams you created, API keys, and usage history. Irreversible, immediate, and synchronous. Returns per-table deletion counts so you can verify completion.
An active paid subscription is canceled in the billing provider first; if that cancellation fails, deletion aborts (502) so you’re never billed for an account whose data is gone. Works identically on self-hosted deployments.
DELETE /v1/memories/all
Delete ALL memories for a user. Irreversible.Search
POST /v1/search
Semantic search across the knowledge graph with LLM re-ranking.
A recall that fits. With
max_tokens, the response carries what was cut, so the cut is never silent:
facts_meta, one entry per fact, aligned with facts:
source is what the writer declared on /v1/add (source and metadata); the CLI hooks send claude-code, codex or cursor with the session, working directory and OS, the MCP server sends mcp, everything else is api. recalled and last_recalled count retrievals, so a fact nobody has asked for in months is visible as such. Facts are never rewritten; the tag the hooks show ((codex, 2026-09-15)) is built from this at read time.
A host does not inherit another host’s paths. Send X-Mengram-Host: <os>/<tool> (for example linux/claude-code; the hooks do) and facts tied to another machine or tool are left out: a /Users/... path recorded on a Mac, a ~/.cursor/hooks.json fact recorded from Cursor. Each result then says how many were withheld in facts_left_out_for_host. Without the header nothing is filtered, and facts saved without provenance are never filtered. From Python: CloudMemory(api_key, host="linux/claude-code").
POST /v1/search/all
Unified search across all 3 memory types.max_tokens works here too: one budget across the sections, spent in the order a task needs them — facts about the entities, then what happened, then how it was done, then raw conversation last. The budget report also counts episodes, procedures and chunks.
chunks (default 1, 0 to 10) is how many raw conversation chunks may come back as the fallback for facts extraction missed. One is the default because on a 90-day history five of them were three quarters of the tokens handed to the model while one kept recall of old facts unchanged; 0 turns the fallback off.
Response:
POST /v1/ask
Ask your memory a question and get a synthesized answer with citations — not a raw fact list. Mengram embeds the query, retrieves the top relevant facts, and uses Cohere Chat (command-a-03-2025) to write a grounded answer with native source attribution.
Counts as 1 search against your monthly quota.
Response:
When
answer is empty / citations is empty: Cohere chose not to answer from the retrieved facts (e.g. no relevant data, or query was ambiguous). This is not an error — it’s an honest “I don’t know” rather than a hallucinated response.
Multilingual: Works natively across all 23 supported languages. Russian/Chinese/Japanese/Spanish queries return answers in the query language with citations to the original (often English) facts.
GET /v1/timeline
Temporal search — find facts within a time range.Cognitive Profile
GET /v1/profile
Generate a Cognitive Profile — a ready-to-use system prompt summarizing a user from memory.GET /v1/profile/:user_id
Generate a profile for a specific sub-user.Rules Generation
GET /v1/rules
Generate a CLAUDE.md, .cursorrules, or .windsurfrules file from memory.
Response:
{"format": "claude_md", "content": "# Project Rules\n..."}
Episodic Memory
GET /v1/episodes
List recent episodes. Each episode has a summary, context, outcome, and participants. Paginated — the response includestotal, limit, and offset so you can page through everything.
GET /v1/episodes/search
Semantic search over episodic memories.Procedural Memory
GET /v1/procedures
List learned workflows and procedures. Paginated — the response includestotal, limit, and offset.
GET /v1/procedures/search
Semantic search over procedural memories.PATCH /v1/procedures/:id/feedback
Record success or failure for a procedure. On failure with context, triggers experience-driven evolution (Pro and above). This is not the only way a procedure evolves. Mengram also infers failures from episodes as they are added and revises the matching procedure on its own, which in practice is the more common path. A revision only earns a new version number once the current one has succeeded at least once — a version nobody ran is a hypothesis, so it is edited in place rather than superseded.
Failure-driven revisions record the violated assumption (the specific belief that turned out false — not just the step number) in the evolution history, and derive a precondition check that accumulates in the procedure’s
metadata.preconditions — so recall returns not just the steps but what to verify before trusting them.
GET /v1/procedures/:id/history
Get version history for a procedure — how it evolved over time.GET /v1/procedures/:id/evolution
Get the evolution log — what changed at each version and why.Entity Management
DELETE /v1/entity/:name
Delete an entity and all its facts, relations, knowledge, and embeddings.PATCH /v1/entity/:name/type
Fix an entity’s type classification.person, project, technology, company, concept, unknown.
POST /v1/entity/:name/dedup
LLM-powered deduplication of facts on a single entity.Memory Management
POST /v1/dedup
Find and merge duplicate entities using word-boundary matching.POST /v1/dedup_all
Deduplicate facts across ALL entities for the user.POST /v1/merge
Merge source entity into target. Source gets deleted, all data moves to target.POST /v1/merge_user
Merge the generic “User” entity into the primary person entity.POST /v1/identity
Pin which entity is you. Extraction context, “User” merging, and profile generation anchor to the pinned entity instead of guessing by heuristics — fixes identity drift when third parties (collaborators, tool authors) are frequently co-mentioned in your conversations.
Returns
{"status": "pinned", "entity": "...", "entity_id": "..."}. Pinning clears the flag from any previously pinned entity. 404 if the entity doesn’t exist.
POST /v1/archive_fact
Archive a specific fact (soft-delete).Insights & Reflections
POST /v1/reflect
Manually trigger memory reflection. Generates AI insights from facts.GET /v1/reflections
Get all reflections. Optionalscope filter: entity, cross, temporal. Each item includes its id for individual deletion.
DELETE /v1/reflections/:id
Delete a single reflection by id. Use when a generated reflection is wrong or polluted — the next reflection pass regenerates from clean facts.{"status": "deleted", "reflection_id": "..."}, or 404 if the id doesn’t exist for this user.
GET /v1/insights
Get formatted AI insights for dashboard display.Agents
POST /v1/agents/run
Run memory agents in the background. Returns a job_id.GET /v1/agents/history
Get agent run history. Optionalagent filter and limit parameter.
GET /v1/agents/status
Check which agents are due to run.Smart Triggers
GET /v1/triggers
Get smart triggers for the authenticated user — reminders, contradictions, patterns.GET /v1/triggers/:user_id
Get triggers for a specific sub-user.POST /v1/triggers/process
Process all pending triggers — sends webhooks for triggered items.DELETE /v1/triggers/:trigger_id
Dismiss a specific trigger without firing its webhook.POST /v1/triggers/detect/:user_id
Manually run trigger detection for a user. Returns detailed results.Knowledge Graph
GET /v1/graph
Get the knowledge graph for visualization. Returns nodes and edges.GET /v1/feed
Activity feed — recent facts with timestamps.Webhooks
POST /v1/webhooks
Create a webhook.GET /v1/webhooks
List all webhooks.PUT /v1/webhooks/:id
Update a webhook (url, name, event_types, active).DELETE /v1/webhooks/:id
Delete a webhook.Teams
POST /v1/teams
Create a team. Returns team info with invite code.GET /v1/teams
List your teams.POST /v1/teams/join
Join a team via invite code.GET /v1/teams/:team_id/members
Get team members.POST /v1/teams/:team_id/share
Share a memory entity with a team.POST /v1/teams/:team_id/unshare
Make a shared memory personal again.POST /v1/teams/:team_id/leave
Leave a team.DELETE /v1/teams/:team_id
Delete a team (owner only).API Keys
GET /v1/keys
List all API keys for your account.POST /v1/keys
Create a new API key.DELETE /v1/keys/:key_id
Revoke a specific API key.PATCH /v1/keys/:key_id
Rename an API key.Jobs
GET /v1/jobs/:id
Check status of a background job. Response:{"status": "completed|processing|failed", ...}
Billing
GET /v1/billing
Get current subscription plan, usage, and quotas.POST /v1/billing/checkout
Create a Paddle checkout session for plan upgrade.POST /v1/billing/portal
Create a Paddle customer portal session for managing subscription.Statistics
GET /v1/stats
Get usage statistics for the authenticated user.facts counts active facts only (matching what export and list endpoints return); facts archived by conflict resolution/dedup are reported separately as archived_facts.
GET /v1/me
Get current account info (email, plan, user_id).Voice (Vapi)
Webhook adapters that turn Vapi’s tool-call and end-of-call events into Mengram memory operations. See the full guide at Vapi Integration.POST /v1/voice/vapi/recall
Called by Vapi as a custom tool. Returns a concise context string the assistant verbalizes at the start of a call. Request body (Vapi sends both shapes; either accepted):toolCalls with function.name + function.arguments — the latter may arrive as a JSON string):
message.call.customer.number → “Unknown caller” fallback.
Response (200 — Vapi tool-result format, result MUST be a string):
message.type is anything other than tool-calls (Vapi sends many event types to the same server URL), the endpoint returns 200 {"status":"ignored","reason":"..."} rather than 4xx — so the assistant isn’t marked broken when lifecycle events arrive.
Quota: 1 search per call.
POST /v1/voice/vapi/save
Called by Vapi at end of call. Routes the final transcript through Mengram’s extraction pipeline, keyed per caller viasub_user_id=voice:<E.164>.
Request body:
message.artifact.transcript — Mengram reads whichever is present.
Response (202 — extraction runs in the background like /v1/add):
end-of-call-report triggers extraction. Partial transcript events (Vapi streams these mid-call) and other lifecycle events are ignored with {"status":"ignored"} so the extraction pipeline doesn’t fire repeatedly per call.
Quota: 1 add per call.
Error Responses
All endpoints return structured JSON errors.401 Unauthorized
Invalid or missing API key.402 Quota Exceeded
Monthly plan limit reached. Includes upgrade URL and retry timing.Retry-After header (seconds until monthly reset).
429 Rate Limited
Too many requests. Retry after theRetry-After header value.
Response Headers
Every authenticated response includes rate limit and quota usage headers.Rate Limiting
Quota Usage
SDKs expose quota headers via the
.quota property — see Python SDK and JavaScript SDK.