supermemory/apps/docs/concepts/multi-tenancy-examples.mdx
MaheshtheDev 672defc08b docs: move SDK snippets to the shipped v5 call shape and finish the namespace rename (#1772)
Rewrites 339 TypeScript calls across 50 pages from the rc.5 `method({ namespace, body })` form to the shipped `method(namespace, { ... })` form, and aligns field names with the live v5 spec: `attach` to `include`, `authUrl` to `authorization`, `lastSync` to `latestRun`, `deletedCount` to `count`, and the paginated `namespaces.list()`.

Renames container tags to namespaces across concepts, connectors, integrations and snippets. The namespace pages keep container tag in the description, search keywords and a rename note so old searches still land, and the v3 reference page points at v5.

The migration guide's SDK table now covers both 5.0.0 SDKs, and the SDK integration page uses the real client options (`baseUrl`, `timeoutInSeconds`, `maxRetries`) and error classes.
2026-10-06 17:06:38 +00:00

125 lines
3.9 KiB
Text

---
title: "Multi-tenancy examples"
sidebarTitle: "Examples"
description: "Common namespace and metadata patterns for personal agents, company agents, email assistants, and support platforms"
icon: "/icons/hugeicons/check-list.svg"
---
A few common shapes multi-tenancy takes in practice, combining [namespaces](/concepts/container-tags) for isolation with [metadata filters](/concepts/filtering) for organization within a boundary.
---
## Personal agent
A single namespace per user is enough — there's no shared data to leak, so metadata is optional.
```typescript
await supermemory.add(userId, { // one namespace per user
content: "User prefers morning workouts and vegetarian meals",
});
const results = await supermemory.search(userId, {
query: "workout preferences",
});
```
---
## Company agent (shared + personal memory)
A company-wide assistant usually needs two kinds of namespaces: one **shared** namespace the whole org reads from, and one **personal** namespace per employee that nobody else can see.
```typescript
// Shared org knowledge — visible to everyone at the company
await supermemory.add("org_acme_shared", {
content: "Q3 roadmap: ship the mobile app redesign by end of August",
metadata: { team: "product", type: "roadmap" },
});
// Personal memory — only this employee's agent should see this
await supermemory.add("org_acme_user_alex", {
content: "Prefers async updates over meetings",
});
```
Inside the shared namespace, use metadata to scope queries to a team rather than creating a namespace per team:
```typescript
const results = await supermemory.search("org_acme_shared", {
query: "roadmap updates",
filter: { field: "team", operator: "eq", value: "product" },
searchMode: "chunks",
});
```
An employee's agent typically queries both namespaces — their personal one plus the shared one — and merges the results, since a request is scoped to exactly one namespace.
---
## Email assistant
One namespace per user, with metadata carrying email-specific properties like label, sender, or folder — so the assistant can answer things like *"find the Spotify email tagged Promotional"*.
```typescript
await supermemory.add(userId, {
content: "Your Spotify Premium receipt for July — $11.99 charged",
metadata: {
source: "gmail",
sender: "no-reply@spotify.com",
label: "Promotional",
},
});
const results = await supermemory.search(userId, {
query: "spotify",
filter: {
operator: "and",
operands: [
{ field: "source", operator: "eq", value: "gmail" },
{ field: "label", operator: "eq", value: "Promotional" },
],
},
searchMode: "chunks",
});
```
---
## Multi-tenant support platform
Each customer gets their own namespace, and metadata tracks ticket-level fields like status and priority — so "open, high-priority tickets" is a filter, not a new namespace, and it can never accidentally include another customer's tickets.
```typescript
await supermemory.add("org_customer_442", {
content: "Customer reports checkout button unresponsive on Safari",
metadata: { status: "open", priority: "high", channel: "chat" },
});
const results = await supermemory.search("org_customer_442", {
query: "checkout issue",
filter: {
operator: "and",
operands: [
{ field: "status", operator: "eq", value: "open" },
{ field: "priority", operator: "eq", value: "high" },
],
},
searchMode: "chunks",
});
```
---
## Next steps
<CardGroup cols={2}>
<Card title="Multi-tenancy Overview" icon="/icons/hugeicons/user-multiple.svg" href="/concepts/multi-tenancy">
Why namespaces and metadata are separate mechanisms.
</Card>
<Card title="Namespaces" icon="/icons/hugeicons/folder-01.svg" href="/concepts/container-tags">
How isolation works, naming rules, and access control.
</Card>
<Card title="Organizing & Filtering" icon="/icons/hugeicons/filter.svg" href="/concepts/filtering">
Metadata filter operators, combining `and`/`or`, and query limits.
</Card>
</CardGroup>