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

# Conversation and thread

> Read a conversation's state and its thread of messages and events

<Info>
  **Endpoint** · `GET /conversation` (detail) and `GET /conversation/messages` (thread)
</Info>

<Note>
  **Read-only** endpoints: they return information and change nothing. They are not sent inside the `actions` array — you call them directly.
</Note>

These are the two reads that give you context before operating on a conversation. `GET /conversation` answers what state it is in (24h window, mailbox, AI employee, labels) and who the contact is; `GET /conversation/messages` answers what was said, in what order, and by whom. The first one tells you **which action is valid** (for example, with the window closed you can only send a template); the second one lets you write the reply with the history in front of you.

Both identify the conversation with the same reference as the rest of the API, but passed as **query params** instead of in the body: exactly one of `phone`, `username`, `whatsapp_user_id`, or `uuid`, plus `channel`.

## Conversation detail

```http theme={null}
GET /conversation
```

**Parameters**

* `phone` — phone number in E.164 format. Normalized to digits before the lookup.
* `username` — the contact's public WhatsApp username. Normalized (leading `@` stripped, case ignored).
* `whatsapp_user_id` — the contact's BSUID (Meta's opaque identity). Exact match, no normalization.
* `uuid` — 1TO1 AI internal UUID, if you already have it stored.
* `channel` — the channel's public key (**required** on every request). List them with `GET /channels`. Case-insensitive. It pins the target channel; on the contact-based paths it restricts resolution to that channel, and with `uuid` the resolver ignores it but the contract still requires it.

Exactly **one** of `phone`, `username`, `whatsapp_user_id`, or `uuid` must be present: zero or two identifiers return `400` (`INVALID_REQUEST`).

### Response

```json theme={null}
{
  "conversation_info": {
    "phone": "5215512345678",
    "window_open": true,
    "window_expires_at": "2026-07-21T18:30:00Z",
    "inbox_status": "pending",
    "is_tester": false,
    "mailbox": { "name": "Ventas" },
    "ai_employee": { "name": "Aura" },
    "tags": [{ "name": "VIP" }]
  },
  "contact_info": {
    "first_name": "Juan",
    "middle_name": "Carlos",
    "last_name": "Pérez",
    "second_last_name": "López",
    "full_name": "Juan Carlos Pérez López",
    "username": "juanp",
    "phone": "5215512345678",
    "whatsapp_user_id": "5215512345678"
  }
}
```

`window_open` is the field that decides what you can send: when it is `false`, the only allowed message is an approved template. `window_expires_at` is `null` when the contact never wrote (the window never opened), and `inbox_status` is `pending` or `resolved`. `mailbox` and `ai_employee` are `null` when the conversation has no mailbox or AI employee assigned. `is_tester` flags whether the conversation was created from the testing module.

<Note>
  In `contact_info`, `whatsapp_user_id` returns the real BSUID when one exists, falling back to the phone number until Meta migrates. If the value you get back is the phone number, send it as `phone` and not as `whatsapp_user_id` — the resolver matches BSUIDs by exact equality and would return `404`.
</Note>

**Errors**

* `400` `INVALID_REQUEST` — the reference carries zero or two identifiers, or `channel` is missing.
* `404` `CONVERSATION_NOT_FOUND` — the conversation does not exist or belongs to another business. `CHANNEL_NOT_FOUND` — the channel key does not exist.
* `409` `PHONE_NUMBER_AMBIGUOUS` / `USERNAME_AMBIGUOUS` — several contacts share that phone number or username. Identify by `whatsapp_user_id` or `uuid`.

### Example

A pure read: it reports the state and changes nothing in the conversation.

```bash theme={null}
curl -X GET "https://app.1to1.ai/api/v1/public/{slug}/conversation?phone=5215512345678&channel=ch_7A9K2M4Q" \
  -H "Authorization: Bearer sk_1to1_your_api_key"
```

If the response has `"window_open": false`, the right action is to send a template; if it has `true`, you can send text, media, or a quick reply.

## Thread of messages and events

```http theme={null}
GET /conversation/messages
```

Returns the conversation's messages and history events. It is identified with the same reference, so **you do not need to know any uuid**.

**Parameters**

* `phone` / `username` / `whatsapp_user_id` / `uuid` — the conversation reference, same rule: exactly one.
* `channel` — the channel's public key (**required**).
* `cursor` — opaque cursor returned by the previous page in `next_cursor` (up to 512 characters). Do not reuse cursors across different endpoints.
* `limit` — items per page. Defaults to 50, maximum 100.

<Note>
  The thread paginates **backwards in time**: the first call returns the most recent items and `next_cursor` moves towards the oldest ones. `has_more` set to `true` means there are **older** items left to read. Items within a page are in chronological order and that order is not configurable (there is no `order` parameter).
</Note>

### Response

```json theme={null}
{
  "items": [
    {
      "type": "message",
      "direction": "contact",
      "event": "message_received",
      "content_type": "text",
      "body": "Hi, is the premium package available?",
      "author": { "type": "customer", "name": "Ana Pérez" },
      "status": "delivered",
      "sent_at": "2026-07-02T14:39:00.000Z"
    },
    {
      "type": "message",
      "direction": "business",
      "event": "message_sent",
      "content_type": "text",
      "body": "Good morning! Yes, the premium package is available.",
      "author": { "type": "ai_employee", "name": "Night Sales" },
      "status": "read",
      "sent_at": "2026-07-02T14:39:12.000Z"
    },
    {
      "type": "event",
      "direction": "business",
      "event": "context_note",
      "content_type": null,
      "body": "Customer asked for a formal quote by email.",
      "author": { "type": "api_token", "name": "CRM integration" },
      "status": null,
      "sent_at": "2026-07-02T15:02:00.000Z"
    }
  ],
  "next_cursor": "MjAyNi0wNy0wMlQxNDozOTowMC4wMDBafDkxODIz",
  "has_more": true
}
```

Every item answers four questions: who spoke (`direction` and `author`), what happened (`event`), with what content (`content_type` and `body`), and when (`sent_at`).

* `type` — `message` or `event`. It discriminates the union: auto-generated SDKs expose it as a tagged union.
* `direction` — `contact` (sent by the person on the other side) or `business` (it came from your business).
* `author.type` — `customer`, `human`, `ai_employee`, `api_token`, `mass_campaign`, or `system`. `author.name` can be `null`.
* `event` — on `message` items: `message_received` or `message_sent`. On `event` items: `context_note`, `contact_name_updated`, `contact_phone_updated`, `contact_email_updated`, `scheduled_cancel`, or `conversion`.
* `content_type` — on `message` items: `text`, `image`, `audio`, `video`, `document`, `location`, `sticker`, `contacts`, `template`, `interactive`, or `reaction`. Always `null` on `event` items.
* `status` — on `message` items: `pending`, `sent`, `delivered`, `read`, or `failed`. Always `null` on `event` items.
* `sent_at` — the item's business clock and the thread's sort key. Always present.

**Errors**

* `400` `INVALID_REQUEST` — invalid reference. `INVALID_CURSOR` — corrupted cursor or one not issued by this endpoint.
* `404` `CONVERSATION_NOT_FOUND` / `CHANNEL_NOT_FOUND`.
* `409` `PHONE_NUMBER_AMBIGUOUS` / `USERNAME_AMBIGUOUS`.

### Example

Also a read: paging through the whole thread does not alter the conversation nor mark anything as read.

```bash theme={null}
curl -X GET "https://app.1to1.ai/api/v1/public/{slug}/conversation/messages?phone=5215512345678&channel=ch_7A9K2M4Q&limit=50" \
  -H "Authorization: Bearer sk_1to1_your_api_key"
```

Next page (older items), using the `next_cursor` from the previous response:

```bash theme={null}
curl -X GET "https://app.1to1.ai/api/v1/public/{slug}/conversation/messages?phone=5215512345678&channel=ch_7A9K2M4Q&cursor=MjAyNi0wNy0wMlQxNDozOTowMC4wMDBafDkxODIz" \
  -H "Authorization: Bearer sk_1to1_your_api_key"
```

With the state and the history in hand, writing goes through the actions: [Send message](/en/action-groups/send-message) to reply and [Change conversation state](/en/action-groups/conversation-status) to mark it resolved or pending. The full context on the reference and the 24h window lives in [Conversations](/en/conversations).
