Ingest Sessions
POST one or several conversation transcripts as a single submission, continue a session by resending it, and poll the receipt.
Send conversation transcripts — what your application would call chats — to store them as sessions against a patient. The patient's memories are formed from them as the submission is processed. Use this to import conversations that already happened; to record one turn by turn as it happens, see Manage a Session.
Make the request
Post one or more transcripts as JSON. Each carries its messages in chronological order, authored by user or assistant:
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:
{
"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
}202 means accepted, not finished. Memories are formed after the response returns, so poll ingestionId to follow the work. See Ingestion for what happens between acceptance and a settled submission.
staged.messages counts the messages this submission stored. A conversation contributes no facts, events or narratives of its own, so those counts stay 0. intake reports each transcript's messages by author, at text_only: a message is kept as the text it is rather than decomposed into structured facts.
Choose the session id
sessionId is optional:
- Declare it when your application already has an id for the conversation. The messages are stored under that session, 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.
- Omit it to store the transcript as a new session under a generated id. Every
intakeitem carries thesessionIdits 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
Send every transcript in sessions. One call is one submission and one receipt, whatever the count, and 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.
All or nothing. If any transcript is refused, the whole request is rejected and nothing is stored.
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 told apart from an identical earlier one only within the same submission, so sent on its own it 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
Validation is synchronous: 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
Poll the receipt until it settles:
curl "https://<workspace-id>.w.clinia.cloud/v1/patients/{patientId}/ingestions/{ingestionId}" \
-H "Authorization: Bearer <access-token>"Stop once status is succeeded, partial or failed — see What partial means for every value. 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 with GET …/sessions/{sessionId}/memories.