Способы выдачи
Свёрстанный документ попадает к людям одним из четырёх путей: пакетом по списку, через форму по ссылке, через форму на сайте организации или по одному через API. Письма — не отдельный путь, а доставка: ими рассылают выпущенное по списку, а форма и API отправляют письмо сами. Здесь — когда что выбирать, как настроить каждый путь через MCP и REST, что видит получатель и когда выдача останавливается.
Прежде чем писать свою интеграцию, найдите свой случай в таблице ниже. Форма и API сами принимают заявку, выпускают документ, списывают квоту, не выдают второй документ тому же человеку и шлют письмо — свой сервер между сайтом и «Вручай» для этого не нужен.
Какой способ выбрать
| Способ | Когда подходит | Кто запускает | Что получает человек | Квота |
|---|---|---|---|---|
| По списку | Список известен заранее: олимпиада, выпуск курса, конференция | Организатор или агент, один раз на весь список | Файл из архива от организатора или письмо с PDF | Списывается при выпуске, по числу отмеченных строк |
| Форма по ссылке | Своего сайта нет; ссылку раздают в чат, в письмо или QR-кодом на экране | Сам участник | Страницу «Вручай», где вводит имя и почту и сразу скачивает документ; копию — письмом | Документ на каждую заявку |
| Форма на сайте | У мероприятия или школы есть свой сайт — Тильда, WordPress, Битрикс, любая страница, в том числе закрытая страница личного кабинета | Сам участник | Кнопку «Получить документ» на странице сайта, дальше — как у формы по ссылке | Документ на каждую заявку |
| API на одного | Документ выдаёт программа по событию: CRM, учебная платформа, бот | Ваша программа | Письмо с PDF или ссылку, которую покажет ваша программа | Документ на каждый запрос |
Пути совмещаются: одна грамота может уйти пакетом по списку, а опоздавшие получат её через форму по ссылке. Всё выданное любым путём попадает в один реестр с кодом проверки и QR.
По списку
| Шаг | MCP | REST |
|---|---|---|
| Загрузить таблицу | import_recipients | `POST /api/documents/{id}/recipients/import` |
| Проверить | validate_recipients | `POST /api/documents/{id}/validation` |
| Выпустить | start_generation | `POST /api/documents/{id}/generate` |
| Дождаться | get_job | `GET /api/jobs/{jobId}` |
| Забрать | get_download_link | `POST /api/jobs/{jobId}/archive-link` или `GET /api/jobs/{jobId}/archive` |
В выпуск попадают отмеченные строки. Ссылка на архив открывается в браузере без входа и живёт час; format: "pdf" склеивает все документы в один файл для печати, name задаёт имена файлов в архиве ("%name", "%number %name"). Дальше документы раздают сами или рассылают письмами (ниже).
Проверка остатка — до постановки задания: к выпущенному прибавляется бронь незаконченных заданий. Не хватает документов или вышел срок плана — выпуск не начнётся, ответ 400.
Форма по ссылке
Страница на адресе «Вручай» для тех, у кого нет своего сайта или нет времени его трогать. Нужны права «Полный доступ» и возможность tilda в плане.
MCP:
{
"kind": "link",
"name": "Конференция, сертификат участника",
"documentIds": ["9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"],
"formFields": ["name"],
"singleFilePerEmail": true
}— аргументы setup_form. REST — тот же объект в `POST /api/integrations/tilda`.
В ответе connect.formUrl — ссылка вида https://vruchay.ru/f/{token}, а если у организации подключён и подтверждён свой домен для форм (`PATCH /api/org/domain`) — на нём: https://forms.school.ru/f/{token}. Её и отдают людям.
- Документ у формы по ссылке ровно один.
formFields— что спросить, кроме почты: имена полей документа, по умолчанию["name"]. Служебные и постоянные поля спросить нельзя — участник не должен напечатать на листе своё.authModeу формы по ссылке по умолчаниюnone: человек открывает ссылку и сразу получает документ, от перебора её держатdailyLimitиsingleFilePerEmail.email_code— почту подтверждают шестизначным кодом из письма.- Документ отдаётся сразу двумя путями — кнопкой скачивания и письмом:
showDownloadиsendEmailу формы по ссылке всегдаtrue. singleFilePerEmail: true(по умолчанию) — повторная заявка с того же адреса получает уже выданный документ, второй не выпускается. Открывается он только после кода, который приходит на адрес выдачи, — даже приauthMode: "none".dailyLimit— предел заявок за последние 24 часа, по умолчанию 500.
Что видит участник: страницу с названием организации и документа, поля из formFields, почту и согласие на обработку данных; затем код из письма (если он нужен) и документ — кнопкой скачивания и письмом. В таблице получателей появляется неотмеченная строка с source: "link", документ — в реестре.
Форма на сайте
Кнопка «Получить документ» на странице организации. Нужны права «Полный доступ» и возможность tilda в плане.
MCP — setup_form:
{
"kind": "site",
"name": "Сайт школы",
"documentIds": ["9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"],
"allowedDomains": ["example.ru"]
}REST — тот же объект в POST /api/integrations/tilda.
allowedDomains— домены страниц с формой, до 20. Адреса приводятся к домену сами (https://www.example.ru/events→example.ru), поддомены разрешённого домена тоже считаются своими. С других адресов форма заявки не примет — поэтому открытая с диска страница или чужой тестовый стенд работать не будут.documentIds— до 50 документов; на странице может стоять кнопка любого из них.
В ответе connect.embedHtml — готовый HTML для каждого документа: блок с кнопкой и подключение стилей и скрипта формы. Куда вставлять:
- Тильда — блок «HTML-код» (T123) на нужной странице;
- WordPress — блок «Произвольный HTML» в редакторе страницы;
- Битрикс — визуальный редактор в режиме HTML или включаемая область;
- обычная страница — в любое место внутри
<body>.
Скрипт защищён от повторной загрузки: две кнопки на одной странице подключают его один раз. Готовые варианты для Тильды, WordPress и Битрикса показывает кабинет: документ → «Выпуск» → «Форма на сайте».
Что видит участник: кнопку на странице, по нажатию — окно с полями, почтой, согласием и кодом из письма; затем документ кнопкой скачивания и письмом.
Закрытая страница и личный кабинет
Форма работает и внутри личного кабинета сайта — например, на закрытой странице Tilda Members, куда пускают только участников мероприятия. Свой сервер для этого не нужен. Кто может открыть страницу, решает сайт: группы и права Тильды «Вручай» не читает.
- Имя и почта подставляются сами. Скрипт формы ищет их по порядку: атрибуты блока
data-nameиdata-email(их заполняет своим шаблоном сайт с собственным кабинетом — WordPress, Битрикс), поля личного кабинета Тильдыma_nameиma_email, объектwindow.tildamembers. На Тильде ничего дописывать не нужно. Не нашёл — человек введёт сам. - ФИО можно поправить. По кнопке открывается окно «Проверьте данные»: имя и почта уже вписаны, человек исправляет опечатку, отмечает согласие и получает документ.
allowEdit: falseделает поля окна только для чтения, аprefillFromAccount: falseвыключает подстановку. Запрет правки — удобство, не защита: заявку шлёт браузер посетителя. showVerifyLink: true— ссылка на проверку подлинности в окне успеха и кнопки «поделиться» ею (showShare, по умолчанию включены, но без ссылки не видны).requireAccount: true— заявка принимается, только если страница передала почту учётной записи, то есть человек вошёл в кабинет. Копия кнопки на открытой странице документ не выдаст.checkList: true— выдавать только тем, чья почта есть в таблице получателей документа.- Документ по кнопке, без писем —
authMode: "none",sendEmail: false,showDownload: true. БезauthMode: "none"форма на сайте сначала пришлёт код на почту: по умолчанию у неёemail_code. Текст после выдачи без письма сам становится «Спасибо! Документ готов»; свой — вsuccessMessage. Почта в окне всё равно обязательна, но из кабинета она подставится сама; повторная заявка того же человека получит уже выданный документ (singleFilePerEmail) — после кода на адрес, куда его выдали.
{
"kind": "site",
"name": "Конференция, закрытая страница",
"documentIds": ["9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"],
"allowedDomains": ["academy.example.ru"],
"requireAccount": true,
"authMode": "none",
"sendEmail": false,
"showDownload": true
}— аргументы setup_form; REST — тот же объект в POST /api/integrations/tilda. Код вставки из connect.embedHtml — в блок «HTML-код» (T123) закрытой страницы.
Форма Тильды без нашего скрипта
У Тильды есть второй путь — без кода на странице: обычная форма Тильды отправляет данные прямо на адрес https://vruchay.ru/api/v1/tilda-create («Свой скрипт для приёма данных»), со скрытыми полями secure (токен формы) и doc_id (id документа), полями mask_name, mask_email и галочкой consent. Пошаговая инструкция — в кабинете там же.
Управление формами
| Действие | MCP | REST |
|---|---|---|
| Список с готовыми ссылками и кодом | list_forms | `GET /api/integrations/tilda` |
Изменить или выключить (active: false) | setup_form с integrationId | `PATCH /api/integrations/tilda/{id}` |
| Заявки и причины отказов | api_request | `GET /api/integrations/tilda/requests` |
| Удалить | api_request | `DELETE /api/integrations/tilda/{id}` |
Вид формы (kind) после создания не меняется. Выключенная форма перестаёт принимать заявки сразу, код на странице править не нужно.
Один документ по API
Ваша программа присылает имя — в ответе готовый документ.
- MCP:
issue_documentсdocumentId,data,email,sendиidempotencyKey. - REST: `POST /api/documents/{id}/issue` с заголовком
Idempotency-Key; состояние — `GET /api/documents/{id}/issue/{jobId}`.
curl -X POST "https://vruchay.ru/api/documents/$DOCUMENT_ID/issue" \
-H "Authorization: Bearer $VRUCHAY_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: lms-completion-48213" \
-d '{"data":{"name":"Иванова Анна Сергеевна","hours":"72"},"email":"ivanova@example.com","send":true}'Idempotency-Key— ваш идентификатор события, 8–100 знаков. Повтор с тем же ключом отдаёт первый документ, а не выпускает второй.201— документ готов: код проверки, номер, ссылка на страницу проверки и ссылка получателя на PDF (recipientUrl, 30 дней).202— опрашивайтеstatusUrlраз в 1–2 секунды.- Поля
data— колонки и поля листа документа; их список отдаётGET /api/documents/{id}/fields(разделissue).nameобязательно. - Письмо (
send: true) уходит по шаблону документа и требует возможностиmailing. - Предел — 120 документов в минуту на организацию.
Что видит получатель: письмо с документом (если send: true) или то, что покажет ваша программа, — ссылку recipientUrl или код проверки.
Письма
Рассылка уже выпущенных документов по строкам таблицы. Нужна возможность mailing в плане.
| Шаг | MCP | REST |
|---|---|---|
| Шаблон письма | set_mail_template | `POST /api/mail/templates/{documentId}` |
| Пробное письмо | api_request | `POST /api/mail/templates/{documentId}/test-send` |
| Кому уйдёт и кому нет | get_mail | `POST /api/mailing/audience` |
| Разослать, дослать новым | send_mail | `POST /api/mailing/send` — уже получившие пропускаются |
| Повторить недоставленные | send_mail с onlyFailed | `POST /api/mailing/resend` |
| Судьба каждого письма | get_mail | `GET /api/mailing/log` |
- В теме и тексте — подстановки
%nameи другие поля строки.attachGeneratedFile(по умолчаниюtrue) прикладывает PDF. - PDF тяжелее, чем принимает почта, письмо не останавливает: оно уходит без файла, с пометкой и кнопкой «Открыть документ», в журнале —
sent. Чтобы файл прикладывался, держите фон и картинки листа лёгкими —check_sheetпредупредит (heavy_images). - Письма ставятся отмеченным строкам с выпущенным документом; кому не поставлено — в
skippedс причиной. - Без своего отправителя письма идут с общего адреса сервиса: не больше 300 за раз и 500 за сутки на организацию. Со своего подтверждённого домена предела нет — домен подключает управляющий в кабинете.
- Пробное письмо по токену приходит тому, кто выдал токен, а не на адрес из запроса.
- Рассылка необратима: перед
send_mailпокажите человеку, кому и сколько писем уйдёт.
Форма и API шлют письмо сами (sendEmail у формы, send у API) по тому же шаблону документа.
Какой домен где
Слово «домен» в API встречается в четырёх разных настройках, и они друг от друга не зависят:
| Настройка | Зачем | Где |
|---|---|---|
| Домены страниц формы на сайте | С каких сайтов форма принимает заявки; ничего подключать не нужно | allowedDomains у `POST /api/integrations/tilda` |
| Свой домен для форм по ссылке | Ссылка https://forms.school.ru/f/{token} вместо vruchay.ru; работает после проверки записей DNS | `PATCH /api/org/domain`, `POST /api/org/domain/check` |
| Домен отправки писем | Письма с адреса организации и без предела общего адреса; записи SPF и DKIM в DNS | `POST /api/mail/domains`, затем отправитель — `POST /api/mail/senders` |
| Домен страницы проверки | Пока только хранится: ссылки и QR в документах ведут на vruchay.ru | `PATCH /api/org/verify-domain` |
Один и тот же поддомен под формы и под письма подключать не нужно: у форм запись указывает на «Вручай», у писем — на почтовый сервис.
Когда выдача останавливается
| Причина | По списку | Форма | API |
|---|---|---|---|
Остаток кончился (left: 0) | 400 до постановки задания | Участник видит «Выдача документов по этой форме сейчас недоступна — напишите организатору»; заявка — rejected | 400 сразу |
Срок плана вышел (expired: true) | То же | То же | То же |
Суточный предел формы (dailyLimit) | — | «Сегодня выдача документов по этой форме уже недоступна. Попробуйте завтра» | — |
Форма выключена (active: false) | — | Заявки не принимаются | — |
Нет mailing в плане | Рассылка — 403 | Документ выдаётся кнопкой скачивания, письмо не уходит (и копия организатору тоже); причина — в error заявки | 403 при send: true |
Квота у формы бронируется в момент заявки (при подтверждении кодом — в момент ввода кода), поэтому участник узнаёт об отказе сразу. Отказы видны организатору в журнале заявок и в журнале действий (issue.refused). Уже выданные документы при любом из этих условий остаются действительными и проверяются по QR.
Остаток и срок заранее показывает get_account или `GET /api/org/usage`.