# Contacts and conversations

The people a business talks to and its conversations with them - kept by PaalChat, read and worked through the API.

> **In a nutshell:** PaalChat keeps a contact for everyone a business messages or hears from, and one conversation per business number and contact. Read them, add your own ids, fields and tags, work conversations (status, priority, tags, read, notes), and listen for contact.* and conversation.* events.

## What PaalChat keeps

- **Contacts** - created automatically by the first message in or out (named from
  the person's WhatsApp profile), or by you. Each has its **identities** (how it is
  reached: WhatsApp number today), your own `external_id`, the business's **custom
  fields** and **tags**.
- **Conversations** - one per business number and contact. Every message, in and out,
  belongs to one (`conversation_id` on messages and their callbacks).
- **Message content** - what was said, encrypted, for the conversation history
  ([how long](/docs/faq)).

## How messages join conversations

```text
 customer writes ──▶ open ──(you resolve)──▶ resolved ──(customer writes)──▶ open
 you write first ──▶ pending ──(customer replies)──▶ open
 closed ──(next message)──▶ a new conversation
```

- An incoming message joins the current conversation on that number, **reopening** it
  if it was pending, resolved or snoozed, and adds to `unread_count`.
- A send joins the current conversation, or starts a **pending** one - so a broadcast
  does not fill your inbox with open conversations.
- `window_open` says whether free-form text is allowed (the contact wrote in the last
  24 hours to that number).

## Link contacts to your records

```bash
curl -X POST https://whatsapp.paaltech.org/api/v1/businesses/presec/contacts \
  -H "Authorization: Bearer $PAALCHAT_TOKEN" -H "Content-Type: application/json" \
  -d '{"external_id": "parent-77", "phone": "+233241234567", "name": "Ama Mensah", "tags": ["parent"]}'
```

The contact is matched by `external_id`, else by `phone`, else created. Define the
business's own fields first ([Define a contact field](/docs/api/define-contact-field)),
then set them with `custom_fields`.

## Work a conversation

- [Update conversation](/docs/api/update-conversation): `status`, `priority`, `tags`,
  and `read: true` once your staff have seen it.
- [Add note](/docs/api/add-conversation-note): an internal note - never sent to the
  contact.
- [List conversation messages](/docs/api/list-conversation-messages): the history,
  with each message's `content`.

## Events

| Event | When |
|---|---|
| [`contact.created`](/docs/api/callbacks/contact-created) | A contact's first message in or out, or you created it |
| [`contact.updated`](/docs/api/callbacks/contact-updated) | Its details, fields or tags changed |
| [`conversation.created`](/docs/api/callbacks/conversation-created) | A conversation started |
| [`conversation.updated`](/docs/api/callbacks/conversation-updated) | Status, priority, tags or assignee changed, or the contact reopened it |

New messages alone arrive as `message.received` / `message.status`, not as
`conversation.updated`.
