/api/v1/:workspace/sign-requestsSend a PDF out for e-signature
Stores a PDF, emails the recipient a /sign/<token> link, and — once they sign — stamps their signature onto that exact PDF and delivers it to the template's deliveryEmail (or the account owner).
Parameters
workspacepath | Workspace slug.required |
Response
{
"signatureRequestId": "uuid",
"recipientEmail": "[email protected]",
"status": "pending",
"expiresAt": "2026-05-24T10:00:00.000Z",
"signingOrder": "sequential",
"signers": [
{
"signerIndex": 1,
"email": "[email protected]",
"name": "Jane Doe",
"status": "pending",
"invitedAt": "2026-05-10T10:00:00.000Z"
},
{
"signerIndex": 2,
"email": "[email protected]",
"name": null,
"status": "pending",
"invitedAt": null
}
]
}Source — exactly one of templateId + data (render a fresh PDF) or renderId (reuse an existing render as-is).
Signers — signers: [{email, name?, locale?}, …], 1–10 entries. Signer i fills the fields assigned "Signer i" in the editor; unassigned fields belong to signer 1. locale (en, de, fr, es, it, pl, tr) is the signer's language for their emails and sign page. A name or language you leave out is filled from your earlier requests to the same address. The legacy recipientEmail shape still works and equals a one-signer array.
signingOrder — parallel (default) invites everyone at once; sequential invites signers one at a time, in order. requireEmailVerification — each signer must confirm a 6-digit emailed code before signing. ttlSeconds — how long links stay signable (default 7 days, max 30); the signed PDF is kept until you delete it.
Each signer gets a personal /sign link and sees only their own fields. Signatures are stamped onto the exact PDF the signers reviewed — never re-rendered. One decline ends the whole request.
includeCertificate: true appends an audit page (hashes, timestamps, verification, IPs) to the signed PDF. Off by default — it exposes signer emails and IPs. The audit trail is always available via GET /sign-requests/:id either way.
Consent. Every signer must tick a consent statement before signing. The exact text they accepted (in their language) is stored on the signed audit event as consent and printed on the certificate page.
Seal and fingerprints. After the last signature the PDF is sealed with a certificate-based digital signature (audit event sealed; readers show it in their signature panel and any later change invalidates it). originalPdfSha256 and signedPdfSha256 are the SHA-256 fingerprints of the document before signing and of the sealed file you download. Anyone holding the PDF can confirm it at /sign/verify, or programmatically via GET /sign/verify/:sha256 (public, no auth): found, completion date, per-signer consent and email-verification flags, the seal and whether the hash-chained audit trail is intact.
test: true — a test request: the PDF is watermarked, every mail is marked [Test] and the signing page says the signature is not legally binding; signable for 24 hours, and the signed copy is deleted 24 hours after signing. Never counts against the quota. Implied by a pk_test_ key; the Free plan can only send test requests.
Available on hosted paid tiers (monthly quota: Essentials 10, Advanced 40, Pro 200, Enterprise 1,000; beyond that €0.10/request from your balance) and on self-hosted installs with an Enterprise license — SMTP must be configured on the host, and self-hosted requests are not metered. Below an Enterprise license the API returns 402 license_upgrade_required; with the license but no mailer, 503 smtp_not_configured. templateId mode also counts one render.
/api/v1/:workspace/sign-requestsList sign requests
Workspace-scoped list of every sign request created from this workspace's templates. Returns the standard {data, meta} envelope; default sort is createdAt:desc.
Parameters
workspacepath | Workspace slug.required |
statusquery | pending | signed | declined | expired |
templateIdquery | Only sign requests for this template UUID. |
qquery | Case-insensitive substring on recipient email. |
limitquery | 1 – 100 (default 50) |
offsetquery | Rows to skip (default 0). |
sortByquery | createdAt | expiresAt | signedAt | status, suffixed with :asc or :desc. |
totalResultsquery | true to include meta.total. |
Response
{
"signRequests": [
{
"id": "uuid",
"status": "pending",
"recipientEmail": "[email protected]",
"recipientName": "Jane Doe",
"templateId": "uuid",
"templateName": "NDA",
"createdAt": "2026-05-10T10:00:00.000Z",
"expiresAt": "2026-05-17T10:00:00.000Z",
"signedAt": null,
"declinedAt": null,
"declineReason": null,
"signatureMethod": null,
"hasSignedPdf": false,
"recipientCopySentAt": null
}
],
"meta": {
"count": 1,
"limit": 50,
"offset": 0,
"hasMore": false
}
}/api/v1/:workspace/sign-requests/:idGet one sign request
Single sign request belonging to this workspace. Use to poll the status of a request you created previously.
Parameters
workspacepath | Workspace slug.required |
idpath | SignatureRequest UUID.required |
Response
{
"id": "uuid",
"status": "signed",
"recipientEmail": "[email protected]",
"recipientName": "Jane Doe",
"templateId": "uuid",
"templateName": "NDA",
"createdAt": "2026-05-10T10:00:00.000Z",
"expiresAt": "2026-05-17T10:00:00.000Z",
"signedAt": "2026-05-11T13:24:00.000Z",
"declinedAt": null,
"declineReason": null,
"signatureMethod": "typed",
"hasSignedPdf": true,
"recipientCopySentAt": "2026-05-11T13:24:05.000Z",
"testMode": false,
"signingOrder": "parallel",
"requireEmailVerification": false,
"signers": [
{
"signerIndex": 1,
"email": "[email protected]",
"name": "Jane Doe",
"status": "signed",
"invitedAt": "…",
"viewedAt": "…",
"signedAt": "…",
"declinedAt": null,
"signatureMethod": "typed",
"emailVerifiedAt": null
}
]
}signers carries per-signer progress (only on this endpoint, not the list). The request-level status stays pending until every signer has signed; one decline flips the whole request to declined.
/api/v1/:workspace/sign-requests/:id/signed-pdf-urlDownload the signed PDF
Returns a short-lived presigned URL to download the signed PDF. Only valid once status === 'signed' and the signature has been stamped. The URL expires in 10 minutes.
Parameters
workspacepath | Workspace slug.required |
idpath | SignatureRequest UUID.required |
Response
{
"url": "https://…",
"expiresAt": "2026-05-11T13:34:00.000Z"
}Returns 409 not_signed with the row's current status when the sign request hasn't been completed. Returns 425 still_processing with a Retry-After: 3 header while the signature is still being stamped — poll a few seconds later.
/api/v1/:workspace/sign-requests/:idDelete a sign request
Permanently deletes a finished sign request: its record, audit trail, signed PDF and every other file it owns. Signed documents are kept until you delete them, so this is how one goes.
Parameters
workspacepath | Workspace slug.required |
idpath | SignatureRequest UUID.required |
Response
{
"ok": true
}A pending request can't be deleted (409 request_pending) — revoke it first. 503 storage_unavailable means the signed PDF couldn't be removed; nothing was deleted, so retry.
Need help?
Open a ticket from the in-app Support page, or email [email protected].