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

# Kartas & memory

> The id you choose selects the durable agent instance, workspace, and memory a session uses - one per user, virtual employee, backend task, or fleet member.

When someone or something talks to your agent, you choose the **karta id**. The
id tells Karta which durable workspace and memory to resume. In the
[widget](/sdks/widget/identity), this is usually `userId`; in
[session metadata](/api-reference/sessions), it is `end_user_id` (or its
`user_id` alias). For a virtual employee that works with a team, a backend task
singleton, or a fleet member, your backend can set `agent_instance_id`.

That id is the single most consequential thing you set, because:

**One id is one durable karta** - one running agent instance with its own
workspace and memory. Create one per user for personal AI assistant use cases,
one per team for virtual employee use cases, one singleton for a backend task
that may run on a timer, event, or on-demand call, or one per fleet member.
Everything the agent accumulates for that id - files, artifacts, conversation
history, and any memory it builds up - is keyed on it. Reach it again with the
same id and the karta picks up where it left off. Reach it with a different id
and you get a fresh karta, remembering nothing.

So the id is the switch that selects the agent instance, workspace, and memory.
Choosing what it maps to is a product decision.

With [workspace access](/cli/workspace-access) enabled, an admin can clone
everything a karta has accumulated read-only over git, to inspect or back it up.

## The mental model: one agent project, many kartas

You deploy one agent project. Karta runs that project as many durable kartas,
each keyed by the id you choose:

* Map the id to **your user's id** -> each user-agent relationship gets its own
  karta with private, accumulating memory.
* Map the id to **a virtual employee id** -> many humans can work with the same
  persistent virtual employee, Jira agent, or shared operations agent. This
  creates one karta for that virtual employee, not one karta for the whole team.
* Map several ids to **several virtual employees** -> one team can operate a
  roster, such as two Auditor kartas covering different business areas and
  three Reviewer kartas checking reports from different angles. That roster can
  include kartas from one agent project or several.
* Map the id to **a fleet member id** -> each student, account, project, or
  system gets its own karta while a supervisor agent coordinates across them.

The project stays the same. The agent instance, files, and memory change with
the id.

## Choosing the grain

| Grain                      | Use when                                                                                         | Example id                        |
| -------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------- |
| Per user                   | Each signed-in user should have private memory and files for this agent.                         | `user_12345`                      |
| Per virtual employee       | Several humans should work with the same durable virtual employee.                               | `team_acme:auditor:north_america` |
| Per backend task singleton | A scheduled, event-triggered, or on-demand backend task needs one durable workspace across runs. | `job_invoice_reconcile_2026_06`   |
| Per fleet member           | Many similar workers each need isolated memory while a supervisor coordinates them.              | `student_8742` or `account_acme`  |
| Throwaway                  | No memory should carry to a later session.                                                       | `ephemeral`                       |

Pick the smallest grain that matches your privacy model. If two actors should
not see each other's files, use different ids. If they are meant to share a
workspace, share the id deliberately.

## Identity trust levels

Continuity and trust are separate decisions:

| Identity level              | Can resume the same karta?                 | Trusted for authorization?                                  |
| --------------------------- | ------------------------------------------ | ----------------------------------------------------------- |
| Anonymous widget id         | Yes, in the same browser.                  | No.                                                         |
| Soft `userId`               | Yes, wherever your page sends the same id. | No.                                                         |
| Verified `userId`           | Yes.                                       | Yes, when your server signs it.                             |
| Backend `agent_instance_id` | Yes.                                       | Yes, because it comes from your server or embed-key config. |

Use verified identity when the agent acts on user-specific data or credentials.
Use soft or anonymous ids only for continuity.

## Three rules

<Steps>
  <Step title="Grain equals privacy - there is no sub-key">
    Everyone and everything that shares an id shares one computer. If two people,
    teams, systems, or fleet members must not see each other's files or memory,
    give each their own id. You cannot get finer-grained privacy out of a coarse
    id - the karta has nothing finer to separate on. For a virtual employee,
    household, project, or backend task that *should* share context, share the id
    deliberately.
  </Step>

  <Step title="Use a stable, durable key">
    The id must stay the same for as long as you want the memory to live. Derive
    it from something permanent (your internal user id), never from something
    that changes between visits - a session token, a rotating value, an email
    that can change. If the id drifts, the old karta is orphaned and the user
    silently starts over.
  </Step>

  <Step title="Treat it as a tenant boundary">
    The id is a security boundary, not a display label. Make it stable, opaque,
    and non-guessable, and keep your id spaces from colliding (a team id that
    happens to equal another user's id would share their karta). For ids your
    own server can vouch for, use [verified identity](/sdks/widget/identity) so
    the agent can safely act on per-user data.
  </Step>
</Steps>

## Throwaway kartas

Sometimes you want no memory at all - a public FAQ bot, or a shared kiosk where
the next person must not see the last conversation. Pass the reserved id
`ephemeral`:

```js theme={null}
karta("identify", { userId: "ephemeral" });
```

Each `ephemeral` session becomes its own isolated, single-use karta - nothing
carries across sessions, and no two ephemeral users ever share state. It behaves
like any other karta for the duration of the session, then disappears after the
session ends.

<Note>
  `ephemeral` is different from passing nothing. An anonymous visitor still gets
  a per-browser id so a reload resumes the same conversation;
  `ephemeral` guarantees a fresh, isolated karta every time.
</Note>

## Checking your ids are stable

If you intend kartas to be reused but your key is unstable, returning users
quietly lose their memory. Your agent's **Overview** surfaces a *per-karta
utility* reading, which measures how often a karta is reached more than once.
If you expect reuse but the reading shows kartas are almost always one-shot,
your id is probably drifting between visits.

## Inspecting a karta's files

A karta's durable files are normally private to the running agent. When you need
to see what one has accumulated, an org admin can enable **workspace access** and
clone the karta's workspace read-only over git - see
[Clone a karta's workspace](/cli/agents-and-sessions#clone-a-kartas-workspace).

## Next

<CardGroup cols={2}>
  <Card title="Widget identity" icon="fingerprint" href="/sdks/widget/identity">
    Anonymous, soft, and verified ids - and how to sign a verified id.
  </Card>

  <Card title="Sessions API" icon="code" href="/api-reference/sessions">
    Passing `end_user_id` in session metadata directly.
  </Card>
</CardGroup>
