Memories & Documents
Memories are short facts about an end-user, injected into every run for that user_id.
Memories vs documents
Documents always belong to an agent (or the company). Manage them with client.documents on the agents page. client.agents.get_document(name) remains available.
Create a memory
from m8tes import M8tes
client = M8tes()
client.memories.create(user_id="cust_123", content="Prefers email over Slack")
client.memories.create(user_id="cust_123", content="Timezone: America/New_York")
client.memories.create(user_id="cust_123", content="VIP customer, escalate issues to a human")When a run executes for that user_id, its memories land in the system prompt. Seed them during onboarding so the first run already has context.
Each memory is short text (max 300 characters), strictly isolated per user_id. Duplicate content for the same user (case-insensitive, whitespace-normalized) returns 409 Conflict.
All memory operations: list, search, update, delete, account scope
List. The source field is "api" for memories you create, "agent" for memories the agent saves during runs.
page = client.memories.list(user_id="cust_123")
for memory in page.data:
print(f"[{memory.id}] {memory.content} (source: {memory.source})")Search. Pass query to keyword-filter by content (case-insensitive substring). The filter is scoped to the end-user; pagination applies to the filtered set.
page = client.memories.list(user_id="cust_123", query="email")Update and delete. Correct a fact in place instead of deleting and re-creating it. Both match exactly the scope you pass: an end-user memory is only reachable with its user_id, an account-level memory only without one.
client.memories.update(7, content="Prefers Slack now", user_id="cust_123")
client.memories.delete(7, user_id="cust_123")Account-level memories. Omit user_id to manage facts injected into runs that carry no user_id (single-tenant setups, internal agents). The two scopes never mix. Requires strict multi-tenant mode to be off (on by default for new API accounts). Turning it off persists account-wide: use this only for personal development; customer-facing apps should keep strict mode on and pass user_id.
client.memories.create(content="Brand voice: direct, no fluff")
page = client.memories.list() # account scope only
client.memories.update(9, content="Brand voice: warm but direct")
client.memories.delete(9)Person or business? Account-level memories can say which they are with audience. It is optional and changes nothing about what agents read today. Both audiences are injected, exactly as before. It exists so that when an account has more than one human, a personal preference does not become a company-wide fact. Recording it as you write is far cheaper than untangling it later.
client.memories.create(content="Prefers Danish", audience="personal")
client.memories.create(content="We sell to DACH mid-market SaaS", audience="company")
client.memories.update(9, content="We sell to DACH mid-market SaaS", audience="company") # fix oneOmit audience when unknown; it reads back as None (unclassified). Older memories default to personal.
Every memory also reports a scope: personal, company, account (account-level, unclassified) or teammate. A memory an agent saved for itself is teammate and always reads audience=None, because its audience is that agent. Read scope, not audience, to tell one from a memory nobody has classified. Trying to classify a teammate memory is refused rather than silently ignored.
Saved memories (agent-created)
During runs, the agent can save memories via its built-in memory tool. These are stored with source: "agent" and follow the same isolation rules. The agent decides what to remember: preferences, key decisions, recurring patterns.
To disable saved memories for a specific run:
run = client.runs.create(
agent_id=bot.id,
message="One-off analysis, don't save anything",
memory=False,
stream=False,
)Previous runs
Runs automatically include context from previous runs for the same user. The agent can search past run outputs to recall what was done before, so you never manage conversation history manually. Pass history=False on a run to start it with a clean slate:
run = client.runs.create(
agent_id=bot.id,
message="Fresh analysis, ignore previous context",
history=False,
stream=False,
)Next: Users · Human-in-the-Loop