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

# Memory models

> Standing questions a space keeps a current answer to: a running model of the user, their preferences, and how they work.

Retrieve answers a question from individual memories. A **memory model** answers a
standing question from *all* of them, and keeps that answer current as new memories
arrive.

Give a model a question ("how does this user like to be communicated with?", "what is
this customer's account history?") and the memory layer synthesizes an answer across
everything the space knows, then rewrites it as the space learns more. Read it back as
markdown and drop it straight into a system prompt.

<Note>
  A model's content is generated in the background. Creating or refreshing one returns a
  `job_id`; poll `GET /v1/spaces/{space_id}/jobs/{job_id}`, then read the model to get its
  content.
</Note>

<Tip>
  Everything on this page is also on the **Models** tab of a space in the
  [dashboard](https://memory.anonalabs.com): the profile, each model's rendered content,
  and create, edit, refresh, clear and delete. Useful for reading what a space has
  concluded without writing a line of code.
</Tip>

## Create a model

```http theme={null}
POST /v1/spaces/{space_id}/models
Authorization: Bearer anona_live_YOUR_KEY
Content-Type: application/json
```

```json theme={null}
{
  "name": "Communication style",
  "query": "How does this user prefer to be communicated with?",
  "model_id": "comms",
  "tags": ["prefs"],
  "max_tokens": 2048,
  "trigger": { "mode": "delta", "refresh_on_new_memories": true }
}
```

| Field                             | Type              | Default   | Description                                                              |
| --------------------------------- | ----------------- | --------- | ------------------------------------------------------------------------ |
| `name`                            | string            | required  | Human-readable name.                                                     |
| `query`                           | string            | required  | The question this model answers from the space's memories.               |
| `model_id`                        | string            | generated | Optional stable id. Lowercase alphanumeric and hyphens.                  |
| `tags`                            | string\[]         | none      | Only build the model from memories carrying these tags.                  |
| `max_tokens`                      | integer           | 2048      | Ceiling on generated content length, 256 to 8192.                        |
| `trigger.mode`                    | `full` \| `delta` | `full`    | How a refresh rewrites the content. See [refresh modes](#refresh-modes). |
| `trigger.refresh_on_new_memories` | boolean           | `false`   | Refresh automatically once newly recorded memories are consolidated.     |
| `trigger.memory_type`             | string\[]         | all       | Restrict to `fact`, `experience` and/or `note`.                          |

**Response** `202 Accepted`

```json theme={null}
{ "model_id": "comms", "job_id": "job_9f2a", "status": "processing" }
```

## List models

```http theme={null}
GET /v1/spaces/{space_id}/models?limit=50&offset=0&tags=prefs
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `200 OK`

```json theme={null}
{
  "items": [
    {
      "id": "comms",
      "space_id": "customer-support-bot",
      "name": "Communication style",
      "query": "How does this user prefer to be communicated with?",
      "content": "Prefers short, direct answers. Has asked for brevity in several sessions and disengages past about three paragraphs.",
      "tags": ["prefs"],
      "max_tokens": 2048,
      "trigger": {
        "mode": "delta",
        "refresh_on_new_memories": true,
        "memory_type": null
      },
      "last_refreshed_at": "2026-08-01T10:00:00Z",
      "created_at": "2026-07-01T10:00:00Z",
      "is_stale": false
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
```

| Field               | Type            | Description                                                                                                                                                                            |
| ------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `content`           | string or null  | The current answer, as markdown. Null until the first refresh finishes, or after a clear. A model that has never been refreshed reports `null`, never a partial or placeholder answer. |
| `is_stale`          | boolean or null | True when memories have been recorded since the last refresh, so the content is behind.                                                                                                |
| `last_refreshed_at` | string or null  | ISO timestamp of the last rewrite.                                                                                                                                                     |

## Get a model

```http theme={null}
GET /v1/spaces/{space_id}/models/{model_id}
Authorization: Bearer anona_live_YOUR_KEY
```

Returns the same object as a list item.

## Update a model

Changes the definition. Existing content is left alone. Change the query and the answer
only catches up on the next refresh.

```http theme={null}
PATCH /v1/spaces/{space_id}/models/{model_id}
Authorization: Bearer anona_live_YOUR_KEY
```

```json theme={null}
{ "name": "Communication preferences", "max_tokens": 4096 }
```

**Response** `200 OK`, the updated model.

## Refresh a model

Re-answers the model's question from everything the space knows now.

```http theme={null}
POST /v1/spaces/{space_id}/models/{model_id}/refresh
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `202 Accepted`

```json theme={null}
{ "model_id": "comms", "job_id": "job_be71", "status": "queued" }
```

### Refresh modes

| Mode    | Behaviour                                                                                                                                                                                                                                     |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `full`  | Regenerates the content from scratch every time. Predictable, and the right default.                                                                                                                                                          |
| `delta` | Edits in place: untouched sections are preserved verbatim, stale parts are dropped, new material is added. Cheaper on long documents. A model with no content yet, or whose `query` changed, falls back to a full regeneration automatically. |

A `delta` model that has drifted over many incremental edits can be reset: clear it, then
refresh for a clean rebuild.

## Clear a model's content

Drops the content, keeps the definition.

```http theme={null}
POST /v1/spaces/{space_id}/models/{model_id}/clear
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `200 OK`, the model, with `content` now null.

## Delete a model

Removes the model. The memories it was built from are untouched.

```http theme={null}
DELETE /v1/spaces/{space_id}/models/{model_id}
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `204 No Content`

## Model history

Every refresh archives the content it replaced, most recent first, showing how the space's view
of the question changed as it learned more.

```http theme={null}
GET /v1/spaces/{space_id}/models/{model_id}/history
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `200 OK`

```json theme={null}
{
  "entries": [
    {
      "previous_content": "Prefers detailed explanations.",
      "changed_at": "2026-07-15T09:00:00Z"
    }
  ],
  "total": 1
}
```

## Space profile

The space's standing description: what it is for, and how it weighs what it is told.

```http theme={null}
GET /v1/spaces/{space_id}/profile
Authorization: Bearer anona_live_YOUR_KEY
```

**Response** `200 OK`

```json theme={null}
{
  "space_id": "customer-support-bot",
  "name": "Alice",
  "mission": "Keep Alice's team organized and shipping.",
  "disposition": { "skepticism": 3, "literalism": 4, "empathy": 5 }
}
```

| Field                    | Type    | Description                                         |
| ------------------------ | ------- | --------------------------------------------------- |
| `mission`                | string  | What this space is for. Empty if never set.         |
| `disposition.skepticism` | integer | 1 takes statements at face value, 5 questions them. |
| `disposition.literalism` | integer | 1 reads intent loosely, 5 reads literally.          |
| `disposition.empathy`    | integer | 1 ignores emotional context, 5 weighs it heavily.   |

Disposition shapes how the space interprets what it is told when it synthesizes. It does
not affect plain retrieval.

## Cost

Creating and refreshing a model each run a synthesis pass over the space's memories and
are billed like [reason](/api-reference/reason). Reading models, history and the profile
is free.

## Error responses

| Status | Code               | Cause                                           |
| ------ | ------------------ | ----------------------------------------------- |
| 401    | `unauthorized`     | Missing or invalid API key.                     |
| 403    | `forbidden`        | The space is not owned by your organization.    |
| 404    | `model_error`      | The space or model does not exist.              |
| 422    | `validation_error` | Unknown or malformed field in the request body. |
| 429    | `rate_limited`     | Credit quota or rate limit exceeded.            |

See the full [error reference](/api-reference/errors).

## Next steps

<CardGroup cols={2}>
  <Card title="Reason API" icon="lightbulb" href="/api-reference/reason">
    Answer a one-off question across memories.
  </Card>

  <Card title="MCP integration" icon="plug" href="/mcp-integration">
    Let an agent read a space's profile and models directly.
  </Card>
</CardGroup>
