API guide
For websites that send documents to their own users and want WriteSign to run the signing: InCorp InSys sending a service of process acceptance to a client, for example. The integrating site keeps its own account system; WriteSign verifies the signer (text code to the mobile the site supplies, plus the link the site hands to its signed-in user), runs the ceremony on any device, seals the result, and reports back.
Base URL https://www.writesign.com/api/v1. Auth header Authorization: Bearer ws_live_.... JSON in, JSON out. Errors are
{ "error": "<code>", "message": "<plain words>" } with a 4xx status.
Keys
Sign in at https://www.writesign.com/login/, then POST /api/keys {"name":"insys"} with the session (the dashboard will get a
button for this). The key is shown once. GET /api/keys lists prefixes; DELETE /api/keys/:id revokes. The account must be
approved by WriteSign before it can send (account_not_approved otherwise). Keys are limited to 600 calls an hour.
Documents
POST /documents {"title": "...", "body": "..."} -> { id, doc_hash, roles, fields }. Body syntax: # heading, ##
subheading, - bullet, 1. numbered, blank line between paragraphs, and inline fields [[signature:signer1]],
[[initials:signer1]], [[date:signer1]], [[text:signer1:Label]], [[checkbox?:signer1:Label]] (? = optional).
A document is immutable once created; its hash roots the evidence chain.
Envelopes
POST /envelopes
{ "document_id": "...", "signers": [{ "role": "signer1", "name": "Ada Lovelace", "email": "[email protected]", "mobile": "+17025550100" }],
"order_mode": "parallel", "message": "optional", "expires_days": 14, "reference": "INC-12345", "deliver": "link", "send": true }
deliver: "email"(default): WriteSign emails each signer the link.deliver: "link": no email; the send response carriessigning_urlper signer whose turn it is, ONCE (the raw link is never stored), for the site to open or send itself. Keep it; a lost link needs a new envelope or a resend. The signer still gets the text code on the mobile given. The ledger records the link as issued to the sender's system.referenceis the sender's own id (searchable in the dashboard, echoed in webhooks).- Response and
GET /envelopes/:id: `{ id, title, status, reference, verify_code, verify_url, signers:[{ id, role, name, email, status, completed_at, declined_at, signing_url }], seal, download_url }`. Status: draft, sent, in_progress, sealing, completed, declined, voided, expired. POST /envelopes/:id/send(forsend:falsedrafts),POST /envelopes/:id/void,GET /envelopes/:id/pdf(sealed PDF).
Webhooks
POST /webhooks {"url":"https://..."} -> { id, url, secret } (secret shown once). Events envelope.completed,
envelope.declined, envelope.voided, envelope.expired are POSTed as JSON with headers X-WriteSign-Event and
X-WriteSign-Signature = HMAC-SHA256(secret, rawBody) in hex. Answer 2xx; failures retry with backoff for about a day.
Payload: { event, at, envelope:{ id, title, status, reference, verify_code, download_url, seal }, signers:[...], reference }.
Verification
Anyone can confirm a document at https://www.writesign.com/verify/?code=XXXX-XXXX-XXXX or by uploading the PDF, and
GET /api/verify/:code is public.