# Learn Memories from a Transcript

URL: https://docs.clinia.com/docs/learned-memory/learn-from-a-transcript

> Send the transcripts of conversations that already happened, so the Context Engine learns memories from them.

Send the transcripts of conversations that already happened, which your application may call chats, to store them as [sessions](https://docs.clinia.com/docs/learned-memory/sessions) against a patient and learn [memories](https://docs.clinia.com/docs/learned-memory/overview) from them. A memory is attributed to the person who said it, as described in [Attribution](https://docs.clinia.com/docs/get-started/how-the-engine-thinks-about-data#attribution), so it stays apart from the facts formed from systems of record. To record a conversation turn by turn as it happens, see [Manage a Session](https://docs.clinia.com/docs/learned-memory/manage-a-session).

## Make the request [#make-the-request]

Post one or more transcripts as JSON. Each carries its messages in chronological order, authored by `user` or `assistant`:

```bash
curl -X POST "https://<workspace-id>.w.clinia.cloud/v1/patients/{patientId}/ingestions/sessions" \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "sessions": [
      {
        "sessionId": "chat-2026-09-10",
        "messages": [
          { "role": "user", "content": "I have been getting headaches most mornings." },
          { "role": "assistant", "content": "How long has that been going on?" },
          { "role": "user", "content": "About two weeks, since I stopped my lisinopril." }
        ]
      }
    ]
  }'
```

A successful call answers `202` with a receipt:

```json
{
  "ingestionId": "c1m2k3n4p5q6r7s8t9u0v1w2",
  "source": "session/v1",
  "mimeType": "application/json",
  "receivedAt": "2026-09-10T14:22:31.004Z",
  "status": "pending",
  "staged": { "facts": 0, "events": 0, "narratives": 0, "messages": 3 },
  "intake": [
    {
      "unit": "message",
      "received": 3,
      "entries": [
        { "kind": "user", "count": 2, "outcome": "text_only" },
        { "kind": "assistant", "count": 1, "outcome": "text_only" }
      ],
      "sessionId": "chat-2026-09-10"
    }
  ],
  "startedAt": null,
  "completedAt": null,
  "failure": null
}
```

Memories are formed after the response, as the submission is processed.

`staged.messages` counts the messages this submission stored. A conversation contributes no facts, events or narratives of its own, so the other staged counts stay `0`.

## Choose the session id [#choose-the-session-id]

`sessionId` is optional.

- Declare a `sessionId` when your application already has an id for the conversation. The messages are stored under that session, which is created if it does not exist yet, including one you have already been appending to. The id must match the pattern in the [API reference](https://docs.clinia.com/api/rest/post-patients-patientId-ingestions-sessions).
- Omit it to store the transcript as a new session under a generated id. Every `intake` item carries the `sessionId` its transcript was stored under, so the generated id comes back on the receipt.

A transcript without a `sessionId` always opens a new session, so resending one stores it twice. Declare the id whenever you might send the same conversation again, or reuse the one the receipt returned.

## Several transcripts in one call [#several-transcripts-in-one-call]

Send every transcript in `sessions`. One call is one submission with one receipt, whatever the number of transcripts. `intake` comes back index-aligned with the transcripts you sent. Each transcript is its own session, so a `sessionId` may appear only once per request.

If any transcript is refused, the whole request is rejected and nothing is stored.

## Continue a session [#continue-a-session]

Resend the conversation under the same `sessionId`, with new turns added at the end. Messages already stored are recognised and not stored again, so only the new turns count toward `staged.messages`. A re-send with nothing new reports `0`. You can send the whole conversation each time, or only what is new. Send the whole conversation when a new turn may repeat an earlier one word for word, such as a second "yes". A turn is only told apart from an identical earlier turn within the same submission, so a repeated turn sent on its own reads as the turn already stored.

A transcript that edits, removes or reorders turns already stored is refused, because the session would no longer match the conversation it records. Send a different history as a new session instead.

## Error responses [#error-responses]

Requests are validated before the response, so a refused request stages nothing.

| Status | Cause                                                                                                                                 |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The body is malformed: no transcripts, a transcript with no messages, an empty message, or a role other than `user` or `assistant`    |
| `400`  | A `sessionId` repeats within the request, or does not match the allowed pattern. The message names the transcript                     |
| `400`  | A transcript does not continue the stored conversation of the session it names (`FAILED_PRECONDITION`). The message names the session |
| `404`  | No such patient                                                                                                                       |

## Follow the submission [#follow-the-submission]

Poll the receipt until it settles, as described in [Track an Ingestion](https://docs.clinia.com/docs/recorded-memory/track-an-ingestion). For a conversation, `partial` means its memories are stored but some of their links to the patient's record could not be made.

Once it settles, read what the conversation produced as described in [Read Memories and Their Links to Facts](https://docs.clinia.com/docs/learned-memory/read-memories).
