MCP · REST API
MCP-сервер и API для ИИ-агентов: Telegram, WhatsApp, MAX
Агент читает переписку из подключённых мессенджеров, находит собеседника и отвечает от вашего имени. Один ключ на все каналы — через MCP-сервер или обычным HTTP, без отдельной интеграции на каждый мессенджер.
- 28
- методов
- 4
- каналов
- 300
- запросов в минуту
- 2
- уровня доступа
Возможности
Что агент делает с перепиской
Каналы подключает человек через интерфейс. API работает с уже подключёнными — управлять подключениями он не может по замыслу.
Может
- Читать список диалогов по всем подключённым мессенджерам сразу
- Ждать новых сообщений, не опрашивая API вхолостую
- Получать вебхук на свой адрес, когда держать соединение негде
- Читать историю переписки и участников диалога
- Скачивать вложения
- Находить собеседника по телефону или имени пользователя
- Начинать диалог с тем, с кем ещё не переписывались
- Отправлять сообщения с текстом и файлами
- Отмечать диалог прочитанным
- Ставить и снимать реакции
Не может
- Подключать и отключать каналы
- Работать с биллингом, оплатой и тарифами
- Входить, регистрироваться, управлять аккаунтом
- Создавать и отзывать API-ключи
- Подключаться к WebSocket
- Видеть групповые чаты и каналы
Начало работы
Ключ и первый запрос
Ключи выпускаются в интерфейсе, на странице «API-ключи». Секрет показывается один раз — в базе хранится только его хеш.
Чтение
sk_1chat_ro_…Видит переписку, ничего не меняет
Запись
sk_1chat_rw_…Видит переписку и может отправлять сообщения от имени владельца ключа
Authorization: Bearer sk_1chat_rw_…Базовый адрес: https://app.1-chat.ru/api. Полный список методов, параметров и кодов ошибок — в документации.
Важное
Что учесть до того, как писать код
Свойства API, которые ломают наивного клиента. Полный список ограничений — в документации.
Лимит новых чатов на подключение за 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 у диалога говорит только о том, нужен ли аккаунту вход. Войти снова может только владелец пространства в интерфейсе.
MCP
MCP-сервер
Агент может ходить в 1-чат не голым HTTP, а через MCP: сервер удалённый, авторизация — тем же API-ключом в заголовке. Набор инструментов повторяет доступные ключу методы, и ключ на чтение пишущих инструментов не видит вовсе.
https://app.1-chat.ru/api/v1/mcp/
Authorization: Bearer sk_1chat_rw_…Транспорт — Streamable HTTP. Сервер понимает версии протокола до 2026-07-28 включительно; конкретная версия согласуется при рукопожатии.
Где это работает
По документации самих клиентов — мы проверяли не каждый.
Инструменты
9 доступны обоим ключам, 17 — только ключу на запись. Пишущих инструментов ключ на чтение не видит в списке вовсе.
Обоим ключам
list_webhooksСостояние вебхуковВаши вебхуки и их состояние. Смотрите сюда, чтобы понять, включил ли человек зарегистрированный вами адрес: is_active=true означает, что события уже идут. Здесь же видно, сколько событий накопилось и не отключили ли адрес за неудачные доставки.wait_for_changesДождаться новогоЖдёт, пока в переписке что-нибудь произойдёт, и возвращает только изменения — новые сообщения, смену статусов, обновления диалогов. ИСПОЛЬЗУЙТЕ ЭТО ВМЕСТО ПОВТОРНЫХ ВЫЗОВОВ list_conversations: один вызов ждёт до 30 секунд и возвращается сразу, как только событие появилось, вместо десятка проверок впустую. Первый раз вызывайте с since=0 и wait=0 — получите текущий курсор без ожидания. Дальше передавайте cursor из прошлого ответа в since. Если пришёл status=gap, курсор устарел: перечитайте list_conversations и начните с нового cursor. conversation:typing — собеседник пишет (или записывает голосовое) до момента until: лучше дождаться его сообщения, чем отвечать на половину мысли. conversation:assignment_updated — сменился ведущий.list_conversationsСписок диалоговДиалоги по всем подключённым мессенджерам. Уведомлений о новых сообщениях у API нет — новые обнаруживаются сравнением last_message_at.get_conversationКарточка диалогаОдин диалог: собеседник, последнее сообщение, счётчик непрочитанных.list_messagesИстория перепискиСообщения диалога, новые первыми. Листается курсором: передайте next_before_seq из ответа в before_seq, чтобы уйти глубже в историю. Пустой next_before_seq означает, что история кончилась.list_participantsУчастники диалогаКто участвует в диалоге, с именами и идентификаторами в мессенджере.list_accountsПодключённые аккаунтыПодключённые аккаунты мессенджеров и сколько новых собеседников каждому из них осталось на сегодня. Смотрите сюда до того, как начинать диалоги пачкой: предел считается по аккаунту, общий с людьми, и при исчерпании start_conversation вернёт отказ. state.can_send=false значит, что из аккаунта сейчас писать нельзя (state.title и state.message объясняют почему, например нужен вход); войти снова может только владелец в интерфейсе.list_teamКомандаКто сейчас в команде: user_id, имя, роль (owner или operator) и is_me — это вы сами. Нужен, чтобы передать диалог человеку через hand_over.list_handoff_categoriesПричины передачиПричины, которые пространство предлагает для hand_over: берите подходящую дословно. Это подсказки, а не ограничение — если ни одна не подходит, напишите свою. is_default=true — владелец список не менял.
Только на запись
register_webhookЗарегистрировать вебхукПросит присылать события на ваш адрес, чтобы не ждать и не опрашивать вообще. Подходит, если вы не живёте постоянно: просыпаетесь по входящему запросу вместо того, чтобы держать соединение. В ответе придёт secret — он показывается ОДИН РАЗ, сохраните его сразу. Каждая доставка подписана: заголовок X-1chat-Signature содержит sha256 от HMAC по строке «метка_времени.тело» с этим секретом; проверяйте подпись, иначе ваш адрес открыт всем. ВАЖНО: вебхук создаётся ВЫКЛЮЧЕННЫМ. Доставка начнётся после того, как человек включит его в интерфейсе — скажите ему об этом, сами включить вы не можете. Проверить состояние: list_webhooks.search_recipientsНайти собеседникаИщет человека в мессенджере по номеру телефона или имени пользователя, чтобы написать тому, с кем переписки ещё не было. Ничего не отправляет и диалог не создаёт. У каждого найденного смотрите can_message: не всякому можно написать, причина будет в reason. Дальше передайте query в start_conversation.start_conversationНачать диалогСоздаёт диалог с собеседником, найденным через search_recipients, и возвращает его идентификатор — отправлять сообщение нужно отдельным вызовом send_message. Само по себе ничего не отправляет и собеседника не беспокоит. Если диалог с этим человеком уже есть, вернётся он же, дубликата не будет и предел новых собеседников при этом не тратится.send_messageОтправить сообщениеОтправляет текст в существующий диалог от имени владельца ключа. Ответ приходит только после подтверждения мессенджером, до полутора минут. ВСЕГДА передавайте client_id (свой UUID на каждое новое сообщение): повтор с тем же client_id безопасен — второй раз не отправится, вернётся уже созданное. БЕЗ client_id повтор отправит сообщение второй раз. Файл: сначала upload_file, его id — в attachment_ids; text тогда — подпись, можно без него. Написать новому собеседнику нельзя, только в уже существующий диалог. Если аккаунту диалога нужен вход (can_send=false у диалога), отправка отклоняется с объяснением — повторять бесполезно, пока владелец не войдёт снова.upload_fileЗагрузить файлГотовит файл к отправке в диалог: по публичной ссылке (сервер скачает сам) или из base64. Возвращает id — передайте его в attachment_ids send_message. Сам по себе файл никому не уходит. До 50 МБ; PDF и другие документы уходят файлом, картинки — фото, если не указан kind. Каждый id отправляется один раз: для второго сообщения загрузите снова.mark_conversation_readОтметить диалог прочитаннымОбнуляет счётчик непрочитанных. Счётчик общий на диалог, а не на пользователя: он обнулится и у людей, работающих с этим диалогом в интерфейсе. С to_messenger=true собеседник ещё и увидит «прочитано» в мессенджере (capabilities.read_receipts в list_accounts); в диалоге, который ведёт другой, ничего не меняется.set_reactionПоставить реакциюСтавит эмодзи-реакцию на сообщение.remove_reactionСнять реакциюСнимает ранее поставленную реакцию.take_conversationВзять диалогДелает вас ведущим диалога. Писать в диалог может только ведущий; свободный диалог send_message берёт сам, так что звать это нужно, чтобы занять диалог до ответа. Диалог, который ведёт другой, без force не взять — ответ conversation_assigned, в нём сказано, кто ведёт. force=true забирает диалог у ведущего, но только если ключ выпущен владельцем пространства; ключ оператора получит owner_only. Забирайте чужой диалог, только если вас об этом прямо попросили.release_conversationОтпустить диалогПерестать вести свой диалог: он станет свободным, и любой из команды сможет его взять. Чтобы отдать диалог конкретному человеку, используйте hand_over.hand_overПередать диалог человекуПросит человека (user_id из list_team) забрать ваш диалог. Ведущим он станет, только когда примет; до этого диалог остаётся за вами и вы можете отвечать. Одна передача на диалог: новая заменяет прежнюю. Скажите, зачем зовёте: category — причина (из list_handoff_categories или своими словами), note — что человеку знать до того, как он откроет диалог. Принятие придёт событием conversation:assignment_updated.cancel_hand_overОтменить передачуОтзывает вашу просьбу забрать диалог, пока её не приняли.update_hand_overИзменить причину передачиМеняет причину и комментарий открытой передачи; меняется только то, что передали, пустая строка стирает. Можно тому, кто позвал (или ключу владельца). Нет передачи — help_call_not_found.show_typingПоказать «печатает»Собеседник видит «печатает» около пяти секунд. Повторяйте раз в 4 секунды, пока готовите ответ; чаще звать можно, лишнее склеится. Только в своём или свободном диалоге, диалог при этом не занимается. Где мессенджер не умеет (capabilities.typing=false в list_accounts), ничего не происходит.escalate_hand_overСделать передачу срочнойУсиливайте, только если позванный долго не подключается, а вопрос важный: у него включится сирена, пока он не примет диалог. Можно тому, кто позвал (или ключу владельца). Нет передачи — help_call_not_found.deescalate_hand_overСнять срочностьВозвращает передачу в обычный вид; сама передача остаётся.accept_hand_overПринять переданный диалогСтановитесь ведущим диалога, который передали именно вам.
Новых собеседников — не больше 10 в сутки
Предел считается по каждому подключённому аккаунту и делится с людьми. Агент, который найдёт и напишет 11-му незнакомцу за сутки, получит отказ с кодом new_contacts_daily_limit. Остаток по каждому аккаунту виден через list_accounts.
Частые вопросы
Что нужно, чтобы агент начал работать с перепиской?
Нужен ли Telegram-бот или WhatsApp Business API?
Как агент узнаёт о новых сообщениях?
Можно ли написать человеку, с которым ещё не переписывались?
Что возвращается при превышении лимита?
Нужно ли что-то устанавливать, чтобы подключить MCP-сервер?
Попробуйте 7 дней бесплатно
Подключите мессенджеры и соберите переписку с клиентами в одном окне. Без карты — просто войдите.
Есть вопросы? Напишите нам в Telegram →