# remember

> Save a fact, decision or note — parameters, response, idempotency and every error the tool can return.

On this page you will learn which parameters `remember` accepts, what it returns, how to make retries safe, and why a write can be rejected.

The running example: the agent saves the agreement "staging is deployed with the systemd unit `app-staging`", citing the document `docs/deploy.md`.

## Purpose

`remember` adds a new record to the memory of the project the key belongs to. It **never deletes or overwrites** existing records: saving again with the same `fact_key` adds a newer version, and the earlier versions are kept and marked.

## Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `content` | string | — (required) | Record text. Not empty, at most 100,000 characters. |
| `workspace` | string | `"default"` | Workspace. Created in the key's project if it does not exist yet. |
| `scope` | string | `"shared"` | A label such as `shared` or `private`. Search can filter by it. It does not restrict access. |
| `source` | string | `"owner"` | Who is saving the record (for example `owner`, `agent`). |
| `source_id` | string or null | `null` | Source label: a document, file or session. |
| `source_hash` | string or null | `null` | Hash of the source content, later used to detect staleness. Requires `source_id`. |
| `source_revision` | string or null | `null` | Source version (tag, revision number). |
| `fact_key` | string or null | `null` | Topic key. Records with the same key and different content get the `conflict` status. |
| `confidence` | number | `0.5` | Confidence from 0.0 to 1.0. |
| `derived_from` | array of string or null | `null` | IDs of the records this one summarizes. Up to 50 IDs, existing records you can read only. |

## Response

| Field | Description |
| --- | --- |
| `id` | ID of the new record. You need it for `forget` and `derived_from`. |
| `api_version` | Server API version (`1.0`). |
| `workspace` | Workspace. |
| `tenant_id` | Account identifier. |
| `project_id` | The key's project identifier. |
| `scope` | Record label. |
| `status` | Always `unverified` for a new record. |
| `source_id`, `source_hash` | Provenance as sent (after secret redaction). |
| `derived_from` | Sorted list of source record IDs; empty unless this is a summary. |
| `created_at` | Creation time, ISO 8601 (UTC). |

## Example

The call as the agent makes it:

```json title="arguments"
{
  "content": "staging is deployed with the systemd unit app-staging",
  "workspace": "default",
  "source": "agent",
  "source_id": "docs/deploy.md",
  "source_hash": "sha256:9f2c4e1a",
  "source_revision": "a1b2c3d",
  "fact_key": "deploy-staging",
  "confidence": 0.9
}
```

Response:

```json
{
  "id": "4d428a41-e7b0-4f81-a886-f40c6f6c766c",
  "api_version": "1.0",
  "workspace": "default",
  "tenant_id": "t-3f9a",
  "project_id": "0c6e2b54-2d0f-4a51-9d0e-6b1f3c2a8e77",
  "scope": "shared",
  "status": "unverified",
  "source_id": "docs/deploy.md",
  "source_hash": "sha256:9f2c4e1a",
  "derived_from": [],
  "created_at": "2026-10-05T09:12:00.412345+00:00"
}
```

A summary of several records is the same call with `derived_from`:

```json title="arguments"
{
  "content": "Deploys: staging uses the systemd unit app-staging, prod goes through the release pipeline",
  "fact_key": "deploy-summary",
  "derived_from": ["4d428a41-e7b0-4f81-a886-f40c6f6c766c", "b7e1d0c2-5a44-4f0e-8f3a-2c9d1e6f0a11"]
}
```

## Errors

Errors come back with `"isError": true` as `Error executing tool remember: …`.

| Text | Cause |
| --- | --- |
| `content exceeds maximum allowed length` | `content` is longer than 100,000 characters. |
| `content must not be empty` | `content` is empty or whitespace only. |
| `Memory rejected by Security Guard: …` | Memory Guard detected a memory-poisoning attempt (instructions such as "ignore previous instructions"). |
| `workspace and scope must not be empty` | Empty `workspace` or `scope`. |
| `confidence must be between 0 and 1` | `confidence` outside 0–1. |
| `source_id is required when source_hash is provided` | `source_hash` without `source_id`. |
| `derived_from accepts at most 50 memory ids` | More than 50 IDs in `derived_from`. |
| `derived_from contains unknown memory ids` | Some IDs do not exist, were deleted, or are not visible to you. |
| `invalid X-Idempotency-Key` | The idempotency key is empty, longer than 256 characters, or contains non-printable-ASCII characters. |
| `409 Conflict: idempotency key was used with different input` | The same idempotency key was already used with different content. |
| `project memory limit exceeded` | The project's plan record limit is reached. |
| `maximum number of memories exceeded for workspace` / `… for tenant` | The technical record limit of the workspace or account is reached. |
| `MCP rate limit exceeded`, `project call limit exceeded` | Too many calls per minute. |
| `workspace '…' was deleted and cannot be reused` | A workspace with this name was deleted. |
| `403 Forbidden: workspace access denied for project` | The workspace belongs to another project. |
| `membership may not write in this organization` | In an organization: auditor role or inactive membership. |
| `[MMW Notice]: …` | No subscription, grace period (read-only) or suspended account. |

What to do about each one: see [Errors](/reference/errors/).

## Notes

**Idempotency.** With a direct HTTP connection, send the `X-Idempotency-Key` header (1–256 printable ASCII characters). A retry with the same key and the same parameters returns the same response with the same `id`; no new record is created. The key is scoped to the access key, project and workspace. Reusing it with different parameters returns `409 Conflict`.

**There is no `verified` status.** `source_hash` is provenance, not proof. A new record is always `unverified`; later `search` may report it as `stale` or `conflict`. See [Source and freshness](/memory/source-and-freshness/).

**`scope` is a label, not access control.** In an organization, who can see a record is decided by its visibility (author, department, project, whole organization), not by `scope`. See [Visibility](/organizations/visibility/).

**Secrets are redacted.** Before saving, Memory Guard replaces any keys, tokens and passwords it finds in text fields with markers like `[REDACTED:rule:8-char hash]`. The record is still saved. See [Memory Guard](/memory/memory-guard/).

**Archivist.** After saving, the [archivist](/memory/archivist/) analyzes the record in the background and links it to other records (visible as `graph_relations` in `search`).

When you save a summary, always pass `derived_from`. If the source records later turn out to conflict or go stale, the summary gets the same status and never looks more reliable than its sources.

## Next steps
