letssign.now docs

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.

Prerequisites

  • A workspace on Branded or Teams tier (API access ships with those). Free + Pro tiers can't mint keys yet.
  • 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 lsk_live_… plaintext to a terminal env var:

export LSK_KEY="lsk_live_YOURKEYHERE"

The plaintext shows once. The dashboard keeps a lsk_live_a1b2… prefix so you can identify the key later.

2 · Send a real request

curl -X POST https://api.letssign.now/v1/signing-requests \
  -H "Authorization: Bearer $LSK_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.

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.letssign.now/v1/signing-requests \
  -H "Authorization: Bearer $LSK_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:

X-LetsSign-Signature: t=1714399812,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 $LSK_KEY" \
  https://api.letssign.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.

What's next

  • Placement modes — pick anchors, auto-append, explicit coordinates, or manual placement.
  • Webhooks — production-grade event delivery, retries, signature verification.
  • Idempotency — safely retry network blips.
  • Errors — full code table.