MemorySync
API Reference

Tenant Write & Retrieval Operations

The remaining tenant-addressed operations: extraction-gated writes, two retrieval variants, summarization, deletion, and prompt composition — all addressing tenant and user explicitly in the body.

Add Memory (tenant-addressed)

POST/v1/memory/add
201 Created

The tenant-addressed sibling of Add Memory. Every input runs through the extraction pipeline; only distilled high-value memories are persisted, and a successful response can report that nothing was stored (status: "skipped" with reason: "no_high_value_content"). There is no path that stores the raw input verbatim — use Add Conversation Turn for verbatim storage.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
textstringThe raw input. Provide exactly one of text or messages — never both.
messagesobject[]Conversation transcript as {role, content} turns. Provide exactly one of text or messages.
sourcestringOptional origin label: chat, event, or file. Defaults to chat.
metadataobjectOptional metadata persisted with each stored candidate.
response.json
{"memory_id":"m_311","status":"created","processing_status":"pending","memory_ids":["m_311","m_312"],"candidates_extracted":2,"candidates_stored":2,"candidates_updated":0,"candidates_deduped":0,"candidates_rejected":0,"request_id":"req_9f3a"}
  • Branch on status: created stores one or more rows in memory_ids; skipped stores nothing and carries a reason.
  • The write returns fast; extraction continues asynchronously — correlate with request_id and poll Memory Status when you need settled state.
  • Requires an API key whose scopes allow writes; the key must belong to the organization that owns the tenant.
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Query Memory (tenant-addressed)

POST/v1/memory/query
200 OK

Ranked semantic retrieval scoped by explicit tenant and user. Returns records; use Retrieve below when you want a prompt-ready block instead.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
promptstringRequired natural-language query.
kintegerOptional result ceiling, 1–100. Defaults to 8.
rerankbooleanOptional. The rerank pass defaults to on; set false to bypass it.
weightsobjectOptional custom ranking weights {semantic, recency, importance}; values 0–1, normalized server-side.
summaries_onlybooleanOptional. Return only summary memories. Defaults to false.
response.json
{"memories":[{"memory_id":"m_311","tenant_id":"acme","user_id":"usr_7f3a9c2e","source":"chat","raw_text":"Prefers the aisle seat on long-haul flights.","summary":null,"metadata":null,"created_at":"2026-08-22T10:00:04Z","score":0.87,"importance":0.6}],"latency_ms":41.7}
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Retrieve Context (tenant-addressed)

POST/v1/memory/retrieve
200 OK

The simpler retrieval sibling: a fixed deterministic ranker (semantic 0.5 / recency 0.3 / importance 0.2 with a 30-day staleness penalty), semantic dedup, and a pre-built context block you can place straight into a prompt.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
querystringRequired natural-language query.
top_kintegerOptional result ceiling, 1–8 (hard cap 8). Defaults to 5.
token_budgetintegerApproximate token ceiling for the rendered context block, 100–4000. Defaults to 800.
response.json
{"memories":[{"memory_id":"m_311","type":"preference","key":null,"value":"Prefers the aisle seat on long-haul flights.","score":0.79,"semantic":0.88,"recency":0.71,"importance":0.6,"staleness_penalty":0.0}],"context":"- Prefers the aisle seat on long-haul flights.","candidate_count":14,"selected_count":1,"latency_ms":38.2,"query_hash":"q_ab12"}
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Summarize Memories (tenant-addressed)

POST/v1/memory/summarize
200 OK

Collapse the user's most recent raw memories into one summary row. Metered as an add, because it persists a new summary memory.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
thresholdintegerMinimum raw (non-summary) memories required, and the number summarized. Defaults to 5; a 400 is returned when fewer exist.
response.json
{"summary_id":"m_340","summary_text":"Travel preferences: aisle seat, morning departures.","child_memory_ids":["m_311","m_312","m_318","m_322","m_325"]}
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Forget Memories (tenant-addressed)

POST/v1/memory/forget
200 OK

Delete specific memories with an audit-log entry (GDPR-supporting). Unlike the header-scoped `DELETE /memory/forget`, this variant is a POST that addresses tenant and user in the body, and it requires an API key with admin scope for destructive operations.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
memory_idsstring[]Required memory IDs to delete (the m_… form returned by writes and queries).
response.json
{"deleted_ids":["m_311","m_312"],"audit_log_id":9021}
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Compose Prompt (tenant-addressed)

POST/v1/compose
200 OK

Recall relevant memories and fill your {context} template placeholder within a token budget — the tenant-addressed sibling of Compose Prompt.

FieldTypeContract
tenant_idstringRequired tenant identifier.
user_idstringRequired end-user identifier.
prompt_templatestringRequired template containing a {context} placeholder.
recall_kintegerOptional memories to recall, 1–100. Defaults to 8.
token_budgetintegerContext token ceiling, 100–16000. Defaults to 4000.
response.json
{"composed_prompt":"You know this about the user:\n- Prefers the aisle seat…\n\nUser: Book me a flight","memories_used":3,"token_count":214,"truncated":false}
import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
project_id=os.environ["MEMORYSYNC_PROJECT_ID"],
end_user_id="usr_7f3a9c2e",
)
# No dedicated SDK method — call over HTTPS from your backend.

Quota behaviour

Errors and next action

A 422 means a missing or contradictory field (for add: provide exactly one of text or messages). A 403 means the API key cannot act for that tenant or lacks the required scope — forget requires admin scope, writes require write scope. A 400 from summarize means fewer than threshold raw memories exist. For 429 or 5xx, retry writes with the same payload after a delay.

Safety notes

Was this page helpful?