APIНачало работы

Аутентификация

Токен

API опознаёт вызывающего по заголовку:

Authorization: Bearer vru_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Токен выдаёт владелец или управляющий в кабинете: Настройки → Интеграции и API → Токены API → «Выдать токен». Он состоит из приставки vru_ и 32 случайных байт в base64url. Приставка не украшение: по ней сервисы поиска утечек (GitHub, GitLab) узнают секрет в чужом репозитории и предупреждают владельца.

Полный токен показывается один раз, в ответе на его создание. На сервере лежит только хеш SHA-256, восстановить строку нельзя. Потеряли — отзовите и выдайте новый. Держите токен в переменной окружения, а не в файлах и командах.

Получить токен можно и без кабинета — входом через OAuth: так подключаются ИИ-агенты — Claude.ai, Claude Desktop, ChatGPT, Claude Code, Cursor, VS Code, Codex, Gemini CLI (см. ниже). Это такой же токен vru_, просто его выдача начинается в приложении агента.

Сервер MCP

https://vruchay.ru/mcp принимает только заголовок Authorization: Bearer vru_… — токен из кабинета или выданный через OAuth. Cookie кабинета там не действуют: адрес вызывают программы, и открытая в браузере сессия не должна давать чужой странице действовать от имени человека. Без токена /mcp отвечает 401 с заголовком WWW-Authenticate, по которому клиенты находят вход через OAuth. Права у инструментов MCP те же, что у REST по тому же токену. Подключение клиентов — в Подключении агента по MCP.

Что даёт токен

Токен принадлежит организации, а не человеку. Он видит те же документы, получателей, задания и реестр, что и сотрудник этой организации с той же ролью. Идентификатор организации всегда берётся из токена и никогда из тела или адреса запроса: подставить чужой orgId невозможно, а обращение к чужому объекту отвечает 404, а не 403, — чтобы не подтверждать, что объект существует.

Вход через OAuth

Для приложений, которые подключаются кнопкой, сервис — сервер авторизации OAuth 2.1 с PKCE. Человек при этом токен не видит и никуда не копирует.

  1. Клиент обращается к /mcp без токена, получает 401 и читает описание ресурса /.well-known/oauth-protected-resource/mcp, а из него — описание сервера авторизации `/.well-known/oauth-authorization-server`.
  2. Регистрируется сам: `POST /api/oauth/register` (Dynamic Client Registration, только публичные клиенты, token_endpoint_auth_method: none). Записи в базе при этом не появляется: client_id — это подписанные сервисом название приложения и его адреса возврата.
  3. Открывает в браузере https://vruchay.ru/oauth/authorize с code_challenge (S256). Не вошедшего в кабинет сначала просят войти.
  4. Страница согласия показывает, какое приложение просит доступ, к какой организации и на какой адрес вернётся разрешение. Человек выбирает права — «Выпускать документы» (member) или «Полный доступ» (admin) — и разрешает (`POST /api/oauth/authorize`) или отказывает.
  5. Клиент меняет одноразовый код на токен: `POST /api/oauth/token` (grant_type=authorization_code, code, code_verifier, client_id). Код живёт десять минут.

Что важно:

  • Разрешает только владелец или управляющий, и только если доступ по API входит в план (возможность api; на пробе она есть). Сотрудник с ролью member увидит «Нужны права управляющего». Отказать может любой.
  • Результат — обычный токен `vru_` с выбранной ролью. Токена обновления нет, срок жизни не ограничен: токен действует, пока его не отзовут и пока разрешивший остаётся в организации владельцем или управляющим.
  • Видно и отзывается в «Токенах API»: строка «Агент «Claude»» (название — то, которым представилось приложение), с правами и временем последней работы. «Отозвать» — и агент сразу теряет доступ.
  • Повторное подключение того же приложения тем же человеком заменяет прежний токен, а не копит новые. «Тем же» считается приложение с тем же названием и адресом возврата с того же сайта: Claude Code и Codex на одном компьютере живут рядом.
  • Не больше десяти подключений через OAuth на организацию, отдельно от десяти обычных токенов. Одиннадцатое не пройдёт, пока не отозвать лишнее.
  • Адреса возврата — https, http только на localhost и 127.0.0.1 (настольные клиенты) и собственные схемы приложений вроде cursor://.
  • Как клиент представляется. Автоматической регистрацией (POST /api/oauth/register) — её сервер и объявляет. Клиент, который сам приходит с адресом своего описания (CIMD), тоже принимается: тогда client_id — это https-адрес JSON-документа с client_id, client_name и redirect_uris. Сервис скачивает его с защитой от походов во внутреннюю сеть, проверяет, что документ называет себя тем же адресом, и помнит его час. Описания на сайтах, закрытых для российских адресов (claude.ai, chatgpt.com), сервис не получит — таким клиентам нужна регистрация.
  • Если за десять минут между разрешением и обменом кода человек потерял права управляющего, токен не выдастся.

Ошибки OAuth отвечают в формате RFC 6749, см. Коды ошибок.

Роли

У токена своя роль, выбранная при выдаче: member («Выпускать документы») или admin («Полный доступ»). У человека роль может быть ещё и owner. Часть действий закрыта ролью:

РольЧто доступно
memberДокументы, получатели, проверка, выпуск, чтение реестра, рассылка
adminТо же плюс удаление документов, отзыв выданного, домены и отправители, интеграции
ownerТо же плюс безвозвратное удаление документа

Роль owner токену выдать нельзя. Если действие требует роли выше вашей, ответ — 403 с сообщением «Недостаточно прав для этого действия».

Чего токен не может

Всё, что управляет людьми, закрыто для токенов наглухо и не открывается ролью:

  • приглашение и удаление сотрудников, смена их ролей — /api/team/*;
  • смена пароля;
  • выдача и отзыв токенов — /api/tokens/*;
  • разрешение доступа агенту на странице согласия OAuth.

Причина простая: токен, умеющий выдавать себе новые токены, — это доступ, который нельзя отозвать, потому что он тут же выдаст себе следующий. А утёкший токен, умеющий менять роли, означал бы потерю организации целиком.

Так же закрыто то, что человек делает от своего имени: своё имя и настройки кабинета (PATCH /api/org/me, GET и PATCH /api/org/preferences), отзыв о сервисе (PATCH /api/reviews/mine), обращения в поддержку (POST /api/support/tickets, POST /api/support/tickets/{id}/messages). Своего имени у токена нет: по нему автором и владельцем настроек оказался бы сотрудник, выдавший токен. Читать организацию (GET /api/org), отзыв и обращения токену можно; userName и email в GET /api/org у него — данные выдавшего, пока тот состоит в организации.

Такие запросы отвечают 403 с сообщением: «Это действие доступно только человеку, вошедшему в кабинет. По токену API его выполнить нельзя.»

Отдельно закрыт раздел самого сервиса — выставление счетов, заявки, модерация отзывов, назначение планов. Туда токен не пускают ни при каких правах. Оплату картой (POST /api/billing/checkout) и счёт по тарифу (POST /api/org/invoices) токен тоже начать не может: платит только человек.

Возможности плана

Роль решает, кому из сотрудников действие доступно, а план организации — входит ли оно в условия. План перечисляет возможности в поле features ответа GET /api/org/usage:

ВозможностьЧто закрываетМаршруты
mailingРассылка писем участникамPOST /api/mail/send/{documentId}, POST /api/mail/templates/{documentId}/test-send, POST /api/mailing/send, POST /api/mailing/test, POST /api/mailing/resend, POST /api/mailing/text/{id}/test, POST /api/mailing/text/{id}/send; выдача по API с письмом (POST /api/documents/{id}/issue с send: true). Без неё не уходят и письма форм на сайте и по ссылке (документ выдаётся скачиванием), и повторная отправка из реестра (POST /api/registry/resend пропускает письма с причиной)
tildaПриём заявок с сайтаPOST /api/integrations/tilda — создание новой формы
apiДоступ по API-токенуPOST /api/tokens — выдача нового токена; разрешение подключения агента через OAuth
awardsАвтоматические правила награжденияPOST /api/award-rules, POST /api/award-rules/{id}/duplicate, POST /api/documents/{id}/awards/rule-set

Проверка стоит только на этих маршрутах. Чтение, правка и удаление уже созданного ею не закрываются, а выданные раньше токены продолжают работать и без api.

На бесплатной пробе и на оплаченном тарифе старого образца (features: null) ограничений нет. Если возможности в плане нет, ответ — 403:

«Рассылка писем участникам» не входит в ваш план. Напишите нам — добавим.

Если срок плана вышел (expired: true), те же маршруты отвечают 403 при любом составе плана:

Срок плана «Название» закончился, поэтому раздел «Рассылка писем участникам» сейчас недоступен. Уже выданные документы остаются действительными. Напишите нам — обсудим продление.

В кавычках стоит название возможности: «Рассылка писем участникам», «Приём заявок с сайта», «Доступ по API-токену» или «Автоматические правила награждения». Проверка плана идёт после проверки входа и роли, но до проверки тела запроса: запрос с ошибкой в полях получит сперва 403, а не 400.

Сессия человека

Кабинет работает не на токенах, а на httpOnly-cookie gramota_session со сроком жизни семь суток. Оба способа разбирает один и тот же слой: сперва проверяется заголовок Authorization, и только если токена нет — cookie. Для интеграции нужен именно токен: вход по паролю программе недоступен, а формы входа защищены ограничением частоты.

Организацию заводит человек, регистрируясь в кабинете. Регистрация означает принятие лицензионного договора-оферты и договора-поручения: сервис записывает, кто, когда, с какого адреса и какую редакцию принял.

Что ещё отличает токен от человека

  • Пробные письма (POST /api/mail/templates/{documentId}/test-send и другие пробы) по токену уходят тому, кто токен выдал, — для подключения через OAuth тому, кто его разрешил. Адрес из запроса не берётся: иначе «проверить письмо» стало бы способом слать что угодно кому угодно. Если этого человека в организации уже нет, проба по токену невозможна — отправьте её из кабинета.
  • Ограничения частоты для токена считаются на организацию, а не на IP-адрес: агенты Claude и ChatGPT ходят с общих облачных адресов за многих пользователей сразу. Подробнее — в Ограничениях частоты.
  • Журнал действий записывает действие от имени токена: «Токен «Название»».
  • Выдавший ушёл. Токен, выданный в кабинете, принадлежит организации и продолжает работать, когда выдавшего его сотрудника убирают из организации. Связь с ним на этом обрывается: в журнале действие по-прежнему записано на токен и к ушедшему не привязано, userName и email в GET /api/org пустые, пробные письма по токену не уходят. Ненужные токены ушедшего отзовите в Настройки → Интеграции и API → Токены API. Подключение через OAuth — личное: это агент самого человека, поэтому оно отзывается вместе с его уходом, и журнал записывает отзыв каждого агента отдельной строкой. Агент получает 401; подключить его снова может только тот, кто в организации состоит. То же при удалении учётной записи разрешившего.
  • Разрешивший понижен. Подключать агентов могут только владелец и управляющий, и держать их — тоже. Когда разрешившего понижают до сотрудника (member), все его подключения через OAuth в этой организации отзываются, какие бы права ни были выбраны на странице согласия, и журнал записывает отзыв каждого агента. Агент получает 401; если человека снова сделают управляющим, агента подключают заново. Токены, выданные им в кабинете, от его роли не зависят и продолжают работать с прежними правами.

Гигиена

  • Держите токен в переменной окружения, а не в коде и не в репозитории.
  • На организацию действует не больше десяти одновременно действующих токенов, выданных в кабинете, и отдельно — не больше десяти подключений через OAuth. Одиннадцатый не выдастся, пока не отзовёте лишние.
  • Отозванный токен перестаёт работать сразу, но запись о нём остаётся: нужно уметь ответить, кто и когда завёл этот доступ.
  • У каждого токена видно время последнего использования — так находят забытые. Отметка обновляется не чаще раза в час, поэтому «только что» она не показывает.

Ошибки

КодКогда
401Заголовка нет, токен неизвестен или отозван, либо заменён повторным подключением того же приложения
403Роли не хватает, действие доступно только человеку, возможности нет в плане или срок плана вышел
404Объект принадлежит другой организации либо не существует
Вручай