快速入门
本教程将带您从一个已发布的模板一路走到签署完毕并已封存的 PDF。教程使用测试密钥,因此不会产生任何费用,每份文档都会带有 TEST 水印。
-
创建 API 密钥
章节标题“创建 API 密钥”API 密钥在控制台的 设置 › API 密钥 中创建。本教程请选择测试:这类密钥以
bf_test_开头。完整密钥只显示一次,请将其保存为环境变量。Terminal window export BONA_FIDE_API_KEY=bf_test_…每个请求都以
Authorization: Bearer …(或x-api-key: …)的形式发送密钥。请参阅身份验证。 -
找到您的模板
章节标题“找到您的模板”模板在控制台中设计(上传 PDF 或 Word 文档并放置字段,或在文档模式下撰写),然后发布。列出模板即可获取其 ID:
Terminal window curl https://api.bonafidesign.com/v1/templates \-H "Authorization: Bearer $BONA_FIDE_API_KEY"const res = await fetch('https://api.bonafidesign.com/v1/templates', {headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}` },});const { data } = await res.json(); // [{ id: 'tpl_…', name: 'Mutual NDA', latestVersion: 3, … }]import os, requestsAPI = "https://api.bonafidesign.com"headers = {"Authorization": f"Bearer {os.environ['BONA_FIDE_API_KEY']}"}templates = requests.get(f"{API}/v1/templates", headers=headers).json()["data"]GET /v1/templates/{id}/versions/latest返回该版本的roles、fields以及其variables的 JSON Schema。控制台的模板页面还有一个在 API 中使用面板,提供针对该版本的现成请求。 -
创建信封
章节标题“创建信封”POST /v1/envelopes会用您的变量渲染模板、锁定版本并开始流转。请为每个角色提供一位收件人(抄送角色为可选)。发送Idempotency-Key,确保重试不会重复发送。Terminal window curl https://api.bonafidesign.com/v1/envelopes \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: onboarding-8841" \-d '{"template": "tpl_…","version": "latest","variables": {"client": { "name": "Acme Robotics, Inc." },"effective_date": "2026-10-13"},"recipients": [{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev" }],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id"}'const res = await fetch('https://api.bonafidesign.com/v1/envelopes', {method: 'POST',headers: {Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`,'Content-Type': 'application/json','Idempotency-Key': 'onboarding-8841',},body: JSON.stringify({template: 'tpl_…',version: 'latest',variables: { client: { name: 'Acme Robotics, Inc.' }, effective_date: '2026-10-13' },recipients: [{ role: 'client', name: 'Jane Doe', email: 'jane@acme.dev' }],delivery: 'embedded',externalId: 'user_8841',dedupeOn: 'external_id',}),});if (res.status === 422) {// RFC 9457 problem: one entry per error, each with a JSON Pointer such as /variables/client/nameconsole.error((await res.json()).errors);}const envelope = await res.json(); // { id: 'env_…', status: 'sent', recipients: [{ id: 'rcp_…', … }] }res = requests.post(f"{API}/v1/envelopes",headers={**headers, "Idempotency-Key": "onboarding-8841"},json={"template": "tpl_…","version": "latest","variables": {"client": {"name": "Acme Robotics, Inc."}, "effective_date": "2026-10-13"},"recipients": [{"role": "client", "name": "Jane Doe", "email": "jane@acme.dev"}],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id",},)if res.status_code == 422:print(res.json()["errors"]) # [{"pointer": "/variables/client/name", "message": "…"}]envelope = res.json()响应为
201 Created,并返回该信封:{"id": "env_8Gm2kQ4rT1","organization": "org_…","template": "tpl_…","templateVersion": 3,"status": "sent","seal": "not_started","testMode": true,"recipients": [{"id": "rcp_5Jw0pLs9Xe","role": "client","name": "Jane Doe","email": "jane@acme.dev","order": 1,"status": "sent","verification": "email_otp","completedAt": null}],"documentHash": "9f2c…","sealedDocumentHash": null,"externalId": "user_8841","metadata": {},"createdAt": "2026-10-13T13:58:04.512Z","completedAt": null}delivery决定如何联系收件人:email(默认值)会在轮到每位收件人时通过电子邮件向其发送签署链接;embedded和none不发送任何电子邮件,由您自行开启签署会话(见下一步)。 -
让收件人签署
章节标题“让收件人签署”从您的后端为收件人签发一个签署会话。会话的有效期很短(
ttlSeconds,60 到 3600,默认 600),并且只能使用一次。Terminal window curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{"recipient": "rcp_5Jw0pLs9Xe","mode": "embedded","allowedOrigins": ["https://app.example.com"]}'将返回的
token(bfs_…)传给您的页面,并渲染 Web 组件:<script type="module" src="https://js.bonafidesign.com/v1"></script><bf-signing session="bfs_…"></bf-signing><script>document.querySelector('bf-signing').addEventListener('completed', (e) => console.log('signed', e.detail.envelope));</script>React 和 Vue 封装、事件以及安全模型,请参阅嵌入式签署。
Terminal window curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{ "recipient": "rcp_5Jw0pLs9Xe", "mode": "hosted", "returnUrl": "https://app.example.com/done" }'将签署人重定向到返回的
url(https://sign.bonafidesign.com/s/bfs_…)。托管页面以移动端优先设计,且无需账户。在默认的
email_otp验证方式下,签署人需要在提交前确认发送到其邮箱的 6 位验证码。在测试模式下,电子邮件只会发送给您组织的成员,因此测试时请使用您自己的邮箱地址。 -
在完成时接收通知
章节标题“在完成时接收通知”在 设置 › Webhook 中(或通过
POST /v1/webhook-endpoints)注册 Webhook 端点,并妥善保存whsec_…密钥。最后一位收件人签署后,您会收到envelope.completed,所有变量和填写的值都在data.values中。随后,已封存的 PDF 会通过envelope.sealed送达。import express from 'express';import { Webhook } from 'standardwebhooks';const wh = new Webhook(process.env.BONA_FIDE_WEBHOOK_SECRET!);const app = express();app.post('/hooks/bona-fide', express.raw({ type: 'application/json' }), async (req, res) => {const event = wh.verify(req.body, req.headers as Record<string, string>) as { type: string; data: any };if (event.type === 'envelope.completed') await saveValues(event.data.envelope.id, event.data.values);if (event.type === 'envelope.sealed') await fetchSealedPdf(event.data.envelope.id);res.sendStatus(204);});下载已封存的 PDF(附有完成证书并加盖时间戳的文档):
Terminal window curl -o signed.pdf "https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/document?version=sealed" \-H "Authorization: Bearer $BONA_FIDE_API_KEY"完整的事件列表、重试机制和手动验证,请参阅 Webhook。
正式上线
章节标题“正式上线”将测试密钥换成 bf_live_ 密钥。正式信封不带水印,电子邮件会发送给任何收件人,已完成的信封会计入您的方案用量(方案与限制)。密钥创建的所有内容都沿用该密钥的模式,列表只显示该模式下的内容,而且测试信封只会通知测试模式的 Webhook 端点,因此请同时注册一个正式端点。