---
title: "Conversations and end users"
description: "Keep a conversation through an API key with conversation_id, name the people who use your product with end_user, keep nothing with store false, and know how long Lookio keeps it."
canonical: "https://lookio.app/docs/platform/conversations-and-end-users"
updated: "2026-11-03"
---

# Conversations and end users

Every answer you get through an API key, the CLI or the MCP server is kept in a conversation. Ask the next question with the previous answer's `conversation_id` and Lookio reads the history itself: you send only the new question.

This page is for products that put an assistant in front of their own users. A person's chats in the app are a different thing: they are personal. See [Chat](/docs/platform/chat).

## Continue a conversation

The first answer returns two ids. `conversation_id` continues the conversation. `message_id` is the answer's own id, the one you need to [forward a thumb](/docs/platform/answer-feedback).

```bash title="curl"
# First question
curl https://api.lookio.app/v1/assistants/ASSISTANT_ID/query \
  -H "Authorization: Bearer $LOOKIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "How much does the Pro plan cost?", "end_user": "user_42"}'

# The answer has "conversation_id": "CONVERSATION_ID" and "message_id": "MESSAGE_ID".
# Follow-up: only the new question.
curl https://api.lookio.app/v1/assistants/ASSISTANT_ID/query \
  -H "Authorization: Bearer $LOOKIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "And for the annual plan?", "conversation_id": "CONVERSATION_ID", "end_user": "user_42"}'
```

```ts title="SDK"
const first = await lookio.assistants.ask("ASSISTANT_ID", {
  question: "How much does the Pro plan cost?",
  end_user: "user_42",
});
const followUp = await lookio.assistants.ask("ASSISTANT_ID", {
  question: "And for the annual plan?",
  conversationId: first.conversation_id!,
  end_user: "user_42",
});
```

```bash title="CLI"
lookio ask ASSISTANT_ID "How much does the Pro plan cost?" --end-user user_42
lookio ask ASSISTANT_ID "And for the annual plan?" --conversation CONVERSATION_ID --end-user user_42
```

The MCP tool `ask_assistant` takes the same `conversation_id`, `end_user` and `store`. The streamed answer returns both ids in its `done` event: see [Streaming](/docs/api/streaming).

A conversation:

- belongs to the API key that started it. Another key, even in the same workspace, gets `resource_not_found`.
- stays with one assistant. Asking another assistant with that `conversation_id` gets `resource_not_found`.
- uses the last six turns as context, the same as a chat in the app.

## Two ways to keep a conversation

|                         | `conversation_id` (Lookio keeps it)       | `history` (you keep it)                                                                |
| ----------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------- |
| **You send**            | The new question and the id.              | The new question and the previous turns, oldest first (up to 20, the last 6 are used). |
| **Memory**              | Read server-side from what Lookio stored. | Whatever you send. Lookio trusts it as written.                                        |
| **Stored by Lookio**    | Yes, 90 days.                             | Yes, unless you also send `store: false`: the answer starts a new stored conversation. |
| **Visible in the logs** | Yes.                                      | Yes, unless `store: false`.                                                            |
| **Use it when**         | You want the simplest follow-up.          | You already store the conversation, or you want nothing kept at Lookio.                |

Sending both `conversation_id` and `history` fails with `invalid_request`.

## Name the people who use your product with end\_user

`end_user` is your own id for the person asking, such as a user id of your product. It is optional.

- It is 1 to 200 characters: letters, digits and `. _ @ : + -`. Anything else fails with `invalid_parameter`.
- **Prefer an opaque id** such as `user_42` to an email address. The id appears in your workspace's [logs](/docs/platform/logs).
- It groups that person's conversations. List them with `GET /v1/conversations?end_user=user_42`.
- **It binds the conversation.** A conversation started with `end_user: "user_42"` can only be continued, read, renamed, deleted or rated by a call that sends the same `end_user`. Another one gets `resource_not_found`. Your backend can rely on this to stop one of your users from opening another's conversation, even if an id leaks.
- A conversation started without `end_user` is reached only by calls that send none, and a call that sends `end_user` reaches only that person's conversations. Pick one habit for a product and keep it.

`end_user` and `store` are for API keys. A person's connection that sends them gets `invalid_parameter`, rather than having them silently ignored.

## Keep nothing with store false

Send `store: false` for a question that must not be kept. Nothing is written: no conversation, no entry in the logs, and `conversation_id` and `message_id` come back `null`. You are charged the same, and the answer cannot be continued with `conversation_id`. Bring the previous turns yourself in `history` if you need a follow-up.

`store: false` cannot be combined with `conversation_id`: a conversation you want to continue is a conversation you keep.

## How long it is kept

Lookio deletes a conversation 90 days after its last message. A new message restarts that clock. You can delete one earlier with `DELETE /v1/conversations/{conversation_id}`, which also removes it from the workspace's logs and figures: nobody can read it afterwards. To honour a user's request to erase their data, list their conversations with `end_user` and delete each one.

Who can read a kept conversation:

- you, with the API key that started it (the endpoints below);
- the people of the workspace who may [read the logs](/docs/platform/logs).

Members' own chats are never in the logs.

## Read and tidy your key's conversations

| What                                      | Endpoint                                                                     | CLI                                    | SDK                      |
| ----------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------- | ------------------------ |
| List, optionally of one `end_user`        | [List conversations](/docs/api/conversations/list-conversations)             | `lookio conversations list --end-user` | `conversations.list`     |
| Read one with its messages and answer ids | [Get a conversation](/docs/api/conversations/get-conversation)               | `lookio conversations get`             | `conversations.get`      |
| Rename                                    | [Rename a conversation](/docs/api/conversations/rename-conversation)         | `lookio conversations rename`          | `conversations.rename`   |
| Delete                                    | [Delete a conversation](/docs/api/conversations/delete-conversation)         | `lookio conversations delete`          | `conversations.delete`   |
| Forward a thumb                           | [Send feedback on an answer](/docs/api/conversations/submit-answer-feedback) | `lookio conversations feedback`        | `conversations.feedback` |

Each row has an MCP tool with the same job: see [Standard tools](/docs/mcp/standard-tools#conversations). Every conversation has a `channel`: `api` for a key through REST, the CLI or the SDK, `mcp` for a key through the MCP server, and `personal` for a person's own chat. A key lists only its own.

## Errors you may meet

| Error                                     | Meaning                                                                                                                      |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `resource_not_found` on `conversation_id` | The conversation does not exist, belongs to another key, another assistant or another `end_user`, or was deleted or expired. |
| `invalid_request`                         | `conversation_id` with `history`, or `conversation_id` with `store: false`.                                                  |
| `invalid_parameter` on `end_user`         | Not 1 to 200 characters of letters, digits and `. _ @ : + -`, or sent by a person's connection.                              |
| `invalid_parameter` on `store`            | `store` sent by a person's connection. A person's chats are always kept.                                                     |
