The mistake to avoid
It is tempting to create a space per end user, since a space is already an isolation boundary. Don’t:- Spaces are capped per plan.
- Memories in different spaces are never synthesized together, so you lose the cross-conversation, cross-session learning a memory layer exists to give you.
Write under a scope
Adduser_id (or agent_id, or session_id) to record:
user_id is a real field, not metadata. Putting a user id in metadata stores it
but does not isolate anything. metadata is returned with results, never
filtered on.Read under the same scope
Pass the identical key toretrieve (or reason, or the chat proxy):
What “strict” means in practice
- A scoped search returns only memories written under the same scope. Never another user’s, and never an unscoped memory either.
- If a space already has history and you turn scoping on today, that old history stays visible to unscoped searches but invisible to scoped ones. Backfill the scope onto it if scoped callers need to see it.
- Passing more than one key ANDs them:
user_id+session_idreturns only that user’s memories from that specific session. - Consolidated synthesis (
notememories) is built per user, so a synthesis never blends two users’ facts, while still rolling a user’s sessions up together so the memory improves across conversations, not just within one. - A
notecarries only that one identity: the user, or the agent when the facts have no user, or the session when they have neither. It keeps its source facts’ own tags and provenance, but not theiragent_idorsession_id. So a fact written withuser_id: alice, agent_id: support-aproduces a note scoped toalicealone. Two consequences:- An
agent_id- orsession_id-scoped read sees the facts, not the note. The memory list returns those facts even under the defaultprefer_observations=true, so nothing is hidden behind a note the filter cannot reach. - A
user_id-scoped read sees the note, and that note can draw on facts written by any of your agents for that user. That is the point: what you know about Alice is shared across agents. For a per-agent synthesis, use a memory model; for agents that must never share anything, use separate spaces (see two agents, one space).
- An
Choosing which key
In the drop-in proxy
The same scope keys work as tunables on the chat/responses/messages proxy, as a body field or a header:Reserved tags
Tags beginning withanona: are rejected with 422 reserved_tag. Scope is
implemented as tags internally, and this stops a hand-written tag from forging
someone else’s scope. Always use the user_id/agent_id/session_id fields, never
a tag that looks like one.
Reading back one user’s history
Once you’re writing underuser_id, User Profiles is
the direct way to read it back: everything a space knows about one user, or a
question answered from that user’s memories only, without hand-rolling a wide
retrieve call yourself. It uses the same user_id scope described above, so it only
ever sees what was recorded under it.
Next steps
User Profiles
Read back everything a space knows about one scoped user.
Retrieve API
The full scoping reference, including tag filters.
Core Concepts
Spaces vs. scope, in one page.