Aller au contenu

E-signatures

v1 · Last updated 2026-07-17

Cette documentation est disponible uniquement en anglais.

POST/api/v1/:workspace/sign-requests

Send 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

workspacepathWorkspace 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).

Signerssigners: [{email, name?}, …], 1–10 entries. Signer i fills the fields assigned "Signer i" in the editor; unassigned fields belong to signer 1. The legacy recipientEmail shape still works and equals a one-signer array.

signingOrderparallel (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 90 days.

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.

Available on hosted paid tiers (monthly quota: Advanced 20, Pro 100, Enterprise 500; 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.

POST/api/v1/:workspace/sign-requestsTry it
/api/v1//sign-requests

Paste an API key above to enable the Send button.

GET/api/v1/:workspace/sign-requests

List 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

workspacepathWorkspace slug.required
statusquerypending | signed | declined | expired
templateIdqueryOnly sign requests for this template UUID.
qqueryCase-insensitive substring on recipient email.
limitquery1 – 100 (default 50)
offsetqueryRows to skip (default 0).
sortByquerycreatedAt | expiresAt | signedAt | status, suffixed with :asc or :desc.
totalResultsquerytrue 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
  }
}
GET/api/v1/:workspace/sign-requestsTry it
/api/v1//sign-requests

Paste an API key above to enable the Send button.

GET/api/v1/:workspace/sign-requests/:id

Get one sign request

Single sign request belonging to this workspace. Use to poll the status of a request you created previously.

Parameters

workspacepathWorkspace slug.required
idpathSignatureRequest 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.

GET/api/v1/:workspace/sign-requests/:idTry it
/api/v1//sign-requests/

Paste an API key above to enable the Send button.

GET/api/v1/:workspace/sign-requests/:id/signed-pdf-url

Download 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

workspacepathWorkspace slug.required
idpathSignatureRequest 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.

GET/api/v1/:workspace/sign-requests/:id/signed-pdf-urlTry it
/api/v1//sign-requests//signed-pdf-url

Paste an API key above to enable the Send button.

Need help?

Open a ticket from the in-app Support page, or email [email protected].