Quickstart
From zero to a signed PDF in under five minutes — terminal-only, no SDK.
This guide goes deeper than the home page summary. By the end you'll have a real PAdES-sealed PDF in your blob storage and a webhook fired against your endpoint, and you'll know which knobs to turn for production.
Every URL below uses the canonical host https://api.wesign.now/v1.
https://api.letssign.now/v1 is a permanent alias of the same API —
see Base URL for what is and isn't the
contract.
Prerequisites
- A workspace on Enterprise. API keys and the template endpoints both ship with it; Free and Branded can't mint keys.
- Legacy Teams workspaces can still mint keys, but
/v1/templates/*returnsenterprise-requiredthere. - A test PDF on disk. Any PDF works; if it doesn't have an anchor marker we just append a signature page.
- An email address you can check (or two — sender + signer can be the same address while you smoke-test).
1 · Mint an API key
In your workspace, open
Developers → API keys and hit Create API key.
Copy the wsk_live_… plaintext to a terminal env var:
export WSK_KEY="wsk_live_YOURKEYHERE"The plaintext shows once. The dashboard keeps a wsk_live_a1b… prefix
so you can identify the key later. A key minted before the September
2026 rename starts with lsk_live_ and works exactly the same — no
need to re-mint.
2 · Send a real request
curl -X POST https://api.wesign.now/v1/signing-requests \
-H "Authorization: Bearer $WSK_KEY" \
-H "Idempotency-Key: smoke-$(date +%s)" \
-F "file=@/path/to/contract.pdf" \
-F 'signers=[{"email":"you@example.com","role":"signer"}]' \
-F 'placement=auto_append' | jq .Successful response (HTTP 201):
{
"documentId": "8a1e4f9a-b3c1-4d22-9e0a-3a92ee7c1f88",
"status": "pending",
"placement": "auto_append",
"presentedSha256": "4f9a…d21c",
"anchors": { "found": 0, "fields": 2 },
"signers": [
{
"role": "signer",
"email": "you@example.com",
"status": "pending",
"signingUrl": "https://yourco.letssign.now/en/sign/abc…",
"signingRequestId": "11111111-…"
}
],
"observers": []
}The signingUrl is what we'll email to the signer (and what you
forward yourself if you'd rather skip our delivery). Open that
URL in another browser tab to play the signer side. Signing links live
on your workspace's branded host (yourco.letssign.now) — only the
API host is api.wesign.now.
3 · Watch a webhook fire (optional)
Skip if you'd rather poll. To see the events live, the easiest path is a free Webhook.site URL:
# webhook.site/<your-token> issued at https://webhook.site
curl -X POST https://api.wesign.now/v1/signing-requests \
-H "Authorization: Bearer $WSK_KEY" \
-F "file=@contract.pdf" \
-F 'signers=[{"email":"you@example.com","role":"signer"}]' \
-F 'callback_url=https://webhook.site/YOUR-TOKEN'The response now includes a callback.secret — store it. Each event
we POST to your URL is signed. The same three values arrive under two
header names; the X-LetsSign-* family is the pre-rename spelling and
is kept forever, so read whichever you like:
X-WeSign-Signature: t=1757404800,v1=9c3b…a2f1
X-WeSign-Event-Id: evt_…
X-WeSign-Event: signing_request.signed
X-LetsSign-Signature: t=1757404800,v1=9c3b…a2f1
X-LetsSign-Event-Id: evt_…
X-LetsSign-Event: signing_request.signedVerify the signature before trusting the body.
4 · Sign
Open signingUrl on your phone (real test) or in another browser
tab (lazy test). Sign. Watch the inbox for the completion email and
your webhook receiver for signing_request.signed →
document.completed.
5 · Pull the signed PDF programmatically
curl -OJ -H "Authorization: Bearer $WSK_KEY" \
https://api.wesign.now/v1/documents/$DOC_ID/signedReturns the fully PAdES-sealed PDF — every signer's signature
appended, RFC 3161 timestamp embedded, ready for your DMS. This is the
same URL document.completed hands you as signed_pdf_url: it needs
your key, so pin that fetch to api.wesign.now and send the bearer —
see signed_pdf_url.
What's next
- Placement modes — pick anchors, auto-append, or explicit coordinates.
- Second factor by SMS — require a one-time code on the signer's phone before they can sign.
- Webhooks — production-grade event delivery, retries, signature verification.
- Idempotency — safely retry network blips.
- Errors — full code table.
