将电子签名集成到您的技术栈
发送信封、跟踪签名、接收 webhooks。简单的 REST API、OpenAPI 3.0、curl/Node/Python 示例 — 所有内容都可在数小时内将 Certyneo 连接到您的 HRIS、CRM 或业务软件。
快速开始
三个步骤:从参数设置中创建 API 密钥,将您的 PDF 编码为 base64,然后发送。响应包含 `signUrl`,您可以直接与收件人分享。
# 1. Upload the PDF (multipart) and capture the returned document id.
DOC_ID=$(curl -s -X POST https://certyneo.com/api/v1/documents \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@contrat.pdf" | jq -r .id)
# 2. Create a DRAFT envelope referencing the uploaded document.
ENV_ID=$(curl -s -X POST https://certyneo.com/api/v1/envelopes \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "{
\"subject\": \"Contrat de prestation\",
\"documentIds\": [\"$DOC_ID\"],
\"recipients\": [
{ \"email\": \"client@example.com\", \"name\": \"Marie Dubois\", \"role\": \"SIGNER\" }
]
}" | jq -r .id)
# 3. Dispatch the envelope — this sends the invitation email/SMS.
curl -X POST https://certyneo.com/api/v1/envelopes/$ENV_ID/send \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"// Plain fetch, no SDK to install.
const auth = { Authorization: `Bearer ${process.env.CERTYNEO_API_KEY}` };
// 1. Upload the PDF (multipart).
const fd = new FormData();
fd.append("file", new Blob([pdfBuffer], { type: "application/pdf" }), "contrat.pdf");
const doc = await fetch("https://certyneo.com/api/v1/documents", {
method: "POST", headers: auth, body: fd,
}).then((r) => r.json());
// 2. Create the DRAFT envelope.
const envelope = await fetch("https://certyneo.com/api/v1/envelopes", {
method: "POST",
headers: { ...auth, "Content-Type": "application/json" },
body: JSON.stringify({
subject: "Contrat de prestation",
documentIds: [doc.id],
recipients: [
{ email: "client@example.com", name: "Marie Dubois", role: "SIGNER" },
],
}),
}).then((r) => r.json());
// 3. Dispatch — this triggers the invitation channel for every recipient.
await fetch(`https://certyneo.com/api/v1/envelopes/${envelope.id}/send`, {
method: "POST", headers: auth,
});
console.log(envelope.id);import os, requests
auth = {"Authorization": f"Bearer {os.environ['CERTYNEO_API_KEY']}"}
# 1. Upload the PDF (multipart).
with open("contrat.pdf", "rb") as f:
doc = requests.post(
"https://certyneo.com/api/v1/documents",
headers=auth,
files={"file": ("contrat.pdf", f, "application/pdf")},
).json()
# 2. Create the DRAFT envelope.
envelope = requests.post(
"https://certyneo.com/api/v1/envelopes",
headers={**auth, "Content-Type": "application/json"},
json={
"subject": "Contrat de prestation",
"documentIds": [doc["id"]],
"recipients": [
{"email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER"},
],
},
).json()
# 3. Dispatch — this triggers the invitation channel for every recipient.
requests.post(
f"https://certyneo.com/api/v1/envelopes/{envelope['id']}/send",
headers=auth,
)
print(envelope["id"])从您的工具尝试 API
Postman 集合和 RapidAPI 卡片从记录此页面的 OpenAPI 规范生成。这三者保持与真实 API 对齐,逐端点对齐,而不是在第一次添加时分散。
信封
创建、发送、状态跟踪、取消。一个信封可以包含多个文档和多个签署人(并行或顺序)。
网络钩子
所有信封和收件人事件(`envelope.sent`、`recipient.signed`、`envelope.completed` 等)都交付到您选择的 URL——完整列表见 /developers/webhooks。每个 payload 上使用 HMAC SHA-256 验证来源。
简单身份验证
Bearer 令牌。每个环境一个密钥(测试/生产)。可以立即撤销。限制为每个密钥每分钟 100 个请求,突发 200 个,干净的 429 响应带有 Retry-After 标头。
可用端点
53 条公开路由:账户、文档、信封、模板、webhooks、电子印章、API 密钥和计费。所有这些都接受 Bearer token 并返回 JSON。
| 方法 | 路径 | 描述 |
|---|---|---|
| GET | /api/v1/account/me | 已认证的调用者身份(id、电子邮件、套餐):不需要作用域的身份标识符测试 |
| GET | /api/v1/sandbox | 统计使用测试密钥创建的数据(30 天后自动删除) |
| DELETE | /api/v1/sandbox | 删除使用测试密钥创建的所有数据,不影响真实数据 |
| POST | /api/v1/documents | 上传 PDF(multipart):返回文档 id |
| GET | /api/v1/documents | 列出文档 |
| GET | /api/v1/documents/{id} | 读取文档元数据 |
| DELETE | /api/v1/documents/{id} | 删除文档 |
| GET | /api/v1/envelopes | 列出信封(使用 ?status= 和 ?limit= 过滤) |
| POST | /api/v1/envelopes | 创建信封(状态为 DRAFT):从 templateId 或 documentIds 加上可选的 fields 数组创建 |
| GET | /api/v1/envelopes/{id} | 读取信封状态 |
| PATCH | /api/v1/envelopes/{id} | 修改 DRAFT 信封 |
| DELETE | /api/v1/envelopes/{id} | 删除 DRAFT 信封(发送后返回 409:改为取消) |
| POST | /api/v1/envelopes/{id}/send | 发送 DRAFT 信封:发送邀请 |
| POST | /api/v1/envelopes/{id}/void | 取消已发送但尚未完全签署的信封:待处理的签署人将收到通知 |
| POST | /api/v1/envelopes/{id}/remind | 根据请求重新提醒等待已发送信封的签署人(可选指定一个收件人) |
| GET | /api/v1/envelopes/{id}/audit-trail | 下载 eIDAS 审计日志 PDF |
| POST | /api/v1/envelopes/{id}/embed-url | 返回收件人的签署URL,并为所请求的来源提供框架授权。应在点击时调用:授权有效期为两小时。 |
| GET | /api/v1/audit-anchors/{root} | 公开:已锚定的审计批次元数据,或使用 ?format=ots 的证明文件 .ots(无需认证) |
| POST | /api/v1/audit-anchors/verify | 公开:验证审计条目及其证明与已锚定的 Merkle 根(无需认证,不透露任何信息) |
| GET | /api/v1/envelopes/{id}/signed-document | 下载已签署的 PDF(COMPLETED 后) |
| GET | /api/v1/envelopes/bulk | 列出您的批量发送 |
| POST | /api/v1/envelopes/bulk | 批量发送:从模板和 CSV 创建 N 个信封(仅限标准/商业版) |
| GET | /api/v1/envelopes/bulk/{id} | 批量发送进度:计数器、每行失败、已创建的信封 |
| GET | /api/v1/templates | 列出可重复使用的信封模板 |
| POST | /api/v1/templates | 创建模板(文件、角色、定位字段) |
| GET | /api/v1/workspaces | 列出您可以在其中创建信封的工作空间 |
| POST | /api/v1/sepa-mandates | 生成 SEPA 授权书的 PDF 及其 DRAFT 信封、字段已放置 |
| POST | /api/v1/payroll-adapters/normalize | 将工资单 CSV(Silae、Sage Paie、PayFit、Lucca)标准化为批量发送格式 |
| POST | /api/v1/ag-copropriete | 创建共有产权业主大会信封(决议和产权份额) |
| POST | /api/v1/ag-copropriete/{envelopeId}/votes | 记录共有产权人在大会决议上的投票 |
| POST | /api/v1/ag-copropriete/{envelopeId}/tally | 开票大会:按决议的结果、按产权份额加权 |
| GET | /api/v1/videos/{videoId} | 下载保留的身份验证视频:RGPD 访问权(第 15 条) |
| GET | /api/v1/webhooks | 列出 webhook |
| POST | /api/v1/webhooks | 注册 webhook:仅返回一次签名密钥 |
| GET | /api/v1/webhooks/{id} | 读取 webhook 订阅 |
| PATCH | /api/v1/webhooks/{id} | 修改 URL、事件或活跃状态 |
| DELETE | /api/v1/webhooks/{id} | 取消注册 webhook |
| POST | /api/v1/seals | 在文件上应用合格电子印章 |
| GET | /api/v1/seals/{id} | 读取印章状态 |
| GET | /api/v1/seals/{id}/certificate | 下载印章证书 |
| GET | /api/v1/payslips/workspaces | 工资单:此密钥分配、由客户持有或委托的空间(会计事务所、工资管理公司) |
| GET | /api/v1/payslips/employees | 工资单:员工登记册,包括那些拒绝电子交付的员工(应交付纸质工资单) |
| PUT | /api/v1/payslips/employees | 工资单:添加或更新员工登记簿中的员工(从不删除) |
| POST | /api/v1/payslips | 将工资单(PDF)提交到员工的保险箱中:密封、保存50年、重试无重复 |
| GET | /api/v1/payslips | 列出已提交的工资单及其查阅证明 |
| GET | /api/v1/keys | 列出API密钥 |
| POST | /api/v1/keys | 创建API密钥:密钥仅显示一次 |
| PATCH | /api/v1/keys/{id} | 重命名或撤销密钥 |
| DELETE | /api/v1/keys/{id} | 删除密钥 |
| GET | /api/v1/billing/usage | 当前期间的消耗量和预计成本 |
| GET | /api/v1/status | 服务状态 |
| GET | /api/v1/health | 健康检查:数据库、队列和对象存储 |
| GET | /api/v1/openapi | 机器可读的OpenAPI规范 |
信封模板
模板一次性记录 PDF、角色和签名字段的位置,然后在每次发送时重用:在 templateId 中传递其标识符而不是 documentIds,已定位的字段会被复制到创建的信封上。
- • 模板从仪表板创建(模板 → 新建模板),您可以在其中上传文档然后用鼠标定位字段——这是最简单的方法。API 也允许通过 POST /api/v1/templates 创建模板,提供文档、角色和字段;注意,字段在其中用绝对坐标定位(页、x、y、宽、高),因此您需要了解 PDF 的页面布局。
- • 在尚未记录任何模板的账户上,GET /api/v1/templates 返回空列表。这是正常行为,不是身份验证缺陷。
- • 列表仅包含属于 API 密钥所有者的模板。由同事创建的模板不会出现在其中,即使在共享工作区内:请从拥有该模板的账户生成密钥。
- • templateId 和 documentIds 互相排斥:发送其中之一,永远不要同时发送两者或都不发送。
- • 至少提供与模板签署人角色数量相等的 SIGNER 收件人,否则创建会被拒绝并返回 400。列表返回的 signerCount 字段指示预期数量。
- • 模板的签名级别被信封继承,除非请求明确传递 signatureLevel。
# 1. Discover the templates saved on this account.
curl -s https://certyneo.com/api/v1/templates \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
# {
# "data": [
# { "id": "cmdq7f4k80001s6y2h1xa9pl3", "name": "Contrat de prestation",
# "signerCount": 2, "documentCount": 1, "signatureLevel": "SIMPLE" }
# ],
# "pagination": { "page": 1, "pageSize": 20, "total": 1, "pages": 1 }
# }
#
# An empty "data" array means no template exists on this account yet —
# create one from the dashboard, it is not an authentication problem.
# 2. Create the envelope FROM the template: no documentIds and no field
# coordinates, both are carried by the template. Pass one SIGNER
# recipient per signer role, in the template's role order.
curl -X POST https://certyneo.com/api/v1/envelopes \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"subject": "Contrat de prestation",
"templateId": "cmdq7f4k80001s6y2h1xa9pl3",
"recipients": [
{ "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" },
{ "email": "legal@example.com", "name": "Paul Martin", "role": "SIGNER" }
]
}'
# 3. The envelope is DRAFT at this point — POST /envelopes/{id}/send
# dispatches it, exactly as in the quick-start above.从 Power Automate 或 Zapier
我们无代码连接器中的"创建信封"操作仅涵盖模板路径:"模板"字段为必填项。对于每次执行都变化的临时文档,请使用"上传文档"操作,然后使用原始 HTTP 操作调用 POST /api/v1/envelopes,传递返回的 documentIds。
文档发送:接受两种形式
POST /api/v1/documents 接受文件的两种方式(可任选)。两种情况下适用相同的控制:允许的类型、50 MB 上限、二进制签名验证和防病毒分析。
- • 以 multipart/form-data 形式,使用名为 file 的部分。这是经典形式,也是 curl -F 和大多数库的形式。
- • 原始正文:文件的字节构成请求正文,Content-Type 标头给出其类型(例如 application/pdf)。从传递内容原样而不包装请求的工具中很有用——这就是 Power Automate 连接器所做的。
- • 在原始正文中,文件名在正文中没有位置:通过 X-File-Name 标头或 ?fileName= 参数指定它。没有它,文档按其类型命名。
- • 不支持的类型以 415 响应,并命名两种接受的形式;声称为 multipart 但无法读取的正文以 400 响应。两者都不是服务器错误。
# a. multipart/form-data — the classic shape.
curl -X POST https://certyneo.com/api/v1/documents \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@contrat.pdf;type=application/pdf"
# b. raw body — the file bytes ARE the body, typed by Content-Type.
# The filename has nowhere to live in the body, so pass it as a header
# (or ?fileName=). Without it the document is named after its type.
curl -X POST https://certyneo.com/api/v1/documents \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/pdf" \
-H "X-File-Name: contrat.pdf" \
--data-binary "@contrat.pdf"
# Both return the same 201 with the document id to pass as documentIds.签名字段的放置
在没有模板的情况下,从 documentIds 创建的信封没有预先定位的字段:签署人收到的文档中没有签名位置。fields 数组在同一创建调用中传递,精确放置每个字段——这是 API 端的等效操作,相当于模板一次性记录的内容。
- • 坐标以 PDF 点为单位,原点在页面左上角,Y 轴向下(A4 页面尺寸为 595 × 842 点)。x 和 y 指定字段的左上角,width 和 height 指定其大小。
- • pageNumber 从 1 开始,documentIndex 从 0 开始。超出文档范围的页码在创建时不会被拒绝:该字段在签署时被忽略,不会出现在任何地方——当字段缺失时,这是首先要检查的地方。
- • recipientEmail 必须与同一调用中的一个收件人匹配,不区分大小写。否则创建会失败,并列出所有有问题的行,这样可以避免逐个更正。
- • fields 和 templateId 相互排斥:模板已经具有自己的布局。因此 fields 数组仅与 documentIds 一起使用。
- • 接受的类型:SIGNATURE、INITIALS、DATE_SIGNED、TEXT、CHECKBOX 和 RADIO_GROUP。required 默认为 true;placeholder 和 dateFormat 是可选的,options 仅对 RADIO_GROUP 进行处理。
- • 一个信封最多接受 100 个字段、20 个文档和 50 个收件人——您的计划限制可能更低。
# Ad-hoc envelope WITH pre-placed fields — no template involved.
# Coordinates are PDF points, origin TOP-LEFT of the page, +Y downwards
# (A4 = 595 x 842 pt). x / y are the field box's top-left corner.
#
# The last field is positioned by ANCHOR instead of by eye: the server
# locates "Signature du client" in the PDF and computes the spot. x / y
# stay required there — they are the fallback if the text is not found.
curl -X POST https://certyneo.com/api/v1/envelopes \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"subject": "Contrat de prestation",
"documentIds": ["cmdq7f4k80001s6y2h1xa9pl3"],
"recipients": [
{ "email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER" }
],
"fields": [
{ "recipientEmail": "client@example.com", "documentIndex": 0,
"pageNumber": 2, "fieldType": "SIGNATURE",
"x": 90, "y": 640, "width": 180, "height": 44 },
{ "recipientEmail": "client@example.com", "documentIndex": 0,
"pageNumber": 2, "fieldType": "DATE_SIGNED",
"x": 320, "y": 640, "width": 140, "height": 30,
"dateFormat": "DD/MM/YYYY" },
{ "recipientEmail": "client@example.com", "documentIndex": 0,
"pageNumber": 2, "fieldType": "TEXT",
"x": 90, "y": 700, "width": 200, "height": 30,
"placeholder": "Fonction", "required": false },
{ "recipientEmail": "client@example.com", "documentIndex": 0,
"pageNumber": 2, "fieldType": "SIGNATURE",
"anchorText": "Signature du client", "anchorPlacement": "below",
"anchorIndex": 0,
"x": 90, "y": 640, "width": 180, "height": 44 }
]
}'
# The envelope is DRAFT at this point — POST /envelopes/{id}/send
# dispatches it, exactly as in the quick-start above.文本锚点:在不知道坐标的情况下放置字段
字段可以引用打印在文档中的文本,而不是坐标:anchorText 在 PDF 中查找它,服务器在创建时计算位置。当文档在每次发送时重新生成时,这是首选方法——邮件合并、合同生成器——因为布局会变化,但"客户签名"的措辞仍然保留。anchorPlacement 表示字段相对于文本的哪一侧放置(默认为 right,也可以是 below、above 或 left),anchorIndex 在文本出现多次时选择出现次数。
即使使用锚点,x 和 y 仍然是必需的:它们充当备用值。找不到锚点不会导致创建失败——该字段保留您提供的字面位置,响应中没有错误或警告。因此请提供可能的备用值而不是 0,0,并在首次发送时验证呈现。
集成签名:无需离开应用程序即可签署
您的客户从您自己的界面查看和签署文件。签署流程在您页面上方的窗口中打开,完成后自动返回到您的页面。在服务器端,没有什么新的:您像往常一样通过填写redirectUrl来创建信封,然后将签署URL交给SDK进行处理。
- • 直接在您的点击处理程序中调用Certyneo.sign(),并通过getUrl传递您的服务器调用。在sign()前使用await会退出用户操作:Safari和Firefox随后会阻止该窗口。SDK会立即打开它,并在您的承诺解决时加载它。
- • redirectUrl 是返回通道。我们通过添加 certyneo_status(completed 或 declined)和 certyneo_envelope 将签署人重定向到该地址。在此返回页面上加载相同的脚本:正是这个脚本会通知在后台保持打开的门户窗口。
- • 在嵌入式模式下,我们自己的操作号召会被禁用。您的客户永远不会看到创建 Certyneo 账户的邀请。
- • 如果浏览器拒绝打开窗口,SDK 会自动切换到全页重定向。签署人的流程保持相同,您的返回页面接收的参数完全相同。
- • 按设计,不存在"用户已放弃"的回调:从您的页面无法读取窗口的状态,这样的回调会被错误地触发。未完成的签名会保持待处理状态,直到 webhook 到达。
// 1. Your server creates and sends the envelope, then hands the browser the
// recipient's signing URL. Nothing new on the API side:
// POST /api/v1/envelopes { …, "redirectUrl": "https://your-app.com/quote/42/signed" }
// POST /api/v1/envelopes/{id}/send → recipients[].accessToken
// signingUrl = "https://certyneo.com/sign/" + accessToken
// 2. On your quote page — load the SDK once:
// <script src="https://certyneo.com/embed.js"></script>
document.querySelector("#sign").addEventListener("click", () => {
Certyneo.sign({
// Called AFTER the window is already open, so no popup blocker ever
// sees a delay between the click and window.open.
getUrl: () =>
fetch("/api/quote/42/signature", { method: "POST" })
.then((r) => r.json())
.then((d) => d.signingUrl),
onCompleted: (e) => showConfirmation(e.envelopeId),
onDeclined: () => showDeclined(),
onError: (e) => showError(e),
});
});
// 3. On https://your-app.com/quote/42/signed — your return page — load the
// same script and render a short confirmation. It relays the outcome to
// the portal window behind it, then closes itself.浏览器事件不是签名证明
onCompleted 是一个显示信号,由浏览器发出,因此任何人都可以从其控制台伪造。永远不要基于此将文件切换为"已签署":使用它来刷新屏幕,并依靠您的服务器接收的已签署 envelope.completed webhook 来获取实际状态。这是支付集成的经典陷阱,在这里也完全相同。
在您的工作站上开发
使用测试密钥,redirectUrl 接受 http://localhost(和 127.0.0.1):您可以在部署前在您的机器上完成整个流程。实际密钥会拒绝它,以确保没有生产信封将真实签署人重定向到不属于他们的机器。
在您的页面中显示签署仪式
框架模式在您的界面内显示签署,无需弹窗。它比窗口模式多需一个步骤:证明将显示它的网站属于您。这可以防止第三方为了欺骗您的客户而嵌入我们的签署仪式。
- • 在"设置"→"集成签署"中声明您的网站,然后发布指定的DNS记录。需要精确匹配地址:不同的子域或端口将被视为另一个网站。
- • 每次签署时,向POST /api/v1/envelopes/{id}/embed-url请求一个新的URL。它携带显示授权,有效期为两小时,对应于点击时刻,而非信封创建时刻。
- • 两种流程无法在框架内进行:合格签署(其身份验证拒绝被框架化)和签署时付款。在这两种情况下,签署人都会被引导至完整窗口。
- • "由Certyneo提供支持"标签从商业计划及以上版本时从框架中消失。框架模式本身从标准计划开始就已包含。
// Mode cadre : la cérémonie s'affiche DANS votre page.
//
// 1. Déclarez votre site une fois pour toutes dans Réglages → Signature
// intégrée, et publiez l'enregistrement DNS qu'on vous y donne.
//
// 2. À chaque signature, votre serveur demande une URL fraîche. Elle porte
// l'autorisation qui permet au navigateur d'afficher la cérémonie chez
// vous, et vaut deux heures :
//
// POST /api/v1/envelopes/{id}/embed-url
// { "origin": "https://portail.exemple.fr" }
// -> { "signingUrl": "…", "expiresAt": "…" }
Certyneo.sign({
mode: "iframe",
el: "#zone-signature", // sélecteur ou nœud de votre page
getUrl: () =>
fetch("/api/devis/42/signature", { method: "POST" })
.then((r) => r.json())
.then((d) => d.signingUrl),
onCompleted: (e) => afficherConfirmation(e.envelopeId),
onDeclined: () => afficherRefus(),
});
// Le cadre parle à votre page par postMessage — pas besoin de page de retour,
// contrairement au mode fenêtre.让某人签署而不发送任何电子邮件
在自己的门户网站上显示签署仪式的门户通常不需要我们的邀请:它出现在他自己的用户旅程旁边,并向不需要它的客户推荐一个账户。为收件人的通知渠道设置 NONE 值,这样就不会向他发送任何内容——您来负责引导他进行签署。
- • 此设置按收件人设置,而不是按信封设置:您可以使您托管的客户保持静默,并为外部共同签署人保留电子邮件,他没有门户网站。
- • 它仅限于签署人和批准人,这些是您唯一需要交付链接的角色。您可以在创建和发送的响应中读取它,或在点击时从 POST /api/v1/envelopes/{id}/embed-url 请求新的 URL。
- • 自动催促会自行停止,对此收件人而言:我们从未写过信给他,我们不会以催促开始。其他收件人继续正常地接收催促。
- • 签署证书会提及它,逐个收件人。如果证明文件在这一点上保持沉默,就会让人相信这个签署人收到了来自我们的邀请,而该邀请从未存在过。
POST /api/v1/envelopes
{
"subject": "Mandat de gestion",
"documentIds": ["doc_8f2c1a4b9e7d"],
"recipients": [
{
"email": "client@exemple.fr",
"name": "Camille Client",
"role": "SIGNER",
"notificationChannel": "NONE"
},
{
"email": "notaire@exemple.fr",
"name": "Maître Notaire",
"role": "SIGNER"
}
]
}
// La réponse rend le lien de chaque signataire :
//
// "recipients": [
// { "email": "client@exemple.fr", "accessToken": "…",
// "notificationChannel": "NONE" },
// { "email": "notaire@exemple.fr", "accessToken": "…",
// "notificationChannel": "EMAIL" }
// ]
//
// Le client ne reçoit rien : vous l'emmenez sur sa signature depuis votre
// portail. Le notaire, lui, reçoit son invitation comme d'habitude.将您的客户名称显示为发件人
默认情况下,签署人会看到 API 密钥持有人的名称。如果您使用单个密钥为多个企业签署文件,请在创建信封时传递 sender 字段:签署页面和邀请及提醒电子邮件将显示相关企业的名称。
- • 仅限商业计划及以上版本。对于较低的计划,创建将被拒绝,而不是让签署人看到与预期不同的名称。
- • 名称是一个显示:证书和审计跟踪保留实际发件人,电子邮件始终来自 Certyneo。
- • 地址是可选的。没有地址,签署人只会看到名称,永远看不到 API 密钥持有人的地址。
POST /api/v1/envelopes
{
"subject": "Devis 2026-118",
"documentIds": ["doc_8f2c1a4b9e7d"],
"recipients": [
{ "email": "client@exemple.fr", "name": "Camille Client", "role": "SIGNER" }
],
"sender": {
"name": "1.2.3. Panneaux Solaires",
"email": "devis@123-panneaux-solaires.fr"
}
}身份验证
每个调用在 Authorization 请求头中携带 API 密钥。密钥从设置 → API 密钥生成,仅显示一次。
GET /api/v1/account/me HTTP/1.1Host: certyneo.com
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
# 200 OK
{ "data": { "id": "usr_…", "email": "you@example.com", "plan": "BUSINESS", "environment": "live" } }- • 格式:生产环境为 sk_live_…,沙箱环境为 sk_test_…。请求头:Authorization: Bearer <密钥>。
- • 作用域:envelopes、documents、webhooks、seals——以读取 (:read) 或写入 (:write) 模式。写入包含读取;作用域 * 授予所有权限。
- • sk_test_ 密钥创建的沙盒资源不计入配额和账单。除非收件人地址与发送账户自己的邮箱一致,否则不会发送真实邮件——这有助于在自己身上测试完整流程。
- • 错误:401 密钥无效,403 权限不足,429 速率限制超出,402 月度配额已达。
响应格式
编写客户端前需要了解的一点:集合被封装在data对象中,而单个资源以平面形式返回。因此在单个资源上读取 response.data.data 会返回undefined。
// GET /api/v1/envelopes
// Collections are WRAPPED in a "data" array.
{
"data": [
{ "id": "env_abc123", "subject": "Contrat", "status": "SENT" }
]
}// GET /api/v1/envelopes/{id}
// Single resources are returned FLAT — no "data" envelope.
{
"id": "env_abc123",
"subject": "Contrat",
"status": "COMPLETED",
"recipients": [ /* … */ ]
}速率限制
速率限制保证所有客户的服务质量稳定。如果您需要更多,请联系我们。
- • 每个 API 密钥每分钟 100 个请求
- • 允许突发到 10 秒内的 200 个请求
- • 429 响应,带有指示延迟秒数的 Retry-After 标头