SignSpry REST API v1

Base URL https://signspry.com/api/v1 · JSON in, JSON out · errors return {"error": "…"} with 4xx/5xx.

Authentication

Create a key in the developer console and send it on every request:

curl https://signspry.com/api/v1/account \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

A key carries only the scopes ticked when it was created — envelopes:read (list, status, audit trail, sealed PDF), envelopes:write (create, send, remind, void, signing and embed links), templates:read, account:read. A call outside the key's scopes returns 403 naming the missing scope. Keys expire (30 days, 90 days, a year, or never — you are emailed a week before) and return 401 afterwards, and can be pinned to an IP allowlist (addresses or CIDR ranges), returning 403 from anywhere else. Give each integration its own key with the narrowest scopes it needs, so revoking one never breaks another.

Create & send an envelope

One call uploads documents (base64 PDFs), adds recipients and fields, and sends. Coordinates are fractions of the page (0–1) from the top-left; recipient is an index into the recipients array; status: "sent" emails the invites immediately (omit it to keep a draft).

curl -X POST https://signspry.com/api/v1/envelopes \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Service Agreement",
    "message": "Please sign by Friday.",
    "expires_days": 15,
    "reminder_days": 2,
    "status": "sent",
    "documents": [{"name": "agreement.pdf", "content_b64": "'"$(base64 -w0 agreement.pdf)"'"}],
    "recipients": [
      {"name": "Asha Vendor", "email": "asha@vendor.in", "routing_order": 1},
      {"name": "Manu Shekhar", "email": "manu@signspry.com", "routing_order": 2},
      {"name": "Accounts",  "email": "accounts@signspry.com", "role": "cc"}
    ],
    "fields": [
      {"recipient": 0, "type": "signature", "page": 0, "x": 0.10, "y": 0.72, "w": 0.25, "h": 0.05},
      {"recipient": 0, "type": "text", "page": 0, "x": 0.10, "y": 0.60, "w": 0.20, "h": 0.04,
       "label": "PAN", "validation": {"type": "pan"}},
      {"recipient": 1, "type": "signature", "page": 1, "x": 0.10, "y": 0.72, "w": 0.25, "h": 0.05}
    ]
  }'

Field types: signature initials text date checkbox dropdown (with options) radio (with group_name) formula. Validations: email numbers letters date phone_in pincode pan gstin {"type":"custom","regex":"…"}.

Embedded signing

Instead of (or in addition to) email invites, fetch a signing URL and open it in your own app — iframe or redirect. When the signer finishes, they're sent to your return_url with ?envelope=…&event=signed (or declined).

curl -X POST https://signspry.com/api/v1/envelopes/ENV_ID/recipients/RECIPIENT_ID/signing-link \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"return_url": "https://yourapp.com/signing-done"}'

#  {"url": "https://signspry.com/sign/…", "recipient": {…}}

Recipient IDs come from the create/detail responses. Each call mints a fresh link and invalidates old ones for that recipient. Routing order still applies — a blocked signer sees a "waiting for others" page.

Webhooks

Add an endpoint in the console; every matching event POSTs JSON to it:

POST https://yourapp.com/webhooks/signet
X-Signet-Event: envelope.completed
X-Signet-Signature: sha256=<hex HMAC-SHA256 of raw body, keyed with your whsec_… secret>

{"id":"…","event":"envelope.completed","created_at":1787480000.1,
 "data":{"envelope":{"id":"…","title":"…","status":"completed","recipients":[…]}}}

Verify (Python): hmac.new(secret, raw_body, hashlib.sha256).hexdigest() == header.split("sha256=")[1]. Failed deliveries are retried twice; recent delivery results show in the console. Events: envelope.sent recipient.viewed recipient.signed recipient.declined recipient.reassigned envelope.completed envelope.voided envelope.expired reminder.sent

Reference

EndpointWhat it does
GET /accountKey owner + usage.
POST /envelopesCreate (and optionally send) an envelope.
GET /envelopes?status=&limit=&offset=List your envelopes.
GET /envelopes/:idFull detail incl. recipients + fields.
POST /envelopes/:id/sendSend a draft.
POST /envelopes/:id/voidVoid with a reason.
POST /envelopes/:id/remindNudge pending signers by email.
POST /envelopes/:id/recipients/:rid/signing-linkEmbedded signing URL (+ return_url).
GET /envelopes/:id/documentDownload the sealed, signed PDF.
GET /envelopes/:id/auditHash-chained audit trail as JSON.