電子署名をシステムに統合
エンベロープ送信、署名追跡、ウェブフック受信。シンプルなREST API、OpenAPI 3.0、curl/Node/Pythonの例 — Certyneを数時間でHRIS、CRM、業務システムに統合できます。
クイックスタート
エンベロープ
# 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仕様から生成されており、この仕様書はこのページも文書化しています。3つはすべてエンドポイントごとに実際のAPIと一致したままであり、最初の追加で分岐することはありません。
Postmanコレクション
25のリクエストがドメイン別に整理されています — エンベロープ、ドキュメント、テンプレート、シール、ウェブフック — それぞれについてリクエスト本体と応答の例が付属しています。コレクション内のapiKey変数にキーを貼り付けてから、GET /healthを実行します。このエンドポイントは認証を必要とせず、最初の認証付きリクエストの前にご使用の設定が正常であることを確認します。
作成、送信、ステータス追跡、キャンセル。エンベロープは複数のドキュメントと複数の署名者(並列または順序付き)に対応します。
ウェブフック
`envelope.created`、`envelope.completed`、`envelope.declined`をご指定のURLで受信します。各ペイロードにHMAC SHA-256署名を付与し、発信元を検証できます。
すべてのエンベロープおよび受信者イベント(`envelope.sent`、`recipient.signed`、`envelope.completed`など)が選択したURLに配信されます — 完全なリストは/developers/webhooksを参照。各ペイロードに対するHMAC SHA-256により、出所を検証します。
簡易認証
ベアラートークン。環境ごと(テスト/本番)に1つの鍵。即時失効可能。制限は1鍵あたり1分あたり100リクエスト、バースト200、Retry-Afterヘッダー付きで429。
全署名サイクルをカバーする12ルート:エンベロープ、ドキュメント、ウェブフック、APIキー。すべてのルートはベアラートークンを受け入れ、JSONを返します。
すべてのパブリックルート:アカウント、文書、エンベロープ、テンプレート、ウェブフック、電子シール、API キー、課金。すべてベアラートークンを受け入れ、JSON を返します。
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/account/me | Identity of the authenticated caller (id, email, plan) — scope-less credential probe |
| POST | /api/v1/documents | Upload a PDF (multipart) — returns document id |
| GET | /api/v1/documents | List documents |
| GET | /api/v1/documents/{id} | Fetch document metadata |
| DELETE | /api/v1/documents/{id} | Delete document |
| GET | /api/v1/envelopes | List envelopes (filter with ?status= and ?limit=) |
| POST | /api/v1/envelopes | Create envelope (status: DRAFT) — from a templateId, or from documentIds with an optional fields array |
| GET | /api/v1/envelopes/{id} | Fetch envelope state |
| PATCH | /api/v1/envelopes/{id} | Update DRAFT envelope |
| DELETE | /api/v1/envelopes/{id} | Void / delete DRAFT envelope |
| POST | /api/v1/envelopes/{id}/send | Dispatch DRAFT — sends invitations |
| GET | /api/v1/envelopes/{id}/audit-trail | Download eIDAS audit-trail PDF |
| GET | /api/v1/audit-anchors/{root} | Public: metadata of an anchored audit batch, or the .ots proof file with ?format=ots (no auth) |
| POST | /api/v1/audit-anchors/verify | Public: verify an audit entry + proof against its anchored Merkle root (no auth, reveals nothing) |
| GET | /api/v1/envelopes/{id}/signed-document | Download signed PDF (once COMPLETED) |
| GET | /api/v1/envelopes/bulk | List your bulk-send jobs |
| POST | /api/v1/envelopes/bulk | Bulk send: create N envelopes from one template + a CSV (Standard/Business only) |
| GET | /api/v1/envelopes/bulk/{id} | Bulk-send job progress: counts, per-row failures, created envelopes |
| GET | /api/v1/templates | List reusable envelope templates |
| POST | /api/v1/templates | Create a template (documents, roles, positioned fields) |
| POST | /api/v1/sepa-mandates | Generate a SEPA mandate PDF and its DRAFT envelope, fields already placed |
| POST | /api/v1/payroll-adapters/normalize | Normalise a payroll CSV (Silae, Sage Paie, PayFit, Lucca) into the bulk-send shape |
| POST | /api/v1/ag-copropriete | Create a condominium general-meeting envelope (resolutions + ownership shares) |
| POST | /api/v1/ag-copropriete/{envelopeId}/votes | Record a co-owner's votes on the meeting resolutions |
| POST | /api/v1/ag-copropriete/{envelopeId}/tally | Tally the meeting - per-resolution result weighted by ownership shares |
| GET | /api/v1/videos/{videoId} | Download a stored identity video - GDPR art. 15 access path |
| GET | /api/v1/webhooks | List webhooks |
| POST | /api/v1/webhooks | Register webhook — returns the signing secret once |
| GET | /api/v1/webhooks/{id} | Fetch webhook subscription |
| PATCH | /api/v1/webhooks/{id} | Update url / events / active state |
| DELETE | /api/v1/webhooks/{id} | Unregister |
| POST | /api/v1/seals | Apply a qualified electronic seal to a document |
| GET | /api/v1/seals/{id} | Fetch seal status |
| GET | /api/v1/seals/{id}/certificate | Download the seal certificate |
| GET | /api/v1/keys | List API keys |
| POST | /api/v1/keys | Create API key — the secret is shown once |
| PATCH | /api/v1/keys/{id} | Rename / revoke key |
| DELETE | /api/v1/keys/{id} | Delete key |
| GET | /api/v1/billing/usage | Current period usage and projected cost |
| GET | /api/v1/status | Service status |
| GET | /api/v1/openapi | Machine-readable OpenAPI specification |
封筒のテンプレート
テンプレートは、PDFと役割、および署名フィールドの位置を一度だけ保存し、送信するたびに再利用します。documentIdsの代わりにtemplateIdで識別子を渡すと、配置されたフィールドが作成されたエンベロープにコピーされます。
- • テンプレートはダッシュボードから作成します(テンプレート → 新しいテンプレート)。ここでドキュメントをアップロードしてマウスでフィールドを配置します — これが最も簡単な方法です。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から
当社のノーコードコネクタの「エンベロープを作成」アクションはテンプレートパスのみをサポートしています。「テンプレート」フィールドは必須です。実行するたびに異なるアドホックドキュメントの場合は、「ドキュメントをアップロード」アクションと、返されたdocumentIdsを渡してPOST /api/v1/envelopesへの生HTTPアクションを使用してください。
ドキュメントの送信: 2 つの形式が許可されています
POST /api/v1/documents は 2 つの方法でファイルを受け入れます。どちらの場合も同じ制御が適用されます: 許可されるタイプ、50 MB の上限、バイナリ署名の検証、ウイルス対策分析。
- • multipart/form-data で、file という名前の部分。これは従来の形式で、curl -F とほとんどのライブラリで使用されます。
- • 生のボディで: ファイルのオクテットはリクエストのボディを構成し、Content-Type ヘッダーはそのタイプを指定します (例: application/pdf)。リクエストをラップせずにコンテンツをそのまま送信するツールから便利です。これは Power Automate コネクタが行うことです。
- • 生のボディでは、ファイル名がボディに記載される場所はありません。X-File-Name ヘッダーまたは ?fileName= パラメーターで指定してください。ない場合、ドキュメントはそのタイプに基づいて名前が付けられます。
- • サポートされていないタイプは 415 で応答し、2 つの許可された形式を示します。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 は、大文字と小文字の区別なく、同じ呼び出しの受信者の 1 人と一致する必要があります。一致しない場合、作成は失敗し、すべての誤りのある行をリストアップします。これにより、1 つずつ修正する手間が省けます。
- • 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 ではなく妥当なフォールバックを指定し、最初の送信でレンダリングを確認してください。
認証
各呼び出しは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キーあたり1分間に100件のリクエスト
- • 10秒以内に最大200件のリクエストまでのバースト負荷に対応
- • 秒単位の遅延を示す Retry-After ヘッダー付きの 429 レスポンス