# 1-чат — API для внешних агентов (документация) > Программный доступ к переписке в Telegram, WhatsApp и MAX по API-ключу: > чтение диалогов и истории, отправка текста, реакции, отметка о прочтении. > Каналы подключает человек через интерфейс — API подключениями не управляет. Базовый адрес: https://app.1-chat.ru/api Авторизация: заголовок `Authorization: Bearer <ключ>` Выпуск ключа: https://app.1-chat.ru/api-keys Полная документация: https://1-chat.ru/baza-znany/api Редакция описания: a68e92844066f698 ## Прежде чем писать код - **Лимит новых чатов на подключение за 24 часа.** По умолчанию — 10; тариф и исключение для рабочего пространства могут менять предел. Текущий лимит возвращается в outreach подключений. Считается создание нового для 1-чат диалога через /conversations/start, даже без отправки сообщения. Предел считается по каждому подключённому аккаунту отдельно и скользящим окном в 24 часа, а не по календарным суткам. Он общий с людьми: то, что оператор начал вручную, тоже входит в счёт. При превышении приходит 429 с кодом new_contacts_daily_limit и временем, через которое освободится место. Предел защищает аккаунт от блокировки мессенджером — обходить его, заводя второй ключ, бессмысленно: счёт ведётся по аккаунту. - **Секрет показывается один раз.** В базе хранится только хеш ключа, поэтому перечитать секрет позже невозможно — ни через интерфейс, ни через поддержку. Потерянный ключ заменяется перевыпуском. - **Отправка сообщения синхронная.** Ответ приходит только после того, как мессенджер подтвердил приём, и на медленных каналах это занимает до полутора минут. Закладывайте это в таймауты клиента. - **Повторяйте отправку только с тем же client_id.** Передавайте client_id — свой UUID на каждое новое сообщение. Повтор с тем же client_id в том же диалоге не отправит второй раз, а вернёт уже созданное сообщение, так что ретрай после таймаута безопасен. Без client_id повтор отправит сообщение второй раз. - **Вместо опроса — ожидание изменений.** WebSocket ключам закрыт, но опрашивать список диалогов не нужно: GET /v1/changes принимает курсор и держит запрос до 30 секунд, возвращаясь в тот момент, когда событие действительно появилось. Один ждущий запрос заменяет десяток пустых проверок. Первый вызов — since=0 и wait=0, чтобы узнать текущий курсор; дальше передавайте cursor из ответа. Ответ status=gap означает, что курсор устарел и состояние надо перечитать целиком. - **Из аккаунта, которому нужен вход, писать нельзя.** Если сессию закрыли или мессенджер её завершил, чаты аккаунта остаются и читаются, но отправка, реакции, поиск собеседника и импорт отвечают 409 с кодом integration_needs_login и состоянием аккаунта. Так же, с кодом integration_not_running, отвечает аккаунт, который сейчас не удаётся подключить. Смотрите заранее state.can_send у аккаунта в list_accounts: он учитывает и то и другое. can_send у диалога говорит только о том, нужен ли аккаунту вход. Войти снова может только владелец рабочего пространства в интерфейсе. - **Ссылку на диалог берите из ответа.** У диалога и у сообщения есть web_url — адрес, по которому человек откроет его в интерфейсе: после входа, в нужном рабочем пространстве, на нужном сообщении. Ссылаясь на диалог, давайте человеку web_url, а не составляйте адрес сами. ## Уровни доступа - `sk_1chat_ro_…` — Чтение: Видит переписку, ничего не меняет - `sk_1chat_rw_…` — Запись: Видит переписку и может отправлять сообщения от имени владельца ключа ## Методы - `GET /v1/attachments/{attachment_id}/raw` — Содержимое вложения - `GET /v1/changes` — Что изменилось с прошлого раза — вместо опроса списка диалогов - `GET /v1/conversations` — Список диалогов - `GET /v1/conversations/{conversation_id}` — Карточка диалога - `GET /v1/conversations/{conversation_id}/assignment-events` — История диалога в команде: кто брал, кому передавал и почему - `GET /v1/conversations/{conversation_id}/messages` — История переписки - `GET /v1/conversations/{conversation_id}/participants` — Участники диалога - `GET /v1/integrations` — Подключённые аккаунты и остаток новых собеседников на сегодня - `GET /v1/team/handoff-categories` — Причины передачи, которые предлагает рабочее пространство - `GET /v1/team/members` — Кто в команде — кому можно передать диалог - `GET /v1/webhook-endpoints` — Свои вебхуки и их состояние - `POST /v1/conversations/recipients/search` — Найти собеседника по телефону или имени - `POST /v1/conversations/start` — Начать диалог с новым собеседником - `DELETE /v1/conversations/{conversation_id}/assignment` — Отпустить диалог — свой; владелец отпускает любой - `POST /v1/conversations/{conversation_id}/assignment` — Взять диалог; забрать чужой (force) может только ключ владельца - `DELETE /v1/conversations/{conversation_id}/help-call` — Отменить передачу — свою; владелец отменяет любую - `PATCH /v1/conversations/{conversation_id}/help-call` — Изменить причину и комментарий передачи — свою; владелец любую - `POST /v1/conversations/{conversation_id}/help-call` — Передать свой диалог человеку — он станет ведущим, когда примет - `POST /v1/conversations/{conversation_id}/help-call/accept` — Принять диалог, который передали вам - `DELETE /v1/conversations/{conversation_id}/help-call/escalate` — Снять срочность с передачи - `POST /v1/conversations/{conversation_id}/help-call/escalate` — Сделать передачу срочной — у позванного сирена, пока не примет - `POST /v1/conversations/{conversation_id}/messages` — Отправить сообщение - `POST /v1/conversations/{conversation_id}/messages/{message_id}/reactions` — Поставить реакцию - `DELETE /v1/conversations/{conversation_id}/messages/{message_id}/reactions/{emoji}` — Снять реакцию - `POST /v1/conversations/{conversation_id}/read` — Отметить диалог прочитанным - `POST /v1/conversations/{conversation_id}/typing` — Показать собеседнику «печатает» — повторять, пока пишете - `POST /v1/uploads` — Загрузить вложение для отправки — его id передаётся в attachment_ids сообщения - `POST /v1/webhook-endpoints` — Зарегистрировать вебхук — заявка, которую включает человек Список разрешённого, а не запрещённого: существующий метод, которого здесь нет, отвечает 403 — в том числе метод, который появится в будущем. Несуществующий путь отвечает 404, так что опечатку в адресе легко отличить от нехватки прав. ## Каналы - `whatsapp` — WhatsApp - `telegram` — Telegram-бот: скоро. Подключить бота пока нельзя: работает личный аккаунт Telegram - `telegram_client` — Telegram (личный аккаунт). Подключение личного аккаунта. Сообщения уходят от имени человека. - `max` — MAX ## Статусы сообщения - `queued` — Принято к отправке - `sent` — Мессенджер принял сообщение - `failed` — Отправить не удалось ## Чего API не умеет - Подключать и отключать каналы: Каналы подключает человек через интерфейс — это решение, а не пробел - Работать с биллингом, оплатой и тарифами: Закрыто полностью - Входить, регистрироваться, управлять аккаунтом: Закрыто полностью - Создавать и отзывать API-ключи: Ключ не управляет ключами, в том числе собой - Подключаться к WebSocket: Поток реального времени доступен только интерфейсу; агент ждёт изменений через /v1/changes или получает вебхук - Видеть групповые чаты и каналы: Агенту доступна только личная переписка ## Ограничения - 300 запросов в минуту на ключ или подключение, окно — календарная минута - До 20 активных ключей на рабочее пространство - По умолчанию не больше 10 новых собеседников в сутки на подключённый аккаунт, окно скользящее; предел общий с людьми - Список диалогов: по умолчанию 50, максимум 200 - История переписки: по умолчанию 50, максимум 200, пагинация курсорная - Срок годности у ключа отсутствует ## Коды ошибок - `401` `invalid_api_key` — Ключ не существует, отозван или перевыпущен - `403` `api_key_scope_forbidden` — Метод недоступен ключам - `403` `api_key_read_only` — Ключом на чтение вызван метод записи - `403` `api_key_channel_forbidden` — Диалог в мессенджере, закрытом для ключей - `404` — Объект не найден или принадлежит другому воркспейсу - `409` `integration_needs_login` — Аккаунту нужен вход: писать из него нельзя, пока владелец не войдёт снова - `409` `integration_not_running` — Аккаунт сейчас не работает: писать из него нельзя - `422` — Некорректное тело запроса - `429` `global_rate_limited` — Превышена частота запросов - `429` `new_contacts_daily_limit` — Исчерпан дневной предел новых собеседников для этого аккаунта ## MCP Агент может ходить в 1-чат не голым HTTP, а через MCP: сервер удалённый, авторизация — тем же API-ключом в заголовке, а в claude.ai и ChatGPT — коннектором, без ключа. Набор инструментов повторяет доступные ключу методы, и ключ на чтение пишущих инструментов не видит вовсе. Адрес: https://app.1-chat.ru/api/v1/mcp/ Транспорт: streamable_http Авторизация: тот же ключ в заголовке Authorization; claude.ai и ChatGPT — коннектором (OAuth), без ключа - `register_webhook` (write) — Просит присылать события на ваш адрес, чтобы не ждать и не опрашивать вообще. Подходит, если вы не живёте постоянно: просыпаетесь по входящему запросу вместо того, чтобы держать соединение. В ответе придёт secret — он показывается ОДИН РАЗ, сохраните его сразу. Каждая доставка подписана: заголовок X-1chat-Signature содержит sha256 от HMAC по строке «метка_времени.тело» с этим секретом; проверяйте подпись, иначе ваш адрес открыт всем. ВАЖНО: вебхук создаётся ВЫКЛЮЧЕННЫМ. Доставка начнётся после того, как человек включит его в интерфейсе — скажите ему об этом, сами включить вы не можете. Проверить состояние: list_webhooks. - `list_webhooks` (read) — Ваши вебхуки и их состояние. Смотрите сюда, чтобы понять, включил ли человек зарегистрированный вами адрес: is_active=true означает, что события уже идут. Здесь же видно, сколько событий накопилось и не отключили ли адрес за неудачные доставки. - `wait_for_changes` (read) — Ждёт, пока в переписке что-нибудь произойдёт, и возвращает только изменения — новые сообщения, смену статусов, обновления диалогов. ИСПОЛЬЗУЙТЕ ЭТО ВМЕСТО ПОВТОРНЫХ ВЫЗОВОВ list_conversations: один вызов ждёт до 30 секунд и возвращается сразу, как только событие появилось, вместо десятка проверок впустую. Первый раз вызывайте с since=0 и wait=0 — получите текущий курсор без ожидания. Дальше передавайте cursor из прошлого ответа в since. Если пришёл status=gap, курсор устарел: перечитайте list_conversations и начните с нового cursor. conversation:typing — собеседник пишет (или записывает голосовое) до момента until: лучше дождаться его сообщения, чем отвечать на половину мысли. conversation:assignment_updated — сменился ведущий. - `list_conversations` (read) — Диалоги по всем подключённым мессенджерам. Уведомлений о новых сообщениях у API нет — новые обнаруживаются сравнением last_message_at. - `get_conversation` (read) — Один диалог: собеседник, последнее сообщение, счётчик непрочитанных. - `list_messages` (read) — Сообщения диалога, новые первыми. Листается курсором: передайте next_before_seq из ответа в before_seq, чтобы уйти глубже в историю. Пустой next_before_seq означает, что история кончилась. - `list_participants` (read) — Кто участвует в диалоге, с именами и идентификаторами в мессенджере. - `list_accounts` (read) — Подключённые аккаунты мессенджеров и сколько новых собеседников каждому из них осталось на сегодня. Смотрите сюда до того, как начинать диалоги пачкой: предел считается по аккаунту, общий с людьми, и при исчерпании start_conversation вернёт отказ. state.can_send=false значит, что из аккаунта сейчас писать нельзя (state.title и state.message объясняют почему, например нужен вход); войти снова может только владелец в интерфейсе. - `search_recipients` (write) — Ищет человека в мессенджере по номеру телефона или имени пользователя, чтобы написать тому, с кем переписки ещё не было. Ничего не отправляет и диалог не создаёт. У каждого найденного смотрите can_message: не всякому можно написать, причина будет в reason. Дальше передайте query в start_conversation. - `start_conversation` (write) — Создаёт диалог с собеседником, найденным через search_recipients, и возвращает его идентификатор — отправлять сообщение нужно отдельным вызовом send_message. Само по себе ничего не отправляет и собеседника не беспокоит. Если диалог с этим человеком уже есть, вернётся он же, дубликата не будет и предел новых собеседников при этом не тратится. - `send_message` (write) — Отправляет текст в существующий диалог от имени владельца ключа. Ответ приходит только после подтверждения мессенджером, до полутора минут. ВСЕГДА передавайте client_id (свой UUID на каждое новое сообщение): повтор с тем же client_id безопасен — второй раз не отправится, вернётся уже созданное. БЕЗ client_id повтор отправит сообщение второй раз. Файл: сначала upload_file, его id — в attachment_ids; text тогда — подпись, можно без него. Написать новому собеседнику нельзя, только в уже существующий диалог. Если аккаунту диалога нужен вход (can_send=false у диалога), отправка отклоняется с объяснением — повторять бесполезно, пока владелец не войдёт снова. - `upload_file` (write) — Готовит файл к отправке в диалог: по публичной ссылке (сервер скачает сам) или из base64. Возвращает id — передайте его в attachment_ids send_message. Сам по себе файл никому не уходит. До 50 МБ; PDF и другие документы уходят файлом, картинки — фото, если не указан kind. Каждый id отправляется один раз: для второго сообщения загрузите снова. - `mark_conversation_read` (write) — Обнуляет счётчик непрочитанных. Счётчик общий на диалог, а не на пользователя: он обнулится и у людей, работающих с этим диалогом в интерфейсе. С to_messenger=true собеседник ещё и увидит «прочитано» в мессенджере (capabilities.read_receipts в list_accounts); в диалоге, который ведёт другой, ничего не меняется. - `set_reaction` (write) — Ставит эмодзи-реакцию на сообщение. - `remove_reaction` (write) — Снимает ранее поставленную реакцию. - `list_team` (read) — Кто сейчас в команде: user_id, имя, роль (owner, admin или operator) и is_me — это вы сами. Нужен, чтобы передать диалог человеку через hand_over. - `list_handoff_categories` (read) — Причины, которые рабочее пространство предлагает для hand_over: берите подходящую дословно. Это подсказки, а не ограничение — если ни одна не подходит, напишите свою. is_default=true — владелец список не менял. - `take_conversation` (write) — Делает вас ведущим диалога. Писать в диалог может только ведущий; свободный диалог send_message берёт сам, так что звать это нужно, чтобы занять диалог до ответа. Диалог, который ведёт другой, без force не взять — ответ conversation_assigned, в нём сказано, кто ведёт. force=true забирает диалог у ведущего, но только если ключ выпущен владельцем или администратором рабочего пространства; ключ оператора получит admin_only. Забирайте чужой диалог, только если вас об этом прямо попросили. - `release_conversation` (write) — Перестать вести свой диалог: он станет свободным, и любой из команды сможет его взять. Чтобы отдать диалог конкретному человеку, используйте hand_over. - `hand_over` (write) — Просит человека (user_id из list_team) забрать ваш диалог. Ведущим он станет, только когда примет; до этого диалог остаётся за вами и вы можете отвечать. Одна передача на диалог: новая заменяет прежнюю. Скажите, зачем зовёте: category — причина (из list_handoff_categories или своими словами), note — что человеку знать до того, как он откроет диалог. Принятие придёт событием conversation:assignment_updated. - `cancel_hand_over` (write) — Отзывает вашу просьбу забрать диалог, пока её не приняли. - `update_hand_over` (write) — Меняет причину и комментарий открытой передачи; меняется только то, что передали, пустая строка стирает. Можно тому, кто позвал (или ключу владельца). Нет передачи — help_call_not_found. - `show_typing` (write) — Собеседник видит «печатает» около пяти секунд. Повторяйте раз в 4 секунды, пока готовите ответ; чаще звать можно, лишнее склеится. Только в своём или свободном диалоге, диалог при этом не занимается. Где мессенджер не умеет (capabilities.typing=false в list_accounts), ничего не происходит. - `escalate_hand_over` (write) — Усиливайте, только если позванный долго не подключается, а вопрос важный: у него включится сирена, пока он не примет диалог. Можно тому, кто позвал (или ключу владельца). Нет передачи — help_call_not_found. - `deescalate_hand_over` (write) — Возвращает передачу в обычный вид; сама передача остаётся. - `accept_hand_over` (write) — Становитесь ведущим диалога, который передали именно вам. ## Страницы - [https://1-chat.ru/baza-znany/api](https://1-chat.ru/baza-znany/api): полное описание API — методы, параметры, ограничения, безопасность - [https://1-chat.ru/mcp](https://1-chat.ru/mcp): раздел для ИИ-агентов - [https://1-chat.ru/llms.txt](https://1-chat.ru/llms.txt): что такое 1-чат — каналы, тарифы, коннектор для Claude и ChatGPT