# Read and delete memories

> List a library, read the text of a memory in parts, download the original file, and delete one memory or a whole end user.

Source: https://fryri.com/docs/api/read-and-delete-memories

`GET /v1/memories` lists the library, newest first, and `GET /v1/memories/{memory_id}` returns one memory with its status, text and original file. Both reads are free. `DELETE /v1/memories/{memory_id}` removes a memory from search and answers at once.

## List and read

An imported conversation has `type: "conversation"`. Its first read page includes `messages`, with the original `role`, `content` and `created_at` plus 1-based `turn`, `line_start` and `line_end`. Later pages continue the readable transcript through `text` and `next_cursor`. Notes and ordinary documents have `messages: null`. Deleting a conversation snapshot uses the same endpoint and removes the facts derived from that source.

**Request**

```bash
curl "https://api.fryri.com/v1/memories?end_user_id=user_42&limit=2" \
  -H "Authorization: Bearer $FRYRI_API_KEY"
```

**Response**

```json
{
  "memories": [
    {
      "id": "file_tjSa4DvE15aMARb4",
      "type": "document",
      "title": "Example Domain.html",
      "status": "ready",
      "status_reason": null,
      "created_at": "2026-09-25T09:03:01.562079Z",
      "source_ref": "https://example.com",
      "sha256": "ff67a9d764d6a2367a187734e697f6a53217db9a21c101d410a113ca871a299d"
    },
    {
      "id": "file_khWTQ9FQRD0vNdAx",
      "type": "text",
      "title": "Atlas budget",
      "status": "ready",
      "status_reason": null,
      "created_at": "2026-09-25T09:02:58.286297Z",
      "source_ref": null,
      "sha256": "c6a6c1b533130aa2c02bb580edb9263885ac229f1ebd7016e1a341885a908ee4"
    }
  ],
  "next_cursor": "eyJwIjp7ImkiOjQ1OSwiayI6..."
}
```

The list covers every note and document in the library, however it arrived. `limit` sets the page size. Default value is `20`. Range `[1, 100]`. Pass `next_cursor` back as `cursor` for the next page; it is `null` on the last page. `source_ref_prefix` lists only the memories whose `source_ref` starts with it, such as one folder or codebase. `sha256` is the SHA-256 of the content as it was added, for comparing with your own copy.

**Request**

```bash
curl "https://api.fryri.com/v1/memories/file_NkolfLrElMmM2fCn?end_user_id=user_42" \
  -H "Authorization: Bearer $FRYRI_API_KEY"
```

**Response**

```json
{
  "id": "file_NkolfLrElMmM2fCn",
  "type": "text",
  "title": "Project Atlas notes",
  "status": "ready",
  "status_reason": null,
  "created_at": "2026-09-25T09:02:54.915644Z",
  "source_ref": "crm:note:881",
  "sha256": "886d5886b41216cf0dc8e2234f4ffb24cb5666425200e5e2c5ee33d841b91be4",
  "summary": "A brief note about Project Atlas, which uses Python and FastAPI, with a launch review scheduled for 14 October.",
  "text": "Project Atlas uses Python and FastAPI. The launch review is on 14 October.",
  "lines": {
    "start": 1,
    "end": 1,
    "total": 1
  },
  "next_cursor": null,
  "download_url": "https://****.r2.cloudflarestorage.com/****/files/****/****.txt?response-content-type=text%2Fplain%3B%20charset%3Dutf-8&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=****%2F20260925%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260925T090639Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=****"
}
```

`status` is `processing` until search can find the memory, then `ready`. A `failed` memory carries a `status_reason` of `processing_failed`, `unsupported_format` or `reading_allowance_reached`. A memory that is still processing can carry `queued`: a memory added in the Fryri app waits for the daily document allowance. Memories added through the API never wait. A memory of an end user must be read with its `end_user_id`. Otherwise, the request fails with `404` `not_found`.

## Read long text in parts

`text` holds the text of the memory: a note as it was added, or the extracted text of a document. The text of a long document arrives in parts. `lines` says which lines a part holds (`start` and `end`, 1-based and inclusive, out of `total`), and `next_cursor` is set while more text follows. A search result's `location.line_start` counts the same lines.

**Complete example**

```python
import os

import requests

API = "https://api.fryri.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['FRYRI_API_KEY']}"}


def read_all(memory_id, **params):
    text, previous = "", None
    while True:
        # Send request
        response = requests.get(f"{API}/memories/{memory_id}", headers=HEADERS, params=params)
        response.raise_for_status()
        # Read response
        page = response.json()
        lines = page["lines"]
        if previous is not None:
            # A part that starts on the line where the last part stopped continues that line.
            text += "" if lines and lines["start"] == previous["end"] else "\n"
        text += page["text"] or ""
        if not page["next_cursor"]:
            return text
        previous, params["cursor"] = lines, page["next_cursor"]


print(read_all("file_NkolfLrElMmM2fCn", end_user_id="user_42"))
```

A cursor from another memory, or from an earlier version of its text, fails with `422` `invalid_cursor`.

## Download the original

`download_url` links to the original file for 5 minutes. Each read returns a fresh link, and `download_url` is `null` when no original file is available.

## Delete

**Request**

```bash
curl -X DELETE "https://api.fryri.com/v1/memories/file_khWTQ9FQRD0vNdAx?end_user_id=user_42" \
  -H "Authorization: Bearer $FRYRI_API_KEY"
```

**Response**

```json
{
  "id": "file_khWTQ9FQRD0vNdAx",
  "deleted": true
}
```

A deleted memory stops appearing in search and answers at once, together with anything learned from it. A memory of an end user must be deleted with its `end_user_id`. Otherwise, the request fails with `404` `not_found`. A second delete of the same memory also fails with `404`.

`DELETE /v1/end-users/{end_user_id}` erases everything stored for one end user in one call. See [Manage your users](/docs/api/give-your-app-memory#manage-your-users).

## Best Practices

**Reading**

- Store the memory `id` next to your own record, so a later read or delete needs no search.
- Poll `GET /v1/memories/{memory_id}` every few seconds after an add, and stop at `ready` or `failed`.
- Follow `next_cursor` until it is `null` to read a long document in full.

**Deleting**

- Delete with the same `end_user_id` the memory was added with.
- Treat a `404` on a repeated delete as done: the memory is already gone.
- Call `DELETE /v1/end-users/{end_user_id}` from your own account-deletion flow.

> **Tip:** A short note arrives in one part, so its first read returns `next_cursor` as `null`.

> **Warning:** `download_url` stops working after 5 minutes. Read the memory again for a fresh link.
