Sign
Send a PDF for e-signature and get a sealed document with an audit trail.
POST /v1/sign creates a signature envelope for one PDF. Each signer verifies their email with a one-time code. Each signer signs by typing their name. When the last signer completes, CloudRaker adds a signature certificate and a tamper-evident cryptographic seal. The sealed document comes back as a new file.
How it works
- You send a file and one or more signers (
name+email). - CloudRaker creates the envelope and emails each signer their own signing link. The call returns
202withstatus: "needs_input". Signing is never synchronous. - The run stays at
needs_inputwhile signatures come in. PollGET /v1/runs/:id, watch the envelope, or subscribe a webhook. - When all signers complete, CloudRaker seals the document. The run reaches
processedwithoutput.fileandoutput.auditUrl.
Sign runs are exempt from the run TTL. An envelope must outlive the 7-day maximum, so CloudRaker never purges an open envelope. The expiresAt field is still present on the run body. For a sign run, the API does not enforce it. The envelope has its own expiry, visible on GET /v1/runs/:id/envelope.
Quickstart
The TypeScript and Python samples use plain HTTP, so they run with no installed packages. This endpoint is also a top-level method on both SDKs as of 0.3.0: client.sign(…). That page has a full worked example.
Example response
envelopeUrl appears on every sign response, the 202 and each GET /v1/runs/:id. It points at the envelope, the sender’s view of who has signed. A signing link is a bearer capability that belongs to one signer. CloudRaker emails the link to that signer and never returns it to you.
When every signer completes, GET /v1/runs/:id reaches processed. Then output carries:
Configuration
Placing the signatures
page (the default) appends an Electronic Signatures page and puts every stamp on it. Nothing needs preparing in the document.
tags puts each signer’s stamp on a literal [Signature N] in the document text. signers[0] signs [Signature 1], signers[1] signs [Signature 2], and so on — matched by position, never by name or email. Every signer needs a marker. If one is missing the run fails before anyone is invited, with error.code: "signature_tags_missing".
A marker sets where a stamp goes, not how big it is. Each stamp grows upward into whatever space is free above it, so leave about 88pt clear of other text and form fields for a full-size stamp — a marker tucked under other content gets a smaller one.
Both placements append the audit pages, so tags gives you in-place signatures and the trail.
Track the envelope
Four sub-routes hang off the run id.
GET /v1/runs/:id/envelope
The sender’s view: envelope status, the signer roster with per-signer state, and the event trail.
The envelope never contains signing links. A signing link is a bearer capability that only its signer holds. To get a signer moving again, re-send their invitation.
POST /v1/runs/:id/signers/:signerId/resend
Emails a pending signer a new signing link. Their previous link stops working immediately. Returns 409 if that signer already signed or if the envelope is no longer pending.
POST /v1/runs/:id/void
Cancels a pending envelope. Every signing link dies at once, and the run terminates as failed. The body accepts an optional { "reason": "…" }. Returns 409 when the envelope is finalizing or completed.
GET /v1/runs/:id/audit
Returns the audit trail as JSON: creation, invitations, email verifications, signatures, and the seal. It is available before the envelope completes. The sealed PDF carries the same document as an attachment.
Sync vs async
Sign is always asynchronous. POST /v1/sign answers 202 for any ?wait= value, because a sign run cannot reach a terminal status inside the window. With the default wait, the call holds until the envelope exists and reports status: "needs_input". With ?wait=0, the call returns immediately with status: "queued". Poll GET /v1/runs/:id?wait=…, watch the envelope, or subscribe run.completed on a webhook endpoint.
Save as a config
Sign is the one capability with no config library and no action reference in its request body. POST /v1/sign and {"sign": …} pipeline steps always run the built-in signing action. They take their whole configuration inline. Send message and placement on every call.
There is no /v1/sign/configs. POST /v1/actions accepts "capability": "sign", so you can create and list a saved sign action. But today no /v1 request path consumes one. The API rejects a saved sign action as another verb’s action with 400 invalid_request. The same applies to a bare {"action": …} pipeline step. Only the sign path keeps the run exempt from the TTL purge.