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)
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.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
text | string | The raw input. Provide exactly one of text or messages — never both. |
messages | object[] | Conversation transcript as {role, content} turns. Provide exactly one of text or messages. |
source | string | Optional origin label: chat, event, or file. Defaults to chat. |
metadata | object | Optional metadata persisted with each stored candidate. |
{"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:createdstores one or more rows inmemory_ids;skippedstores nothing and carries areason. - The write returns fast; extraction continues asynchronously — correlate with
request_idand 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 osfrom memorysync import MemorySyncClientclient = 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)
Ranked semantic retrieval scoped by explicit tenant and user. Returns records; use Retrieve below when you want a prompt-ready block instead.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
prompt | string | Required natural-language query. |
k | integer | Optional result ceiling, 1–100. Defaults to 8. |
rerank | boolean | Optional. The rerank pass defaults to on; set false to bypass it. |
weights | object | Optional custom ranking weights {semantic, recency, importance}; values 0–1, normalized server-side. |
summaries_only | boolean | Optional. Return only summary memories. Defaults to false. |
{"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 osfrom memorysync import MemorySyncClientclient = 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)
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.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
query | string | Required natural-language query. |
top_k | integer | Optional result ceiling, 1–8 (hard cap 8). Defaults to 5. |
token_budget | integer | Approximate token ceiling for the rendered context block, 100–4000. Defaults to 800. |
{"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 osfrom memorysync import MemorySyncClientclient = 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)
Collapse the user's most recent raw memories into one summary row. Metered as an add, because it persists a new summary memory.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
threshold | integer | Minimum raw (non-summary) memories required, and the number summarized. Defaults to 5; a 400 is returned when fewer exist. |
{"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 osfrom memorysync import MemorySyncClientclient = 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)
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.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
memory_ids | string[] | Required memory IDs to delete (the m_… form returned by writes and queries). |
{"deleted_ids":["m_311","m_312"],"audit_log_id":9021}
import osfrom memorysync import MemorySyncClientclient = 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)
Recall relevant memories and fill your {context} template placeholder within a token budget — the tenant-addressed sibling of Compose Prompt.
| Field | Type | Contract |
|---|---|---|
tenant_id | string | Required tenant identifier. |
user_id | string | Required end-user identifier. |
prompt_template | string | Required template containing a {context} placeholder. |
recall_k | integer | Optional memories to recall, 1–100. Defaults to 8. |
token_budget | integer | Context token ceiling, 100–16000. Defaults to 4000. |
{"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 osfrom memorysync import MemorySyncClientclient = 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.