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

# Conversations

> How a conversation is identified and why the 24h window decides what you can send.

A conversation is the WhatsApp thread between your business and a contact.
Almost every send and action endpoint (`/conversation/*`) takes it in the
request body under the `conversation` object.

## Identifying a conversation

The `conversation` object accepts **one** of four identifiers. The resolver
evaluates them in this order: `uuid` → `whatsapp_user_id` → `username` →
`phone`: `whatsapp_user_id` looks up by exact match and `username` by a
case-insensitive match (case is ignored); `phone` is normalized to digits.
When the contact has a BSUID, `phone` and
`whatsapp_user_id` identify different values (see Note).

<ParamField body="uuid" type="string">
  The UUID from a `GET /conversations`. The most direct and stable path (it can
  become stale if two conversations of the same contact are merged — see the merge
  note below).
</ParamField>

<ParamField body="whatsapp_user_id" type="string">
  The contact's BSUID (Meta's opaque identity). Resolves by exact match against
  the stored BSUID; if it does not resolve, the endpoint returns `404` without
  falling back to `phone`. Recommended identifier going forward.
</ParamField>

<ParamField body="username" type="string">
  The contact's public WhatsApp username, with or without a leading `@` and
  case-insensitive. Best-effort resolution against the last username observed by
  the platform (users can change their handle); if several contacts share it,
  the endpoint returns `409` (`USERNAME_AMBIGUOUS`).
</ParamField>

<ParamField body="phone" type="string">
  Number in E.164 format (`+5215512345678`). Normalized to digits before the
  lookup. Useful when all you have is the phone.
</ParamField>

```jsonc theme={null}
{ "conversation": { "phone": "+52 55 1234 5678" } }
// equivalent: { "conversation": { "uuid": "7b8a..." } }
```

<Warning>
  The phone number can be **duplicated** across contacts (recycled numbers or
  separate identities sharing a number): in that case the API returns `409`
  (`PHONE_NUMBER_AMBIGUOUS`) instead of guessing — identify the conversation by
  `whatsapp_user_id` or `uuid`. Also, `whatsapp_user_id` can **change** if the
  user re-registers their WhatsApp account (identity rotation on Meta's side).
  Use the `uuid` as the stable key in your system and `whatsapp_user_id` as the
  preferred resolution identifier.
</Warning>

<Note>
  `phone` and `whatsapp_user_id` are **different** identifiers: `phone` is the
  phone number (wa\_id without `+`) and `whatsapp_user_id` is the contact's BSUID.
  They coincide only while the contact has no BSUID. In responses,
  `whatsapp_user_id` returns the real BSUID when present, with a fallback to the
  phone so there is always a resolvable value. Watch the round-trip: if the contact
  has no BSUID yet, this field carries the phone; re-send it as `phone` then, not as
  `whatsapp_user_id` — the resolver matches `whatsapp_user_id` by exact match and
  would return `404`.
</Note>

<Note>
  When the same contact ended up recorded twice by identity (for example, first only
  with their phone and later with their BSUID), the two conversations are
  **merged automatically** into one: the full history moves to the survivor. The
  absorbed conversation's `uuid` stops resolving and returns `404`; the phone and the
  BSUID migrate to the survivor. If a `uuid` you stored starts returning `404`,
  re-resolve the conversation by `phone` or `whatsapp_user_id`.
</Note>

## The 24h window

This is WhatsApp's core concept and it decides what you can send.

<Steps>
  <Step title="The contact messages you">
    WhatsApp opens a **24-hour window**. Each new message from the contact
    resets the timer.
  </Step>

  <Step title="Window open">
    You can send free-form messages: text, media, and quick replies.
  </Step>

  <Step title="24h pass with no reply">
    The window closes. The only allowed message is a **template** approved by
    Meta.
  </Step>

  <Step title="Sending a template reopens the window">
    You can send free-form messages again.
  </Step>
</Steps>

<Warning>
  Sending text, media, or a quick reply with the window closed fails with
  `WINDOW_CLOSED` (422). Send a template first to reopen it.
</Warning>

## Checking the window status

Before sending a free-form message, you can verify whether the window is open
with `POST /conversation/status`:

```bash theme={null}
curl -X POST "https://app.1to1.ai/api/v1/public/{slug}/conversation/status" \
  -H "Authorization: Bearer sk_1to1_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "conversation": { "phone": "+5215512345678" } }'
```

The response includes `window.status` (`open` or `closed`) and
`window.hours_remaining`, plus the assignment, mailbox, tags, and
`inbox_status` of the conversation. Use it to decide between a free-form
message and a template.

## Next steps

<CardGroup cols={2}>
  <Card title="Send messages" icon="paper-plane" href="/en/messages">
    Text, media, quick replies, and templates.
  </Card>

  <Card title="Templates" icon="newspaper" href="/en/templates">
    How to send templates when the 24h window is closed.
  </Card>
</CardGroup>
