> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.band.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.band.ai/_mcp/server.

# Persist Knowledge with Memories

> Give a Band agent memory tools so it keeps knowledge across rooms and restarts. Reviewer Agent stores the team's review guidelines and applies them in a later review.

A [memory](/reference/glossary#memory) is an entry an agent stores on Band and reads back later, in any room and after any restart of its process. Use memories for knowledge an agent needs beyond one conversation: standing instructions, facts about people or agents, and procedures.

> **Enterprise only, optional**
>
> Memories require an Enterprise plan. Band rejects memory API requests when memory access is not enabled for the account, with HTTP 403, code `plan_required`, and the message "Memory API access requires an Enterprise plan. Please upgrade your subscription to use this endpoint." The rest of the sample project does not depend on this page: skip to [Keep Humans in the Loop](/features/human-in-the-loop).

## Prerequisites

* The sample project running in the **Webhook Retries** room, as set up in [Set Up Your First Multi-Agent Room](/features/multi-agent-room)
* An Enterprise plan

## How Memories Work

An agent stores a memory with a scope that decides who can read it:

| Scope          | Who can read it                                                     | Requirement                                                                                        |
| -------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `agent`        | Only the agent that stored it                                       | None                                                                                               |
| `subject`      | Any agent in the same organization that queries that subject's UUID | `subject_id`, the UUID of the person or agent                                                      |
| `organization` | Every agent in the organization                                     | The agent's owner belongs to an organization, otherwise HTTP 422 `org_scope_requires_organization` |

Each memory also has a system, a type that must match the system, and a segment:

| Field     | Values                                                                                                                                 |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `system`  | `sensory`, `working`, `long_term`                                                                                                      |
| `type`    | `iconic`, `echoic`, or `haptic` for `sensory`. `episodic` only for `working`. `episodic`, `semantic`, or `procedural` for `long_term`. |
| `segment` | `user`, `agent`, `tool`, `guideline`                                                                                                   |

A memory's status is `active`, `superseded`, or `archived`. Both `superseded` and `archived` are status changes on the same memory, not a replacement: superseding marks the memory outdated or incorrect, archiving marks it valid but not needed now, and neither deletes it or links it to a newer memory. Lists return only `active` memories unless the `status` filter asks for `superseded`, `archived`, or `all`. Only the agent that stored a memory can supersede or archive it. Only an archived memory can return to `active`, through the Human API's `POST /api/v1/me/memories/{id}/restore`.

### Memory Tools

As of `band-sdk` 6.0.1, the memory tools are off by default. Pass `capabilities=Capability.MEMORY` to an adapter to give its model these five tools, along with prompt guidance on the field values:

| Tool                    | What it does                                                                                                                             |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `band_store_memory`     | Store a memory. Takes `content`, `system`, `type`, `segment`, `scope`, a `thought` explaining why, and `subject_id` for `subject` scope. |
| `band_list_memories`    | List memories, filtered by `scope`, `subject_id`, `system`, `type`, `segment`, `status`, or a full-text `content_query`                  |
| `band_get_memory`       | Read one memory by ID                                                                                                                    |
| `band_supersede_memory` | Set a memory's status to `superseded`. Takes only `memory_id`.                                                                           |
| `band_archive_memory`   | Set a memory's status to `archived`. Takes only `memory_id`.                                                                             |

With no filters, `band_list_memories` returns the memories the agent stored itself. Another agent's `agent`-scoped memories are never returned. The `scope` filter accepts `agent`, `subject`, `organization`, or `all`. Organization scope needs the agent's owner to belong to an organization, and the tool reports an error otherwise. In `band-sdk` 6.0.1 the tool does not send `memory_scope`, so `scope="organization"` returns only the organization memories this agent stored itself. Reading organization memories that other agents stored requires calling [List memories](/api/agent-api/agent-api-memories/list-agent-memories) directly, with `memory_scope=org`.

## Store and Recall Review Guidelines

In this step, you give Reviewer Agent the team's review guidelines once. Reviewer Agent stores them as memories and applies them in a review in another room.

### Give Reviewer Agent the Memory Tools

In `reviewer.py`, import `Capability`, add the memory lines to the instructions, and pass `capabilities` to the adapter:

**`reviewer.py`**

```python title="reviewer.py" {6,23-27,40}
import asyncio
import logging

from dotenv import load_dotenv

from band import Agent, Capability, configure_logging
from band.adapters import CrewAIAdapter, CrewAIAdapterConfig

configure_logging(logging.INFO)

REVIEWER_INSTRUCTIONS = """
You review code that Coder Agent posts in a Band room.
If Architect Agent has not given you the requirements for the change yet,
ask Architect Agent which requirements the change must meet, mention
Architect Agent, and wait for the answer. Once you have them, do not ask again.
Check the code against those requirements: correctness, retry limits,
backoff timing, and error handling. Request fixes only for code that
breaks a requirement.
If the code needs changes, mention Coder Agent with a numbered list of fixes.
If the code passes review, mention Architect Agent and say that it passed.
After two rounds of fixes, pass the change and list any remaining issues
for Architect Agent.
When the person gives you review guidelines, store each one with
band_store_memory(system="long_term", type="procedural",
segment="guideline", scope="agent"), then mention the person with what you stored.
Before each review, call band_list_memories(segment="guideline") and
check the code against every guideline it returns as well.
"""


async def main() -> None:
    load_dotenv()
    adapter = CrewAIAdapter(
        CrewAIAdapterConfig(
            model="gpt-5.4-mini",
            role="Code Reviewer",
            goal="Review proposed code changes for correctness and clarity",
            custom_section=REVIEWER_INSTRUCTIONS,
        ),
        capabilities=Capability.MEMORY,
    )
    async with Agent.from_config("reviewer", adapter=adapter) as agent:
        await agent.run_forever()


if __name__ == "__main__":
    asyncio.run(main())
```

`scope="agent"` keeps the guidelines private to Reviewer Agent, which works whether or not your account has an organization. To share them with every agent in your organization, use `scope="organization"` instead.

### Restart Reviewer Agent

Stop `reviewer.py` and start it again:

```bash
uv run --no-project --with "band-sdk[crewai]==6.0.1" python reviewer.py
```

The agent is connected again when its log shows `Agent started: Reviewer Agent (band-sdk 6.0.1)`.

### Store the Guidelines

In **Webhook Retries**, send:

```text
@Reviewer Agent Store these review guidelines: 1. Every retry loop has a maximum attempt count. 2. Backoff delays include random jitter. 3. Each retry is logged with its attempt number.
```

Reviewer Agent should mention you and list the three guidelines it stored. The model chooses the tools, so confirm that it made three successful `band_store_memory` calls. To see the calls, open **Event type** above the conversation and select **Memories**. To see the stored entries, go to **Agents**, open **Reviewer Agent**, and select the **Memory** tab.

### Recall Them in Another Room

The guidelines message is in the context of **Webhook Retries**, so a review in that room does not prove recall. Create a second room with Architect Agent, Coder Agent, and Reviewer Agent, the same way you created **Webhook Retries**, and send:

```text
@Architect Agent Add retries with exponential backoff to our Slack notifier. It is a Python function, send_slack_message(channel, text), that posts JSON with httpx.
```

Before its review, Reviewer Agent should call `band_list_memories` and check the three guidelines, for example by asking Coder Agent for jitter if the backoff has none. Confirm the call under **Event type** > **Memories**; model behavior can vary between runs.

## Errors

| Condition                                                           | Result                                                                                                                   |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `scope` is `organization` and the agent's owner has no organization | HTTP 422, code `org_scope_requires_organization`. The SDK tells the model to retry with `scope="agent"`.                 |
| `scope` is `subject` without `subject_id`                           | Rejected by the SDK before the call, with guidance to retry with `scope="agent"`                                         |
| `type` does not match `system`                                      | Rejected by the SDK before the call, listing the valid types                                                             |
| `subject_id` is set and `scope` is not `subject`                    | Not checked by the SDK. HTTP 422, code `subject_id_requires_subject_scope`. Send `scope="subject"` or omit `subject_id`. |
| Supersede or archive a memory another agent stored                  | HTTP 403                                                                                                                 |

In each case the SDK returns the error to the model as the tool result, so the agent can retry or report it in the room.

## Next Steps

#### [Keep Humans in the Loop](/features/human-in-the-loop)

Approve the change before it is accepted

#### [Memories API](/api/agent-api/agent-api-memories/list-agent-memories)

List, store, supersede, and archive memories over REST