Clients
- Sync client:
Memory - Async client:
AsyncMemory - Universal cross-agent client:
UniversalMemory
add() and get() remain the main integration path. Optional domain helper methods expose structured profile data for dashboards.
How domain schemas work with the SDK
Domain schemas are configured on the tenant, not in SDK code. That means this code stays the same:| Tenant setting | What add() does | What get() returns |
|---|---|---|
| General Engine | Generic memory extraction | Generic prompt-ready memory |
| EdTech Schema | Generic memory + EdTech overlay | Generic memory + tutoring/student context |
| Customer Support Schema | Generic memory + Support overlay | Generic memory + support/customer context |
system_prompt_addition can include current issue, support history, resolution preference, sentiment risk, and safety rules. Your own tools still provide live truth such as order status, invoice status, refunds, or ticket updates.
Use the same SDK methods for all three modes.
Memory
add()
Parameters
| Parameter | Type | Required | Notes | |
|---|---|---|---|---|
messages | `list[dict[str, str]] | list[ConversationMessage]` | Yes | At least one message; roles must be user, assistant, or system |
external_user_id | str | Yes | End-user identifier inside your tenant | |
agent_id | `str | None` | No | Optional agent identifier |
metadata | `dict[str, Any] | None` | No | Optional metadata attached to the ingestion job |
Return fields
| Field | Type | Meaning | |||
|---|---|---|---|---|---|
job_id | `str | None` | Extraction job id when queued | ||
status | str | Current add outcome | |||
blocked_reason | `str | None` | Reason when blocked | ||
retry_after_seconds | `int | None` | Retry hint for rate-limit blocks | ||
budget_remaining_pct | `float | None` | Remaining quota after the request estimate | ||
quota_mode | `“FULL" | "PASSTHROUGH" | "DEGRADED_RETRIEVE" | "BLOCKED”` | Quota envelope mode from response headers |
processing_eta_seconds | `int | None` | Queue ETA when ingestion is delayed | ||
processing_status | `“normal" | "delayed”` | Background ingestion health | ||
circuit_status | `“HEALTHY" | "DEGRADED" | "CRITICAL”` | Platform dependency status |
Status outcomes
status value | Meaning | Typical action |
|---|---|---|
queued | Request accepted and extraction job queued | Store job_id if you want to track job state |
passthrough | Tenant is in passthrough mode, so no memory write happens | Continue your app without memory persistence |
L1 | Blocked by per-user rate limit | Retry after retry_after_seconds |
L2 | Blocked by low-quality input | Improve message quality before retrying |
L3 | Blocked as semantically duplicate | Avoid sending repeated near-identical content |
L4 | Blocked by budget governance | Upgrade plan or wait for reset |
blocked | Internal quality-gate failure fallback | Retry later and monitor logs |
get()
Parameters
| Parameter | Type | Required | Notes | ||
|---|---|---|---|---|---|
query | str | Yes | Natural-language retrieval query | ||
external_user_id | str | Yes | End-user identifier inside your tenant | ||
limit | int | No | Default 10 | ||
categories | `list[str] | None` | No | Optional category filter | |
time_filter_days | `int | None` | No | Return only memories from the last N days | |
format | `“bullets" | "json" | "xml”` | No | Format for system_prompt_addition |
context_max_tokens | int | No | Prompt context token budget, default 500 |
Return fields
| Field | Type | Meaning | |||
|---|---|---|---|---|---|
items | list[MemoryResult] | Retrieved memories | |||
cached | bool | Whether the result came from the hot cache | |||
system_prompt_addition | str | Prompt-ready context block | |||
context_token_count | int | Tokens used by system_prompt_addition | |||
memories_from_hot_tier | int | Number of returned memories served from hot tier | |||
quota_mode | `“FULL" | "PASSTHROUGH" | "DEGRADED_RETRIEVE" | "BLOCKED”` | Quota envelope mode |
is_passthrough | bool | True when you should skip memory context | |||
is_degraded | bool | True when retrieval is degraded | |||
circuit_status | `“HEALTHY" | "DEGRADED" | "CRITICAL”` | Platform dependency status |
Degradation handling pattern
Domain profile helpers
For domain-aware tenants, normalget() already includes domain-aware context. Use profile helpers only when your product needs structured UI data.
EdTech example:
delete()
hard_delete=True to permanently delete.
list()
MemoryPage with:
itemsnext_cursorlimittotal
export()
export() maps to GET /v1/users/me/export and returns a MemoryExport bundle containing:
usermemoriesapi_keysagents
export() currently maps to the user export endpoint, not a tenant-wide export endpoint.
get_usage() and delete_user()
The current Python SDK does not expose get_usage() or delete_user() methods.
Use the REST API directly for those operations:
- tenant usage:
GET /v1/tenant/usage - current user deletion:
DELETE /v1/users/me - tenant proxy-user deletion:
DELETE /v1/users/{external_user_id}
AsyncMemory
AsyncMemory has the same method surface as Memory, but every method is async.
Use it when your backend is already async, for example FastAPI, async workers, or high-concurrency chat services. It is not a separate memory engine and it works with General, EdTech, and Support tenants.
UniversalMemory
UniversalMemory is the cross-agent client for the Memory Passport flow. It uses:
- an agent API key (
agent_sk_...) - a user UUI token (
uui_...) for the approved Memory Passport user
redirect_uri, MemoryOS shows a hosted completion page after approval.
categories preselects the memory categories for this consent link. Users can still add or remove categories before approving. If you omit it, MemoryOS uses the global agent’s default categories.
Pass a callback only if your app needs to update its own UI automatically after consent:
add()
Parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
messages | list[dict[str, str]] | list[ConversationMessage] | Yes | Same message shape as tenant-scoped add() |
metadata | dict[str, Any] | None | No | Optional JSON metadata |
Behavior
- writes to
/v1/universal/memories/add - uses the active UUI grant to determine whether the agent may write
- returns
403 UAT_002if the grant is read-only - stores results in the universal memory collection, not the tenant-scoped memory collection
get()
Parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | str | Yes | Natural-language retrieval query |
limit | int | No | Default 10 |
Additional return fields
In addition to the normalRetrieveResult fields, universal retrieval adds:
| Field | Type | Meaning |
|---|---|---|
permission_status | str | None | Permission-related explanation such as no_grant_for_user |
categories_available | list[str] | Categories this agent is currently allowed to read |
Empty result behavior
If the user has not granted this agent access, MemoryOS returns:items = []permission_status = "no_grant_for_user"categories_available = []