Аутентификация
Токен
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. Человек при этом токен не видит и никуда не копирует.
- Клиент обращается к
/mcpбез токена, получает401и читает описание ресурса/.well-known/oauth-protected-resource/mcp, а из него — описание сервера авторизации `/.well-known/oauth-authorization-server`. - Регистрируется сам: `POST /api/oauth/register` (Dynamic Client Registration, только публичные клиенты,
token_endpoint_auth_method: none). Записи в базе при этом не появляется:client_id— это подписанные сервисом название приложения и его адреса возврата. - Открывает в браузере
https://vruchay.ru/oauth/authorizeсcode_challenge(S256). Не вошедшего в кабинет сначала просят войти. - Страница согласия показывает, какое приложение просит доступ, к какой организации и на какой адрес вернётся разрешение. Человек выбирает права — «Выпускать документы» (
member) или «Полный доступ» (admin) — и разрешает (`POST /api/oauth/authorize`) или отказывает. - Клиент меняет одноразовый код на токен: `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 | Объект принадлежит другой организации либо не существует |