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 fact extraction, and only the durable facts it contains are stored, as memories with their own ids. Extraction is asynchronous, so the response confirms the write rather than listing what was stored. Nothing stores the raw input as a memory: to send one conversation turn use Add Conversation Turn, and to keep a transcript your code reads back use Conversation History & State.

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":null,"status":"processing","processing_status":"pending","memory_ids":null,"candidates_extracted":null,"candidates_discarded":null,"candidates_stored":null,"candidates_updated":null,"candidates_deduped":null,"candidates_rejected":null,"deduplicated_against":null,"reason":null,"request_id":"9f3a51c0e2d84b7a"}
  • status is processing while the facts are extracted, or accepted when extraction already ran. memory_id, memory_ids and the candidates_* counts are null, because the response is sent before extraction finishes.
  • The extracted memories get their own ids and appear in List Memories shortly after; request_id correlates the extraction. Input with nothing worth keeping stores nothing.
  • 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. Counts as one add.

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. Like every delete route, it needs an API key that can delete memories (the memories:delete scope).

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 needs memories:delete, and writes need 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?