Collect e-signatures on a document

View as Markdown
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. **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](https://docs.cloudraker.com/api/cloud-raker-api/runs/get-run), carries `envelopeUrl`: - [GET /v1/runs/{id}/envelope](https://docs.cloudraker.com/api/cloud-raker-api/runs/get-run-envelope) — roster and per-signer state. - [POST /v1/runs/{id}/signers/{signerId}/resend](https://docs.cloudraker.com/api/cloud-raker-api/runs/resend-run-signer) — issue a fresh link. - [POST /v1/runs/{id}/void](https://docs.cloudraker.com/api/cloud-raker-api/runs/void-run-envelope) — kill every pending link. ```json { "file": { "id": "a04d6597-4e34-4a99-94ea-964c289a4c68" }, "signers": [{ "name": "Ada Lovelace", "email": "[email protected]" }], "message": "Please countersign by Friday.", "placement": "page" } ``` <Note> 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: they never appear in `tasks[]` or anywhere else on the sender's API. </Note> **Learn more:** [E-signature guide](https://docs.cloudraker.com/capabilities/sign)

Authentication

AuthorizationBearer

Bearer authentication of the form Bearer <token>, where token is your auth token.

Query parameters

waitintegerOptional0-120Defaults to 60
How many seconds to hold the request open waiting for the run to finish. Defaults to `60`, maximum `120`. 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

This endpoint expects an object.
signerslist of objectsRequired

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.

fileobjectRequired

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 with POST /v1/files, reusable across runs and never re-parsed.
messagestringOptional<=2000 characters
A note included in the invitation email each signer receives.
placementenumOptional

Where signatures land in the document.

page (the default) 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.

metadatamap from strings to anyOptional

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.

webhookobjectOptional

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 from POST /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.

ttlintegerOptional1-604800

How long, in seconds, to keep this run and its files before purging them automatically.

Defaults to 24 hours; 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

The finished run.
object"sign_run"
idstring
statusenum

Where the run is in its life.

StatusMeaning
queuedAccepted, not started
processingWork in flight
needs_inputParked for a person — see tasks[]
processedFinished; output is populated
failedFinished unsuccessfully
cancelledStopped on request
expiredTTL elapsed and the data was purged

The last four are terminal.

expiresAtstring or null
statusUrlstring
fileslist of objects
envelopeUrlstring
fileobject
errorobject

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.

metadatamap from strings to any
taskslist of objects

The human steps currently blocking the run. Present while status is needs_input.

Each task has a url — a ready-made page you can send a person to — or you can drive it yourself through GET and POST /v1/runs/{id}/task. E-signature runs never carry tasks[]: their signing links are signer-held secrets, so use envelopeUrl instead.

outputobject

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.

Errors

400
Bad Request Error
422
Unprocessable Entity Error
429
Too Many Requests Error