Skip to main content
POST
JavaScript
Nothing in a memory layer lands in the context window up front. The agent reaches for what it needs, when it needs it. That is the whole design: you can hand an agent a thousand pages of policy without paying for a single token until it asks. spec.type is required, and it decides everything about how the layer behaves.

Two types, two mechanics

A skills layer is a reference library you curate. An episodic layer is a diary the agent keeps. They are not interchangeable. Either way the agent reads with the same two tools: get_memory to pull an entry by its exact key, and search_memory to find a key it does not know. Only an episodic layer grants store_memory.
Both metadata.name and spec.type are enforced: omit either and the request fails with a 400.

Write the entry description for the model

An entry’s description is the only thing the model sees before it decides whether to read the body, and it is the text search_memory matches against. It is not a note to your teammates. It is the “when to use this” line. Write When a customer asks for a refund, not Refund policy v3 (updated by Dana). The first tells a model when to reach for the entry, and gives search something to hit. The second tells it nothing it can act on. Search matters more than it looks. search_memory runs trigram similarity over keys and descriptions only, never over content. An entry whose body is full of the right words but whose description is vague stays invisible to the agent. The entry key is what the model passes to get_memory. Slashes are conventional, not structural: policy/refunds reads like a path but lookups are flat, and the key is one opaque string.
The key field documents rules that are not enforced today. Keys beginning or ending with /, containing //, or starting with the reserved cadenya/ and system/ prefixes are all accepted. Uniqueness within a layer is enforced, with a 409. Do not rely on the rest to catch a malformed key for you.

Content comes back only on a detail read

Listing entries gives you the summary view: key, description, and metadata. Read a single entry and you get a top-level content field alongside it. That keeps a list of a thousand entries from dragging their bodies along.
For a body too large to inline, upload it first and set spec.type to uploadId with the upload’s ID, instead of content with an inline body. The type field names which source you chose, and the matching field must ride along with it.
The uploadId path does not work today. An upload never leaves UPLOAD_STATUS_PENDING, and a memory entry that references one hangs rather than erroring. Keep bodies inline until that is fixed.
Sizes to keep in mind. An inline content caps at 1 MiB. A single get_memory call returns at most 500 lines or 100 KB, and the agent pages through anything longer. So a 1 MiB entry is legal and slow to read: split it into entries the agent can pick between.

The cascade decides who wins

An objective resolves keys against an ordered list of layers. The first layer holding a key wins, and everything behind it is shadowed. Think CSS specificity: the most specific source takes the key. Order, most specific first:
  1. The episodic layer, when the objective carries an episodic key.
  2. The objective’s memoryCascade, in array order. Earlier elements are more specific.
  3. The variation’s assigned layers, by ascending position. Lower position is more specific.
Give both layers a policy/refunds entry and the enterprise one wins, because it sits earlier in the array. You never have to reason about this from memory. Read the objective back with includeInfo and info.effectiveMemoryCascade shows you the resolved order, index 0 first:
Pin a single entry rather than a whole layer by passing memoryEntryId alongside its memoryLayerId. That entry then behaves as a one-entry layer at that position. The entry must belong to the layer you name. The total effective cascade, your memoryCascade plus the variation’s assignments, caps at 10 entries. A request that would exceed it is rejected.
System-managed layers cannot be named in memoryCascade. The episodic layer attaches itself, at the most specific end, whenever an objective carries an episodic key.

Episodic memory: the agent’s own notes

An episodic layer is not something you create and fill. Turn on enableEpisodicMemory on the agent, then give each objective an episodicMemory.key. Objectives sharing that key, for that agent, share one system-managed layer, and the agent writes into it with store_memory.
Every objective for that customer now reads and writes the same memory. The agent remembers the last conversation without you threading a transcript through your application. Set episodicMemoryTtl on the agent and the expiry slides forward each time a new objective touches the key. Leave the TTL unset and memories are kept indefinitely. The flag and the key are a matched pair, and the API enforces both directions. Pass an episodicMemory.key to an agent without enableEpisodicMemory and the request fails. Omit the key for an agent that has it enabled, and it fails too. Because the episodic layer sits at the most specific end of the cascade, what the agent learned about this customer beats whatever the general playbook says.
Episodic layers are system-managed. They appear in list (filter by type, agentId, or episodicKeyPrefix), but you cannot attach one to a variation, name one in memoryCascade, or edit it. It attaches itself.

Lifecycle

Entries follow the same create, retrieve, list, update, delete shape, nested under their layer.

Memory cascade

How layers stack, and what happens on a key clash.

Give your agent memory

The hands-on lesson, from empty layer to an agent that remembers.

Create an objective

Where memoryCascade and episodicMemory get set per run.

Preventing tool bloat

The same on-demand idea, applied to tools instead of knowledge.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

workspaceId
string
required
Example:

"workspace_01HXKD2E5NQM3T9AYWCF133E3Q"

Body

application/json
metadata
object
required

CreateResourceMetadata contains the user-provided fields for creating a workspace-scoped resource. Read-only fields (id, account_id, workspace_id, profile_id, created_at) are excluded since they are set by the server.

spec
object
required

Response

OK

MemoryLayer is a named container of memory entries that can be composed into an objective's memory cascade. Layers are workspace-scoped resources. The layer type controls how its entries participate in the agent loop — see MemoryLayerType for details.

See "Memory cascade composition" above for how layers compose at lookup time.

metadata
object
required

Standard metadata for persistent, named resources (e.g., agents, tools, prompts)

spec
object
required
info
object