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

# Identity

> How Kai decides which contact a write belongs to.

Kai matches a write to a contact by identity. An identity is one handle that
belongs to one person. A contact can hold many.

## The four kinds

| Kind       | Example                       | Who writes it         |
| ---------- | ----------------------------- | --------------------- |
| `external` | `DK-1042`                     | you, as `external_id` |
| `email`    | `ayse@example.com`            | you, as `email`       |
| `phone`    | `905321112233`                | you, as `phone`       |
| `channel`  | `whatsapp_cloud:905321112233` | the messaging channel |

`external_id`, `email` and `phone` become identities on their own. You do not
need the `identities` array for them. Use that array for a channel handle, or
for a second email address.

## Normalization

Kai stores an identity in one form, and matches on that form:

* an email address becomes lowercase;
* a phone number keeps its digits only, and loses a `00` prefix;
* an `external` value and a `channel` value keep their case, because they
  belong to another system.

Three spellings of the same number are therefore one identity:

| You send             | Kai stores     |
| -------------------- | -------------- |
| `+90 532 111 22 33`  | `905321112233` |
| `0090 532 111 22 33` | `905321112233` |
| `905321112233`       | `905321112233` |

This is why a WhatsApp conversation and a contact from your CRM meet on the
same record.

## Match order

Kai reads the identities in the request and finds the contacts that hold them:

1. no contact holds any of them: Kai creates a contact, and gives it every
   identity in the request;
2. one contact holds one or more of them: Kai updates that contact, and adds
   the identities that it does not hold yet;
3. two contacts hold them: Kai refuses the write.

## Conflicts

The third case returns 409 and names the identities:

```json theme={null}
{
  "error": {
    "type": "identity_conflict",
    "message": "Those identifiers already belong to two different contacts. Kai does not merge contacts automatically.",
    "details": [
      { "kind": "email", "value": "ayse@example.com" },
      { "kind": "phone", "value": "905321112233" }
    ]
  }
}
```

Kai does not merge the two contacts. A merge cannot be undone, and a wrong
merge puts the history of one customer in front of another. Correct the
conflict in Kai, under **Contacts**, or write to each contact by its Kai id.

## Send at least one identity

`POST /contacts` refuses a request that carries no identity. Without one, Kai
has nothing to match on, and a job that runs twice would make a second copy of
every person.
