跳转到内容

信封与收件人

信封是一份正在走签署流程的合同:用您的变量渲染出的模板版本、需要处理它的收件人,以及所发生的一切的证据。使用 POST /v1/envelopes 创建信封。

字段 类型 说明
template tpl_… 必填
version 数字或 "latest" 默认为 latest;在创建时解析并锁定。必须是已发布的版本
variables 对象 依据该版本的 JSON Schema 进行校验
recipients 数组 每个角色一位(role、name、email;可选 externalUserId、verification、按字段 ID 预填的 fields,以及用于更改签署顺序的 order)
subject、message 字符串 用于签署邮件,并显示在签署页面上
delivery email · embedded · none 默认为 email
expiresAt RFC 3339 必须是将来的时间;届时信封过期,签署链接和查看者链接随之失效
cc 数组 模板抄送角色之外的额外抄送收件人(name、email);最多 50 个
viewers 数组 无需签署、只关注信封的人(name、email,可选 notifyOnSignature);每个信封的数量上限取决于方案
viewerDocumentAccess 布尔值 允许查看者在其状态页面上打开文档。默认为 false(仅显示状态);Team 及以上方案可用
reminders 对象 { "enabled": false } 关闭提醒;{ "enabled": true, "intervalHours": 24 } 更改提醒间隔(1 到 720)
externalId 字符串 您自己的 ID,最多 200 个字符
dedupeOn "external_id" 如果已存在具有该 externalId 的信封,则返回该信封而不新建
metadata 字符串值对象 每个值最多 500 个字符;随信封和 Webhook 一并返回

每位收件人都需要对应该版本中的一个角色;每个非抄送角色必须恰好有一位收件人。错误会一并报告,并附带 /recipients/1/role 或 /recipients/0/fields/start_date 这样的指针。

响应:201,返回信封和 Location 请求头;当 dedupeOn 匹配时返回 200、已有的信封和 x-deduplicated: true;对于 ?dry_run=true 返回 200 和试运行摘要;当 Free 工作区已用完所含信封时返回 402;当查看者超出方案额度或方案不包含 viewerDocumentAccess 时返回 403 plan-upgrade-required(方案与限制)。试运行同样会检查方案限制。

首个版本之后新增的字段都是可选的:不带这些字段的请求,行为与之前完全一致。

模板规定了谁按什么顺序签署。对于单个信封,您可以在不修改模板的情况下更改这些设置:

{
"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。顺序必须为正整数;抄送角色不能设置顺序;每个角色仍然需要有收件人(这样模板中的字段才有对应的签署人);至少要有一位收件人签署。envelope.created 事件会记录 routingOverridden: true。
  • 抄送:额外的抄送收件人会收到已完成文档的电子邮件,但从不签署。他们以 kind: "cc" 和角色 _cc 出现在 recipients 中。
  • 提醒:每隔 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 }
}

除了 Webhook 事件类型之外,审计记录中还有仅用于审计的条目,例如 session.created、recipient.verified、recipient.reminded 以及查看者事件(查看者打开其页面时,操作者类型为 viewer)。

如需在界面中显示实时状态,GET /v1/envelopes/{id}/events/stream 提供服务器发送事件(SSE)流:每帧的事件名称为事件的 type,ID 为 seq;使用 Last-Event-ID 重新连接即可从断点继续。

GET /v1/envelopes 可按 status、seal、template 和 q(对收件人姓名和电子邮件、externalId 以及信封 ID 进行全文搜索)筛选。与所有列表一样,它采用游标分页:

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

将 nextCursor 作为 cursor 传回即可;limit 为 1 到 100(默认 20)。