# Контакты

Контакт — это человек, который пишет боту в мессенджере или в чате на сайте. Методы этой страницы выгружают контакты ваших ботов — например, чтобы перенести их в CRM, — считают их и создают контакт из своей системы, если человек уже известен вам по ID в мессенджере. О контактах в кабинете — в разделе [Контакты](https://support.watbot.ru/chatbots/contacts).

Выгрузку можно листать двумя способами: по страницам (`page` и `count`, до 500 контактов за запрос) или сдвигом от начала (`offset` и `limit`, до 1000 контактов за запрос). Сколько контактов под условия, скажет `getNumberOfContacts`.

Методы возвращают контакты только ваших ботов. Контакты, которые появились при проверке бота в предпросмотре, в выгрузку и подсчёт не попадают.

## Поля контакта

Все методы со списком контактов — здесь и на странице [Рефералы](https://support.watbot.ru/api/referrals) — отдают контакт в одном виде.

| Поле | Тип | Описание |
|---|---|---|
| `id` | число | ID контакта |
| `bot_id` | число | ID бота |
| `phone` | строка или `null` | Номер телефона, если контакт им поделился или номер задан через API |
| `email` | строка или `null` | Email |
| `name` | строка | Имя |
| `address` | строка или `null` | Адрес |
| `messenger` | строка | Откуда контакт: `telegram`, `max`, `viber`, `vk` или `web` (чат на сайте) |
| `utm` | объект | Переменные контакта, имя которых начинается с `utm_`: `{"utm_source": "…"}`. Если таких нет — пустой массив `[]` |
| `avatar` | строка или `null` | Ссылка на фото контакта. Ссылка на файл в хранилище временная — сохраняйте сам файл, а не ссылку |
| `telegram_id` | строка | ID пользователя в Telegram. Только у контактов Telegram |
| `telegram_username` | строка или `null` | Username в Telegram без `@`. Только у контактов Telegram |
| `max_user_id` | число | ID пользователя в MAX. Только у контактов MAX |
| `max_username` | строка или `null` | Username в MAX. Только у контактов MAX |
| `vk_user_id` | число или `null` | ID пользователя ВКонтакте. Есть у всех контактов, у не-ВКонтакте — `null` |
| `viber_id` | строка | ID пользователя в Viber. Только у контактов Viber |
| `created_at` | строка | Когда контакт появился, ISO 8601 в UTC |
| `unsubscribed_at` | строка или `null` | Когда контакт отписался от бота; `null` — подписан |
| `tags` | массив строк | Теги контакта |
| `variables` | массив объектов | Переменные контакта |

Каждая переменная в `variables` — объект:

| Поле | Описание |
|---|---|
| `id` | ID переменной у контакта |
| `name` | Имя переменной |
| `value` | Значение |
| `type` | Что в значении: `0` — текст, `1` — картинка, `2` — документ, `3` — аудио, `4` — видео. У медиа в `value` ссылка на файл — её раскрывает метод [decodeShortLink](https://support.watbot.ru/api/links) |
| `schema_id`, `deletable`, `payload` | Служебные поля |

О тегах и переменных в кабинете — на странице [Теги и переменные](https://support.watbot.ru/chatbots/contacts/tags-variables).

## getContacts

Возвращает контакты ваших ботов — по страницам (по умолчанию 20 на странице) или сдвигом от начала.

```endpoint
GET POST https://watbot.ru/api/v1/getContacts
```

| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| `bot_id` | число | нет | Только контакты этого бота. Без параметра — контакты всех ваших ботов |
| `count` | число | нет | Контактов на странице: от 1 до 500. По умолчанию 20 |
| `page` | число | нет | Номер страницы, с 1. По умолчанию 1 |
| `offset` | число | нет | Сколько контактов пропустить от начала, с 0. Включает выгрузку сдвигом |
| `limit` | число | нет | Сколько контактов вернуть при выгрузке сдвигом: от 1 до 1000. По умолчанию 100. Тоже включает выгрузку сдвигом |
| `date_from` | число | нет | Контакты, появившиеся не раньше этого момента. Unix-время в секундах |
| `date_to` | число | нет | Контакты, появившиеся не позже этого момента. Unix-время в секундах |
| `with` | строка | нет | Принимается для совместимости, например `variables`. Ничего не меняет: теги и переменные в ответе есть всегда |

Контакты идут по возрастанию `id` — и по страницам, и при выгрузке сдвигом. Если передан `offset` или `limit`, работает сдвиг, а `page` и `count` не учитываются.

### По страницам

```bash title="Запрос"
curl -X POST "https://watbot.ru/api/v1/getContacts" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"bot_id": 12345, "count": 2, "date_from": 1758931200}'
```

```json title="Ответ 200"
{
  "data": [
    {
      "id": 4815162,
      "bot_id": 12345,
      "phone": "70001234567",
      "email": null,
      "name": "Мария Иванова",
      "address": null,
      "messenger": "telegram",
      "utm": {"utm_source": "vk_ads"},
      "avatar": null,
      "telegram_id": "123456789",
      "telegram_username": "maria_ivanova",
      "vk_user_id": null,
      "created_at": "2026-09-28T07:41:12+00:00",
      "unsubscribed_at": null,
      "tags": ["оформил заказ"],
      "variables": [
        {"id": 17590475010001, "name": "utm_source", "value": "vk_ads", "type": 0, "schema_id": null, "deletable": false, "payload": null},
        {"id": 17590475820003, "name": "город", "value": "Казань", "type": 0, "schema_id": null, "deletable": false, "payload": null}
      ]
    },
    {
      "id": 4815170,
      "bot_id": 12345,
      "phone": null,
      "email": null,
      "name": "Алексей Смирнов",
      "address": null,
      "messenger": "vk",
      "utm": [],
      "avatar": null,
      "vk_user_id": 700123456,
      "created_at": "2026-09-29T15:02:47+00:00",
      "unsubscribed_at": null,
      "tags": [],
      "variables": []
    }
  ],
  "links": {
    "first": "https://watbot.ru/api/v1/getContacts?page=1",
    "last": "https://watbot.ru/api/v1/getContacts?page=38",
    "prev": null,
    "next": "https://watbot.ru/api/v1/getContacts?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 38,
    "links": […],
    "path": "https://watbot.ru/api/v1/getContacts",
    "per_page": 2,
    "to": 2,
    "total": 75
  }
}
```

- `meta.total` — сколько всего контактов под условия, `meta.last_page` — номер последней страницы. Чтобы выгрузить всё, запрашивайте страницы, пока `links.next` не станет `null`. В ссылках `links` нет ваших параметров, кроме `page`, — `bot_id`, `count` и даты передавайте в каждом запросе заново.
- Новые контакты попадают в конец выгрузки — порядок по `id` не даёт страницам сдвигаться. Чтобы выгрузка не росла, пока вы её листаете, ограничьте её параметром `date_to`.
- `bot_id` чужого или несуществующего бота не даёт ошибки: список будет пустым.

### Сдвигом

Запрос второй сотни контактов бота:

```bash title="Запрос"
curl -X POST "https://watbot.ru/api/v1/getContacts" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"bot_id": 12345, "limit": 100, "offset": 100}'
```

```json title="Ответ 200"
{
  "data": [
    {
      "id": 4815162,
      "bot_id": 12345,
      "phone": "70001234567",
      "email": null,
      "name": "Мария Иванова",
      "address": null,
      "messenger": "telegram",
      "utm": [],
      "avatar": null,
      "telegram_id": "123456789",
      "telegram_username": "maria_ivanova",
      "vk_user_id": null,
      "created_at": "2026-09-28T07:41:12+00:00",
      "unsubscribed_at": null,
      "tags": ["оформил заказ"],
      "variables": [
        {"id": 17590475820003, "name": "город", "value": "Казань", "type": 0, "schema_id": null, "deletable": false, "payload": null}
      ]
    }
  ],
  "meta": {
    "offset": 100,
    "limit": 100,
    "total": 101
  }
}
```

- `meta.total` — сколько всего контактов под условия. Выгрузка закончена, когда в `data` пришло меньше контактов, чем `limit`, или `offset + limit` дошёл до `meta.total`.
- Первая порция — `offset` `0` или без `offset`.

## getNumberOfContacts

Считает контакты ваших ботов — с теми же фильтрами, что у `getContacts`.

```endpoint
GET POST https://watbot.ru/api/v1/getNumberOfContacts
```

| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| `bot_id` | число | нет | Только контакты этого бота. Без параметра — всех ваших ботов |
| `date_from` | число | нет | Контакты, появившиеся не раньше этого момента. Unix-время в секундах |
| `date_to` | число | нет | Контакты, появившиеся не позже этого момента. Unix-время в секундах |

```bash title="Запрос"
curl "https://watbot.ru/api/v1/getNumberOfContacts?bot_id=12345" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json"
```

```json title="Ответ 200"
{
  "count": 1284
}
```

Число — в поле `count` на верхнем уровне, без обёртки `data`.

## createOrUpdateContact

Создаёт контакт в боте или обновляет найденный. Контакт ищется в боте по ID в выбранном мессенджере: `telegram_id`, `max_id`, `vk_id` или `viber_id`. Нашёлся — его данные обновляются, нет — создаётся новый.

```endpoint
GET POST https://watbot.ru/api/v1/createOrUpdateContact
```

| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| `bot_id` | число | да | ID вашего бота |
| `messenger` | строка | да | Мессенджер контакта: `telegram`, `max`, `viber` или `vk` |
| `name` | строка | да | Имя контакта. Заменяет прежнее при каждом вызове |
| `telegram_id` | число | для `telegram` | ID пользователя в Telegram |
| `telegram_username` | строка | нет | Username в Telegram, до 255 символов |
| `max_id` | число | для `max` | ID пользователя в MAX. Можно передать и как `max_user_id` — под этим именем он приходит в ответе |
| `max_username` | строка | нет | Username в MAX, до 255 символов |
| `vk_id` | число | для `vk` | ID пользователя ВКонтакте. Можно передать и как `vk_user_id` — под этим именем он приходит в ответе |
| `viber_id` | строка | для `viber` | ID пользователя в Viber, до 255 символов |
| `phone` | строка | нет | Телефон в международном формате: `+` и цифры, от 9 до 16 символов вместе с плюсом — `+70001234567`. Сохраняется цифрами, без `+`; `null` — как если бы телефон не передали |
| `email` | строка | нет | Email |
| `address` | строка | нет | Адрес, до 255 символов |
| `tags` | массив строк | нет | Теги, до 100 штук, каждый до 255 символов. **Заменяют** все теги контакта |

```bash title="Запрос"
curl -X POST "https://watbot.ru/api/v1/createOrUpdateContact" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "bot_id": 12345,
    "messenger": "telegram",
    "telegram_id": 123456789,
    "telegram_username": "maria_ivanova",
    "name": "Мария Иванова",
    "phone": "70001234567",
    "email": "maria@example.com",
    "tags": ["клиент", "из CRM"]
  }'
```

```json title="Ответ 201"
{
  "data": {
    "id": 4815162,
    "bot_id": 12345,
    "phone": "70001234567",
    "email": "maria@example.com",
    "name": "Мария Иванова",
    "address": null,
    "messenger": "telegram",
    "utm": [],
    "avatar": null,
    "telegram_id": "123456789",
    "telegram_username": "maria_ivanova",
    "vk_user_id": null,
    "created_at": "2026-10-03T09:15:42+00:00",
    "unsubscribed_at": null,
    "tags": ["клиент", "из CRM"],
    "variables": []
  }
}
```

```json title="Ответ 404"
{
  "message": "Бот не найден",
  "errors": {
    "bot_id": ["Бот не найден"]
  }
}
```

Код ответа `201` — контакт создан, `200` — обновлён существующий.

- **Что меняется у найденного контакта.** `name` — всегда. `email`, `address`, `phone`, `telegram_username`, `max_username` — только если переданы и не пустые: очистить их этим методом нельзя. `tags` — если переданы, заменяют весь набор тегов; пустой массив `[]` снимает все теги. Переменные контакта метод не трогает.
- **Новый контакт** появляется в списке контактов бота с первым сообщением «Created from API» и увеличивает число подписчиков бота. Сценарий бота при этом не запускается, и контакту ничего не отправляется.
- **Телефон** хранится цифрами, без `+`, — так же, как его сохраняют блоки бота. В ответе `phone` тоже без `+`.

Ошибки метода (общие — в разделе [Ошибки](https://support.watbot.ru/api#ошибки)):

| Код | Когда | Ответ |
|---|---|---|
| `404` | Бота с таким `bot_id` нет среди ваших — его нет совсем или он в другом аккаунте | `{"message": "…", "errors": {"bot_id": ["…"]}}` |
| `422` | Не передан ID для выбранного мессенджера, неверный формат телефона или email | `{"message": "…", "errors": {…}}` |
