Перейти к основному содержимому

API — обзор

Актуально для: SimpleTwo 0.9.x · Проверено: 07.09.2026

У платформы не один API, а несколько — по службам, и это не разрозненность, а следствие разделения плоскостей: у плоскости связи и плоскости управления разные требования к доступности, поэтому у них разные адреса и разные сроки жизни токенов.

СлужбаБазаЧто там
Каталогhttps://dir.<домен>вход и токены платформы (OpenID Connect), люди и группы
Координаторhttps://s2.<домен>/v1политики доступа, встречи, реестр узлов, консоль
Messaginghttps://chat.s2.<домен>/v1разговоры и сообщения, звонки (в том числе токен звонка) и сигналинг, присутствие, боты, вложения
Календарьhttps://dir.<домен>/cal/v1календари, записи, приглашения, ICS и CalDAV

Человека в систему впускает только каталог; координатор никого не впускает и токенов людям не выдаёт. Звонок в беседе берёт пропуск у messaging (POST /v1/calls/token с room = conv-<id> и conv = <id>): членство в беседе и роли в ней знает только он. У координатора остаётся вход во встречу календаря (POST /v1/meetings/{id}/join) — приглашённых и ведущего знает он.

Полная карта эндпоинтов каждой службы — в разделе Справочник: он собирается из кода, поэтому не отстаёт от релиза.

Аутентификация: пять разных вещей​

Все пять ходят в одном заголовке Authorization: Bearer <токен> — и это единственное, что у них общее. Права, срок жизни и способ получения различаются.

ТокенКому выдаётсяКак получитьЖивёт
токен платформычеловеку в приложенииу каталога: /oauth/authorize (код + PKCE) и обмен в /oauth/token; пароль локальной учётки — /oauth/signin/passwordминуты; продлевается refresh-токеном в /oauth/token каталога
бот (bot_…)боту или интеграцииадминистратором в консоли: Botsдо отзыва; каждый запрос в аудите, включая чтения
служебныйслужбе продукта (messaging → координатор)из конфигурации при установке ролидо перевыпуска
узел (X-Node-Token, не Bearer)хосту с рольюпри подключении хоста join-командойдо отзыва хоста
приглашениеодноразовое, в пути URLPOST /admin/api/enrollодин обмен, затем 410

Три правила, о которые спотыкаются интеграции:

  1. Токен бота — не токен человека. Бот ограничен возможностями (capabilities) и списком разговоров: то, что видит сотрудник, боту может быть недоступно, и наоборот. Проверять свою интеграцию под сессией человека, а запускать под ботом — верный способ получить 403 в проде.
  2. 401 означает «продли», а не «повтори». На 401 нужно один раз обменять refresh-токен в /oauth/token каталога (grant_type=refresh_token) и повторить запрос; повтор с тем же токеном даст тот же 401.
  3. 403 намеренно накрывает и «нет такого», и «не ваше» — там, где различить их значило бы раскрыть каталог, который вызывающему не положено читать.

Версия протокола​

Полный текст контракта — отдельная страница

Ниже — краткая выжимка. Обязательства сторон целиком зафиксированы в клиент-серверном протоколе: поверхности, формы запросов, события сокета, возможности, время на проводе и правила, по которым это вообще может меняться.

Одно монотонное целое, PROTOCOL_VERSION, покрывает и HTTP-формы, и кадры сокета: это один контракт, и день, когда они начнут версионироваться отдельно, — это день, когда клиент сможет удовлетворить половину. Не semver: единственный вопрос, который кто-либо задаёт, — «этот клиент старше того, что сервер требует», а это сравнение.

ЗаголовокНаправлениеЗначение
X-SimpleTwo-Protocolсервер → клиентчто говорит эта служба
X-SimpleTwo-Protocol-Minсервер → клиентсамый старый клиент, который ещё обслуживается
X-SimpleTwo-Client-Protocolклиент → серверчто говорит этот клиент

Заголовки, а не поля в теле: клиент должен узнать, что он отстал, из вызова, который он и так делал — включая неудавшийся, а заголовок доживает до клиента даже с тем 4xx, чьё тело он не разберёт.

Три состояния, и все три существуют:

Клиент относительно сервераСерверКлиент
актуаленобслуживаетничего
отстал, но ≥ Minобслуживает, считает по версиямненавязчивое «доступно обновление»
ниже Minотказ: client_too_oldблокирующий экран: эта сборка не говорит с этим сервером

Средняя строка — самое важное. Без неё каждое изменение контракта — выбор между «сломать молча» и «тащить алиас вечно», а алиас нельзя вывести из обращения: доказать, что последний старый клиент исчез, невозможно. С ней у устаревания есть конец: поднять Min в назначенный день, посмотрев на отчёт по популяции, после недель предупреждений в самом приложении.

Min сегодня равен 4: клиент, который назвал версию ниже, получает 426 с кодом client_too_old. Запрос без заголовка считается версией 0 и обслуживается — он не заявляет ничего, о чём можно судить, — но такой клиент и не узнает, что отстал. Планируя интеграцию, отправляйте X-SimpleTwo-Client-Protocol.

Ошибки​

{ "code": "call_step_is_signalling",
"error": "This version of the app can no longer place calls — please update it." }
  • code — машиночитаемый, строчными через подчёркивание, никогда не переименовывается и не переиспользуется. Это идентификатор: переименование меняет то, что покажет более старый клиент.
  • error — английское предложение, остаётся навсегда как запасной вариант для клиента, который кода не знает. Оно видно пользователю независимо от наших пожеланий: установленные клиенты показывают его дословно.

Полный перечень кодов — Коды ошибок, он генерируется из объявлений в службе.

Коды состояния несут смысл, и различать их обязательно:

КодЗначитЧто делать
400запрос неправильный или называет неизвестноеэто баг: сообщить, не повторять
401токена нет, истёк или отозванпродлить и повторить один раз
403аутентифицирован и не имеет праване повторять, это ответ
404нет такого — или нет для этого вызывающегосчитать отсутствующим
409конфликт состояния (повторное вступление, занятое имя)разрешить и повторить
410форма ушла; сообщение называет заменуправить клиент
429ограничение частотыотступить; на сокет не влияет

События: один сокет​

GET /v1/ws?token=…&device=… на хосте messaging. Один сокет на устройство, а не по одному на разговор: порядок событий гарантирован только внутри соединения, а несколько соединений одного устройства — это гонка, которую нельзя починить на клиенте.

Формы кадров, порядок доставки и что делать при разрыве — в разделе «События» спецификации протокола; отдельная статья про сокет пишется следующей.

С чего начать интеграцию​

  1. Получить токен бота в консоли (Settings → Bots) с нужными возможностями.
  2. Посмотреть, что уже умеют автоматизации: исходящие вебхуки и сценарии по событию закрывают большинство задач без опроса API, и их настраивает администратор в консоли без написания кода.
  3. Проверять X-SimpleTwo-Protocol-Min в ответах и отправлять свою версию: интеграция — такой же клиент, и порог Min касается её ровно так же, как мобильного приложения.
  4. Прочитать контракт — прежде всего §1 (личность проставляет сервер), §5 (три поверхности) и §14 (как это расширяется): большинство ошибок интеграции — это попытка сказать серверу то, что он о вас и так знает.