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

Конверты и получатели

Конверт — это один договор на пути к подписанию: версия шаблона, сформированная с вашими переменными, получатели, которые с ней работают, и доказательства всего, что с ней происходит. Конверт создаётся вызовом POST /v1/envelopes.

Поле Тип Примечания
template tpl_… Обязательное
version число или "latest" По умолчанию latest; определяется и закрепляется при создании. Должна быть опубликована
variables объект Проверяется по JSON Schema версии
recipients массив По одному на роль (role, name, email; необязательно externalUserId, verification, fields для предзаполнения по идентификатору поля, order для изменения порядка подписания)
subject, message строка Используются в письмах с запросом подписи и показываются на странице подписания
delivery email · embedded · none По умолчанию email
expiresAt RFC 3339 Должно быть в будущем; в этот момент срок действия конверта истекает, и ссылки для подписания и ссылки наблюдателей перестают работать
cc массив Дополнительные получатели копии (name, email) сверх ролей CC шаблона; до 50
viewers массив Люди, которые следят за конвертом, не подписывая его (name, email, необязательно notifyOnSignature); количество на конверт ограничено тарифом
viewerDocumentAccess логическое значение Позволяет наблюдателям открывать документ на странице статуса. По умолчанию false (только статус); с тарифа Team
reminders объект { "enabled": false } отключает напоминания; { "enabled": true, "intervalHours": 24 } меняет интервал (от 1 до 720)
externalId строка Ваш собственный идентификатор, до 200 символов
dedupeOn "external_id" Вернуть существующий конверт с этим externalId вместо создания нового
metadata объект со строками До 500 символов на значение; возвращаются в конверте и в вебхуках

У каждого получателя должна быть роль из этой версии; у каждой роли, кроме CC, должен быть ровно один получатель. Ошибки сообщаются все сразу, с указателями вида /recipients/1/role или /recipients/0/fields/start_date.

Ответы: 201 с конвертом и заголовком Location; 200 с существующим конвертом и x-deduplicated: true, если сработал dedupeOn; 200 со сводкой пробного прогона для ?dry_run=true; 402, если рабочее пространство на тарифе Free исчерпало включённые конверты; 403 plan-upgrade-required, если число наблюдателей превышает лимит тарифа или viewerDocumentAccess не входит в тариф (Тарифы и лимиты). Пробные прогоны тоже проверяют лимиты тарифа.

Все поля, добавленные после первого выпуска, необязательны: запрос без них работает точно так же, как раньше.

Шаблон определяет, кто и в каком порядке подписывает. Для отдельного конверта это можно изменить, не трогая шаблон:

{
"template": "tpl_9fK2mQ7xLp",
"variables": { "client": { "name": "Jane Doe" } },
"recipients": [
{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev", "order": 2 },
{ "role": "company", "name": "Sam Lee", "email": "sam@bonafide.dev", "order": 1 },
{ "role": "witness", "name": "Kim Park", "email": "kim@acme.dev", "order": 1 }
],
"cc": [{ "name": "Legal", "email": "legal@acme.dev" }],
"viewers": [{ "name": "Alex Chen", "email": "alex@acme.dev", "notifyOnSignature": true }],
"reminders": { "enabled": true, "intervalHours": 48 },
"expiresAt": "2026-11-30T23:59:59Z"
}
  • Порядок: recipients[].order — шаг, на котором подписывает получатель; получатели с одинаковым номером подписывают одновременно. Если поле не указано, действует order роли из шаблона. Значения порядка — положительные целые числа; ролям CC порядок задать нельзя; каждой роли по-прежнему нужен получатель (чтобы у полей шаблона сохранился подписант); хотя бы один получатель должен подписывать. Событие envelope.created фиксирует routingOverridden: true.
  • CC: дополнительные получатели копии получают письмо с завершённым документом и никогда не подписывают. Они отображаются в recipients с kind: "cc" и ролью _cc.
  • Напоминания: тот, чья очередь, получает напоминание каждые intervalHours (по умолчанию — значение REMINDER_INTERVAL_HOURS развёртывания, 72), не более трёх раз; enabled: false отключает их. Напоминания относятся к доставке email.
  • Аутентификация подписанта задаётся для каждого получателя: verification переопределяет способ роли. Сейчас доступны none (только уникальная ссылка для подписания; по умолчанию для ролей, где способ не задан) и email_otp (ссылка плюс код, отправленный по почте); passkey и id_check отклоняются как пока недоступные. См. проверку подписанта.
  • Язык: locale у получателя, получателя копии или наблюдателя (или у конверта — для всех, у кого нет своего) задаёт язык их страницы подписания и писем — один из 50 языков подписания. Без него страница подписания следует языку браузера, а письма отправляются на английском.

Экран отправки в панели управления предлагает те же параметры: перенос шагов раньше или позже, флажок Подписывать одновременно, добавление получателей копии и наблюдателей, выбор аутентификации (Только ссылка по почте или Ссылка по почте + код) и языка для каждого подписанта, а также дату истечения срока и расписание напоминаний.

  • email: каждый получатель получает по почте ссылку на размещённую у нас страницу подписания, когда наступает его очередь. Получатели, которые ещё не подписали, раз в несколько дней получают напоминание (до трёх), а после завершения конверта письмо получают все.
  • embedded: подписантам письма не отправляются. Создайте сессию подписания, когда подписант находится в вашем продукте. Наблюдатели по-прежнему получают по почте ссылку на статус.
  • none: никаких писем (в том числе наблюдателям); используйте, если доставляете ссылки сами (сессии на нашей странице).

POST /v1/envelopes/{id}/recipients/{recipient}/resend отправляет по почте новую ссылку получателю, чья сейчас очередь (не чаще раза в минуту).

┌──────────── declined (a signer declined)
│
sent ─────┼──────────── voided (POST /v1/envelopes/{id}/void)
│
├──────────── expired (expiresAt passed)
│
└──────────── completed ──► seal: pending ──► sealed
status Значение
rendering Идёт подготовка
sent В процессе: получатели подписывают в порядке маршрутизации
completed Все получатели завершили работу. Начинается запечатывание
declined Получатель отказался; конверт завершается
voided Вы аннулировали конверт ({ "reason": "…" }); открытые сессии подписания перестают работать
expired expiresAt наступило до завершения

seal отслеживает запечатанный PDF: not_started, pending (завершён, идёт запечатывание), sealed или failed. Запечатывание никогда не блокирует завершение: конверт сначала завершается, а сразу после этого запечатывается.

{
"id": "rcp_5Jw0pLs9Xe",
"role": "client",
"name": "Jane Doe",
"email": "jane@acme.dev",
"order": 1,
"status": "viewed",
"verification": "email_otp",
"completedAt": null
}

status получателя — pending (его очередь ещё не наступила), sent, viewed, completed или declined, а kind — тип роли: signer, approver, form_filler или cc. Маршрутизация идёт по order (из роли или из переопределения при отправке): все получатели с наименьшим незавершённым номером действуют параллельно, а следующая группа начинает, когда они закончат. Получатели копии никогда не блокируют маршрутизацию.

Наблюдатель следит за конвертом, не подписывая его: руководитель, помощник юриста, менеджер по работе с клиентом на стороне клиента. Наблюдатели не являются получателями. У них нет роли и очереди, они никогда ничего не блокируют и не завершают и никогда не появляются в списке подписантов в сертификате.

  • Когда конверт отправляется (или когда вы добавляете наблюдателей позже через POST /v1/envelopes/{id}/viewers), каждый наблюдатель получает фирменное письмо со ссылкой на страницу статуса только для чтения: название конверта, отправитель, каждый шаг с именами получателей, ролями, статусом и метками времени — в реальном времени по мере подписания. Адреса электронной почты получателей не показываются.
  • Наблюдатели снова получают письмо, когда конверт завершён, отклонён или аннулирован, а также после каждой подписи, если notifyOnSignature равно true (по умолчанию выключено).
  • Документ отображается на странице, только если задано viewerDocumentAccess: true (с тарифа Team): оригинал, пока идёт подписание, и запечатанный PDF после запечатывания. Иначе наблюдатели видят только статус.
  • DELETE /v1/envelopes/{id}/viewers/{viewer} отзывает наблюдателя: все отправленные ему ссылки сразу перестают работать.
  • Ссылки — это персональные URL-адреса, дающие доступ. Хранится только SHA-256 токена каждой ссылки. Ссылка работает до истечения срока конверта (не более 90 дней), в течение 30 дней после завершения конверта и никогда — после отзыва наблюдателя.
  • Добавление, открытие (первый просмотр страницы и документа) и отзыв записываются в журнал аудита как viewer.added, viewer.viewed, viewer.document_viewed и viewer.revoked, а значит, и в сертификат.

Ответы по отдельному конверту (создание, получение, аннулирование) содержат их список:

{
"viewers": [
{
"id": "vwr_2Hc8sQ1nVt",
"name": "Alex Chen",
"email": "alex@acme.dev",
"notifyOnSignature": true,
"status": "active",
"invitedAt": "2026-10-13T13:58:04.512Z",
"firstViewedAt": "2026-10-13T14:05:41.090Z",
"lastViewedAt": "2026-10-13T15:12:09.337Z",
"revokedAt": null,
"createdAt": "2026-10-13T13:58:04.512Z"
}
],
"viewerDocumentAccess": false
}

Число наблюдателей на конверт зависит от тарифа (Free — 1, Pay-as-you-go — 2, Team — 5, Business — 20, Platform — без ограничений); получатели копии не учитываются. Отозванные наблюдатели освобождают своё место.

GET /v1/envelopes/{id}/document?version=… скачивает PDF, а его SHA-256 передаётся в x-document-sha256:

version Файл
original (по умолчанию) Сформированный документ в том виде, в каком он был отправлен на подпись
sealed Итоговый PDF: значения встроены в страницы, добавлен сертификат о завершении, метка времени документа. После envelope.sealed
certificate Только сертификат о завершении

documentHash конверта — это SHA-256 оригинала, а sealedDocumentHash — SHA-256 запечатанного файла; именно их ищет проверка.

Каждое действие — это событие в цепочке хешей конверта: hash = SHA-256(prevHash ‖ canonical JSON of the event), где первый prevHash — 64 нуля. GET /v1/envelopes/{id}/events возвращает события и проверяет цепочку:

{
"data": [
{
"id": "evt_…",
"envelope": "env_8Gm2kQ4rT1",
"seq": 1,
"type": "envelope.created",
"createdAt": "2026-10-13T13:58:04.512Z",
"recipient": null,
"actor": { "kind": "api_key", "id": "…", "name": null, "email": null },
"ip": "203.0.113.7",
"userAgent": null,
"data": { "template": "tpl_…", "templateVersion": 3, "documentHash": "9f2c…" },
"hash": "4b1d…",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000"
}
],
"chain": { "valid": true, "brokenAt": null }
}

Помимо типов событий вебхуков, в журнале есть записи только для аудита, например session.created, recipient.verified, recipient.reminded и события наблюдателей (тип субъекта viewer, когда наблюдатель открывает свою страницу).

Для отображения статуса в реальном времени в интерфейсе служит GET /v1/envelopes/{id}/events/stream — поток событий, отправляемых сервером (SSE): имя события в каждом кадре — это type события, а его идентификатор — seq; чтобы продолжить, переподключитесь с Last-Event-ID.

GET /v1/envelopes фильтрует по status, seal, template и q (свободный текст по именам и адресам электронной почты получателей, externalId и идентификатору конверта). Как и любой список, он использует постраничную навигацию по курсору:

{ "data": [ … ], "hasMore": true, "nextCursor": "…" }

Передайте nextCursor обратно как cursor; limit — от 1 до 100 (по умолчанию 20).