Collect e-signatures on a document
Sends a PDF out for signature and tracks the envelope until every signer is done.
Each signer verifies their email with a one-time code and signs by typing their name. The completed document gets a signature certificate and a tamper-evident cryptographic seal, and comes back as a new file alongside output.auditUrl.
Where the signatures land — placement:
page(default) — a signature certificate page is appended to the document.tags— each signer’s stamp replaces a[Signature N]placeholder already present in the document. Every signer needs one, or the run fails.
Keeping others in the loop — cc: informed-only recipients who do not sign. They receive no OTP or signature tag, and are emailed the sealed document when the envelope completes.
Language — language: en (default) or fr. Sets the language of every recipient-facing asset — invitation and code emails, the signing page, and the audit certificate — for all signers and CC parties.
Always asynchronous. The call returns 202 with status: "needs_input" as soon as the envelope exists, and stays there until the last signer completes.
Managing the envelope — every sign response, both the 202 and the run, carries envelopeUrl:
- GET /v1/runs/{id}/envelope — roster and per-signer state.
- POST /v1/runs/{id}/signers/{signerId}/resend — issue a fresh link.
- POST /v1/runs/{id}/void — kill every pending link.
Sign runs are exempt from the run TTL, so an envelope outlives the 7-day maximum and waits for its signers. Signing links are signer-held secrets and never appear on the sender’s API.
Learn more: E-signature guide
Authentication
Bearer authentication of the form Bearer <token>, where token is your auth token.
Path parameters
Query parameters
How many seconds to hold the request open waiting for the run to finish.
Finishing inside the window returns 200 with the full run; running past it returns 202 with a statusUrl to poll. Send 0 to skip waiting entirely and always get the 202.
Request
Who has to sign, in order — up to 50 people, each with a name and an email.
Every signer verifies their email with a one-time code, then signs by typing their name. Track them individually at GET /v1/runs/{id}/envelope.
An input file, given one of two ways.
{ "url": "…", "name"?: "…", "processing"?: "…" }— fetched over http(s) for this run and purged with it.{ "id": "…" }— a file you already registered withPOST /v1/files, reusable across runs and never re-parsed.
Where signatures land in the document.
page appends a signature certificate page. tags puts each signer's stamp over a [Signature N] placeholder already present in the document — every signer needs one, or the run fails.
Informed-only recipients. CC parties do not sign, receive no OTP or signature tag, and are emailed the sealed document when the envelope completes.
Language of every recipient-facing asset — invitation and code emails, the signing page, and the audit certificate. Applies to all signers and CC parties. Defaults to en.
Arbitrary JSON you attach to the run and get back on every read of it.
Use it to carry your own identifiers — an order number, a customer id — so a webhook or a polled run reconciles without a lookup table. Capped at 10 KB serialized.
Where to deliver this run's events, given one of two ways.
{ "url": "…" }— a one-off https endpoint for this run only.{ "id": "whe_…" }— a saved endpoint fromPOST /v1/webhooks. Runs hold the reference, so pausing or re-pointing that endpoint applies to this run too.
Deliveries are at-least-once and signed — dedupe on eventId and verify against GET /v1/webhooks/jwks.json.
How long, in seconds, to keep this run and its files before purging them automatically.
The maximum is 604800 (7 days). The deadline comes back as expiresAt on every read of the run. Call POST /v1/runs/{id}/keep before then to clear the TTL and move the results into a space permanently.
E-signature runs are exempt — an envelope waits for its signers however long that takes.
Response
Where the run is in its life.
The last four are terminal.
Why the run failed. Present whenever status is failed, and only then.
code is the stable, snake_case reason (input_unavailable, parse_failed, …); message is the human-readable detail. Per-file and per-step failures are also reported in files[].error and, for a pipeline, steps[].error.
The signed document. Present once every signer has completed.
file is the sealed PDF, signers[] records who signed and when, and auditUrl points at the machine-readable audit trail.