Documentation Index
Fetch the complete documentation index at: https://docs.mengram.io/llms.txt
Use this file to discover all available pages before exploring further.
Base URL
Authentication
All /v1/* endpoints require a Bearer token:
Authorization: Bearer om-your-api-key
Get your API key at mengram.io.
Memory — Core
POST /v1/add
Add memories from a conversation. Automatically extracts entities, facts, episodes, and procedures in the background.
curl -X POST https://mengram.io/v1/add \
-H "Authorization: Bearer om-..." \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "I use Python and Railway"},
{"role": "assistant", "content": "Noted."}
],
"user_id": "default"
}'
| Parameter | Type | Default | Description |
|---|
messages | array | required | Chat messages with role and content |
user_id | string | "default" | User identifier for multi-user isolation |
agent_id | string | null | Agent identifier |
run_id | string | null | Session/run identifier |
app_id | string | null | Application identifier |
expiration_date | string | null | ISO datetime — facts auto-expire after this |
source | string | null | Provenance source (e.g. "discord", "slack", "email", "api") |
metadata | object | null | Arbitrary provenance metadata (stored on entities and facts) |
agent_mode | boolean | false | Extract from all speakers (user + assistant). Auto-enabled when agent_id is set. |
Response: {"status": "accepted", "job_id": "job-..."}
POST /v1/add_text
Add memories from plain text instead of chat messages.
{"text": "Meeting notes: migrating to PostgreSQL 16", "user_id": "default", "source": "slack", "metadata": {"channel": "#engineering"}}
Same optional parameters as /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)
curl -X POST https://mengram.io/v1/add_file \
-H "Authorization: Bearer om-..." \
-F "file=@meeting-notes.pdf" \
-F "user_id=default"
| Parameter | Type | Default | Description |
|---|
file | file | required | File to upload (.pdf, .docx, .txt, .md) |
user_id | string | "default" | User identifier |
agent_id | string | null | Agent identifier |
run_id | string | null | Session/run identifier |
app_id | string | null | Application identifier |
File size limits: Free 10MB, Pro 50MB, Business 100MB.
Response (202):
{
"status": "accepted",
"job_id": "job-...",
"file_type": "pdf",
"page_count": 12,
"quota_used": 12,
"message": "Processing meeting-notes.pdf (12 pages/chunks) in background."
}
GET /v1/memories
List all entities for a user. Supports pagination.
| Parameter | Type | Default | Description |
|---|
user_id | string | "default" | User whose memories to list |
limit | int | 100 | Max results |
offset | int | 0 | Pagination offset |
GET /v1/memories/full
Get all memories with full facts, relations, and knowledge in a single request.
| Parameter | Type | Default | Description |
|---|
user_id | string | "default" | User whose memories to list |
limit | int | 100 | Max results |
offset | int | 0 | Pagination offset |
GET /v1/memory/:name
Get details for a specific entity including facts, relations, knowledge, and metadata.
Response includes a metadata object with provenance information (source, agent_id, etc.).
DELETE /v1/memory/:name
Delete a specific entity and all its data.
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.
{"query": "database preferences", "user_id": "default", "limit": 5, "graph_depth": 2}
| Parameter | Type | Default | Description |
|---|
query | string | required | Natural language search query |
user_id | string | "default" | User whose memories to search |
limit | int | 5 | Max results |
graph_depth | int | 2 | Knowledge graph traversal depth (0-4) |
agent_id | string | null | Filter by agent |
run_id | string | null | Filter by run |
app_id | string | null | Filter by app |
filters | object | null | Metadata key-value filters (JSONB containment) |
POST /v1/search/all
Unified search across all 3 memory types.
{"query": "deployment", "user_id": "default", "limit": 5}
Response:
{
"semantic": [...],
"episodic": [...],
"procedural": [...]
}
POST /v1/ask
Pro / Growth / Business only. Free and Starter plans return 403.
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.
curl -X POST https://mengram.io/v1/ask \
-H "Authorization: Bearer om-..." \
-H "Content-Type: application/json" \
-d '{"query": "what programming languages do I use?", "user_id": "default"}'
| Parameter | Type | Default | Description |
|---|
query | string | required | Natural language question |
user_id | string | "default" | User whose memories to use |
max_facts | int | 15 | How many top facts to feed Cohere as documents (capped at 30 internally) |
Response:
{
"answer": "You use Python and Rust. Python is your daily language and Rust is your favorite. You also use Java for enterprise systems.",
"citations": [
{
"text": "Python and Rust",
"start": 8,
"end": 23,
"sources": [
{"entity": "Python", "fact": "uses Python daily for backend development"},
{"entity": "Rust", "fact": "Rust is favorite language"}
]
},
{
"text": "Java for enterprise systems",
"start": 92,
"end": 119,
"sources": [
{"entity": "Ali Baizhanov", "fact": "specializes in Java/Spring Boot for enterprise"}
]
}
],
"facts_used": 22
}
| Field | Type | Description |
|---|
answer | string | Synthesized answer text. Empty string if Cohere can’t answer from retrieved facts. |
citations | array | Citation objects linking spans of answer back to specific facts. May be empty. |
citations[].text | string | The cited substring as it appears in answer |
citations[].start | int | Start character offset in answer |
citations[].end | int | End character offset in answer |
citations[].sources | array | Facts that support this citation (entity name + fact text) |
facts_used | int | How many facts were passed to Cohere (capped at 30) |
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.
| Parameter | Type | Default | Description |
|---|
after | string | null | ISO datetime start |
before | string | null | ISO datetime end |
user_id | string | "default" | User to search |
limit | int | 20 | Max results |
Cognitive Profile
GET /v1/profile
Generate a Cognitive Profile — a ready-to-use system prompt summarizing a user from memory.
| Parameter | Type | Default | Description |
|---|
user_id | string | "default" | User to profile |
force | boolean | false | Regenerate (bypass cache) |
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.
| Parameter | Type | Default | Description |
|---|
format | string | "claude_md" | Output format: claude_md, cursorrules, windsurf |
force | boolean | false | Regenerate (bypass cache) |
user_id | string | "default" | User whose memories to use |
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.
| Parameter | Type | Default | Description |
|---|
limit | int | 20 | Max results |
after | string | null | ISO datetime filter start |
before | string | null | ISO datetime filter end |
user_id | string | "default" | User to query |
GET /v1/episodes/search
Semantic search over episodic memories.
| Parameter | Type | Default | Description |
|---|
query | string | required | Search query |
limit | int | 5 | Max results |
after | string | null | ISO datetime filter start |
before | string | null | ISO datetime filter end |
user_id | string | "default" | User to search |
Procedural Memory
GET /v1/procedures
List learned workflows and procedures.
| Parameter | Type | Default | Description |
|---|
limit | int | 20 | Max results |
user_id | string | "default" | User to query |
GET /v1/procedures/search
Semantic search over procedural memories.
| Parameter | Type | Default | Description |
|---|
query | string | required | Search query |
limit | int | 5 | Max results |
user_id | string | "default" | User to search |
PATCH /v1/procedures/:id/feedback
Record success or failure for a procedure. On failure with context, triggers experience-driven evolution.
| Parameter | Type | Default | Description |
|---|
success | boolean | required | Whether the procedure worked |
context | string | null | What went wrong (triggers evolution) |
failed_at_step | int | null | Which step number failed |
user_id | string | "default" | User to query |
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.
Valid types: 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.
| Parameter | Type | Default | Description |
|---|
source | string | required | Entity to merge from |
target | string | required | Entity to merge into |
user_id | string | "default" | User |
POST /v1/merge_user
Merge the generic “User” entity into the primary person entity.
POST /v1/archive_fact
Archive a specific fact (soft-delete).
{"entity_name": "PostgreSQL", "fact_content": "Uses version 15"}
Insights & Reflections
POST /v1/reflect
Manually trigger memory reflection. Generates AI insights from facts.
GET /v1/reflections
Get all reflections. Optional scope filter: entity, cross, temporal.
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.
| Parameter | Type | Default | Description |
|---|
agent | string | "all" | Agent to run: curator, connector, digest, or all |
auto_fix | boolean | false | Auto-archive bad facts |
user_id | string | "default" | User to run agents for |
GET /v1/agents/history
Get agent run history. Optional agent 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.
| Parameter | Type | Default | Description |
|---|
include_fired | boolean | false | Include already-fired triggers |
limit | int | 50 | Max results |
user_id | string | "default" | User to query |
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.
| Parameter | Type | Default | Description |
|---|
user_id | string | "default" | User to query |
GET /v1/feed
Activity feed — recent facts with timestamps.
| Parameter | Type | Default | Description |
|---|
limit | int | 50 | Max items |
user_id | string | "default" | User to query |
Webhooks
POST /v1/webhooks
Create a webhook.
{
"url": "https://your-app.com/hook",
"name": "Production",
"event_types": ["memory_add", "memory_update", "memory_delete"],
"secret": "your-hmac-secret"
}
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.
{"name": "Engineering", "description": "Shared engineering memory"}
GET /v1/teams
List your teams.
POST /v1/teams/join
Join a team via invite code.
{"invite_code": "abc123"}
GET /v1/teams/:team_id/members
Get team members.
POST /v1/teams/:team_id/share
Share a memory entity with a team.
{"entity_name": "PostgreSQL"}
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.
{"name": "production-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.
GET /v1/me
Get current account info (email, plan, user_id).
Error Responses
All endpoints return structured JSON errors.
401 Unauthorized
Invalid or missing API key.
{"detail": "Invalid API key"}
402 Quota Exceeded
Monthly plan limit reached. Includes upgrade URL and retry timing.
{
"error": "quota_exceeded",
"action": "add",
"limit": 50,
"used": 50,
"plan": "free",
"upgrade_url": "https://mengram.io/checkout?token=...",
"message": "Monthly add limit reached (50). Upgrade to Starter ($5/mo) at ...",
"retry_after": 864000
}
The response also includes a Retry-After header (seconds until monthly reset).
| Field | Type | Description |
|---|
error | string | Always "quota_exceeded" |
action | string | Which action was blocked: add, search, add_file |
limit | int | Monthly limit for this action |
used | int | Current usage count |
plan | string | Current plan: free, starter, pro, business |
upgrade_url | string | Direct upgrade link (includes signed checkout token) |
message | string | Human-readable message with next plan and price |
retry_after | int | Seconds until quota resets (end of month) |
429 Rate Limited
Too many requests. Retry after the Retry-After header value.
{"detail": "Rate limit exceeded"}
Every authenticated response includes rate limit and quota usage headers.
Rate Limiting
| Header | Description |
|---|
X-RateLimit-Limit | Requests allowed per minute |
X-RateLimit-Remaining | Requests remaining this minute |
X-RateLimit-Reset | Seconds until rate limit resets |
Quota Usage
| Header | Description |
|---|
X-Quota-Add-Used | Add calls used this month |
X-Quota-Add-Limit | Add calls allowed this month |
X-Quota-Search-Used | Search calls used this month |
X-Quota-Search-Limit | Search calls allowed this month |
SDKs expose quota headers via the .quota property — see Python SDK and JavaScript SDK.
Health
GET /v1/health
Health check. Returns basic status for unauthenticated requests; detailed diagnostics for authenticated.