> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memoryo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Reference for the MemoryOS TypeScript SDK, including tenant-scoped memory and the universal Memory Passport client.

Install the TypeScript SDK:

```bash theme={null}
npm install @memoryos/sdk
```

## Clients

* Tenant-scoped client: `MemoryOS`
* Universal cross-agent client: `UniversalMemoryOS`

```ts theme={null}
import { MemoryOS, UniversalMemoryOS } from "@memoryos/sdk";

const client = new MemoryOS(process.env.MEMORYOS_API_KEY!);
```

Use `MemoryOS` for normal workspace memory inside your tenant. Use `UniversalMemoryOS` only after a user has granted your global agent access through Memory Passport.

There is no separate SDK for domain schemas. If your tenant enables EdTech or Support, `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:

```ts theme={null}
import { MemoryOS } from "@memoryos/sdk";

const client = new MemoryOS(process.env.MEMORYOS_API_KEY!);

await client.add(
  messages,
  "customer-123",
  "support-bot",
  { source: "chat" },
);

const result = await client.get(
  "How should the assistant answer?",
  "customer-123",
);
```

What changes is the tenant setting:

| 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 |

For Support, `systemPromptAddition` 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.

## `add()`

```ts theme={null}
const result = await client.add(
  [{ role: "user", content: "I prefer concise technical explanations." }],
  "customer-123",
  "support-bot",
  { source: "chat" },
);
```

### Parameters

| Parameter        | Type                                   | Required | Notes                                  |
| ---------------- | -------------------------------------- | -------- | -------------------------------------- |
| `messages`       | `ConversationMessage[]`                | Yes      | At least one message                   |
| `externalUserId` | `string`                               | Yes      | End-user identifier inside your tenant |
| `agentId`        | `string \| undefined`                  | No       | Optional agent identifier              |
| `metadata`       | `Record<string, unknown> \| undefined` | No       | Optional metadata                      |

### Return fields

| Field                  | Type                                                          | Meaning                            |
| ---------------------- | ------------------------------------------------------------- | ---------------------------------- |
| `jobId`                | `string \| null`                                              | Extraction job id when queued      |
| `status`               | `string`                                                      | Current add outcome                |
| `blockedReason`        | `string \| null`                                              | Reason when blocked                |
| `retryAfterSeconds`    | `number \| null`                                              | Retry hint for L1 blocks           |
| `budgetRemainingPct`   | `number \| null`                                              | Remaining tenant budget percentage |
| `quotaMode`            | `"FULL" \| "PASSTHROUGH" \| "DEGRADED_RETRIEVE" \| "BLOCKED"` | Quota mode from headers            |
| `processingEtaSeconds` | `number \| null`                                              | Queue ETA when delayed             |
| `processingStatus`     | `"normal" \| "delayed"`                                       | Background ingestion health        |
| `circuitStatus`        | `"HEALTHY" \| "DEGRADED" \| "CRITICAL"`                       | Platform dependency status         |

### Status outcomes

| `status` value | Meaning                                       | Typical action                  |
| -------------- | --------------------------------------------- | ------------------------------- |
| `queued`       | Request accepted and job queued               | Track the job if needed         |
| `passthrough`  | Writes are bypassed in the current quota mode | Continue without persistence    |
| `L1`           | Per-user rate limit exceeded                  | Retry after `retryAfterSeconds` |
| `L2`           | Low-quality input was blocked                 | Improve message quality         |
| `L3`           | Duplicate query was blocked                   | Avoid near-identical writes     |
| `L4`           | Budget governance blocked the request         | Upgrade or wait for reset       |
| `blocked`      | Internal gate fallback                        | Retry later                     |

## `get()`

```ts theme={null}
const memories = await client.get(
  "How should I answer this user?",
  "customer-123",
  5,
  ["preference", "goal"],
);
```

### Parameters

| Parameter          | Type                            | Required | Notes                                      |
| ------------------ | ------------------------------- | -------- | ------------------------------------------ |
| `query`            | `string`                        | Yes      | Natural-language retrieval query           |
| `externalUserId`   | `string`                        | Yes      | End-user identifier inside your tenant     |
| `limit`            | `number`                        | No       | Default `10`                               |
| `categories`       | `MemoryCategory[] \| undefined` | No       | Optional category filter                   |
| `timeFilterDays`   | `number \| undefined`           | No       | Return only memories from the last N days  |
| `format`           | `"bullets" \| "json" \| "xml"`  | No       | Format for `systemPromptAddition`          |
| `contextMaxTokens` | `number`                        | No       | Prompt context token budget, default `500` |

### Return fields

| Field                  | Type                                                          | Meaning                                          |
| ---------------------- | ------------------------------------------------------------- | ------------------------------------------------ |
| `items`                | `MemoryItem[]`                                                | Retrieved memories                               |
| `cached`               | `boolean`                                                     | Whether the result came from the hot cache       |
| `systemPromptAddition` | `string`                                                      | Prompt-ready context block                       |
| `contextTokenCount`    | `number`                                                      | Tokens used by `systemPromptAddition`            |
| `memoriesFromHotTier`  | `number`                                                      | Number of returned memories served from hot tier |
| `quotaMode`            | `"FULL" \| "PASSTHROUGH" \| "DEGRADED_RETRIEVE" \| "BLOCKED"` | Quota mode                                       |
| `isPassthrough`        | `boolean`                                                     | Skip memory context when `true`                  |
| `isDegraded`           | `boolean`                                                     | Retrieval is degraded when `true`                |
| `circuitStatus`        | `"HEALTHY" \| "DEGRADED" \| "CRITICAL"`                       | Platform dependency status                       |

## UniversalMemoryOS

```ts theme={null}
import { UniversalMemoryOS } from "@memoryos/sdk";

const universal = new UniversalMemoryOS(
  process.env.MEMORYOS_AGENT_API_KEY!,
  userUuiToken,
);
```

The universal client is independent from `MemoryOS`. It uses agent credentials and a user UUI token:

* `Authorization: ApiKey agent_sk_...`
* `X-MemoryOS-UUI: uui_...`

### `UniversalMemoryOS.consentUrl()`

```ts theme={null}
const consentUrl = UniversalMemoryOS.consentUrl(
  "your_global_agent_id",
  null,
  userSessionId,
  ["preference", "goal"],
);
```

Redirect users to this URL when they click a control such as "Connect shared memory". If you pass `null` for the callback, MemoryOS shows a hosted completion page after approval.

The fourth argument preselects 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:

```ts theme={null}
const consentUrl = UniversalMemoryOS.consentUrl(
  "your_global_agent_id",
  "https://yourapp.com/integrations/memoryos/callback",
  secureRandomStateToken,
  ["preference", "fact"],
);
```

### `universal.add()`

```ts theme={null}
const result = await universal.add(
  [{ role: "user", content: "I prefer short technical answers." }],
  { source: "chat" },
);
```

### `universal.get()`

```ts theme={null}
const result = await universal.get("How should I personalize this answer?", 5);
```

Universal retrieve responses include the normal retrieve fields plus:

| Field                 | Type             | Meaning                                                                     |
| --------------------- | ---------------- | --------------------------------------------------------------------------- |
| `categoriesAvailable` | `string[]`       | Memory categories the user granted this agent                               |
| `permissionStatus`    | `string \| null` | Permission status, such as `no_grant_for_user`, when no active grant exists |

### Degradation handling pattern

```ts theme={null}
const result = await client.get(
  "What should I remember about this user?",
  "customer-123",
);

const promptAddition = result.hasContext
  ? result.systemPromptAddition
  : "";
```

## Domain profile helpers

For domain-aware tenants, normal `get()` already includes domain-aware context. Use profile helpers only when your product needs structured UI data.

EdTech example:

```ts theme={null}
const profile = await client.getEdTechProfile("student_123");

if (profile?.hasExamContext) {
  console.log(profile.examName, profile.examDate);
}

console.log(profile?.weakTopics.slice(0, 3));
```

## `delete()`

```ts theme={null}
const deleted = await client.delete(
  "1c5d5ab6-73c8-4b12-90e9-0f7f9db8db4f",
  "customer-123",
  false,
);
```

## `list()`

```ts theme={null}
const page = await client.list("customer-123", { limit: 50 });

for (const memory of page.items) {
  console.log(memory.content);
}
```

Returns:

* `items`
* `nextCursor`
* `limit`
* `total`

## `export()`

```ts theme={null}
const bundle = await client.export("customer-123");
```

Returns a `MemoryExport` object with:

* `user`
* `memories`
* `apiKeys`
* `agents`

> `export()` currently maps to the user export endpoint, not a tenant-wide export endpoint.

## `getUsage()` and `deleteUser()`

The current TypeScript SDK does not expose `getUsage()` or `deleteUser()`.

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}`

## Related pages

For the product flow and consent UX, see:

* [Memory Passport](/concepts/memory-passport)
* [Cross-agent memory sharing](/guides/cross-agent-sharing)
