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/* returns enterprise-required there.
  • 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.signed

Verify 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.signeddocument.completed.

5 · Pull the signed PDF programmatically

curl -OJ -H "Authorization: Bearer $WSK_KEY" \
  https://api.wesign.now/v1/documents/$DOC_ID/signed

Returns 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.