SiggyAPI docsManage API keys ›

Siggy API

Send documents for signature programmatically: upload a PDF, place signature fields, and send an envelope to one or more recipients.

API access is included on the Business and Unlimited plans. Keys stop working if the organisation later downgrades.
Using Microsoft Power Automate? There's a dedicated step-by-step integration guide with a ready-made custom connector.

1. Authentication

Authenticate every request with an API key as a bearer token:

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Create a key under Security → API keys. The full key is shown once — copy it immediately. Revoke a key any time; revoked keys return 401 instantly. Keys belong to your organisation, not a single user — keep them secret.

Base URL:

https://siggy.com.au/api/be/v1

2. Endpoints

POST /v1/documents — upload a PDF

multipart/form-data with one file field (PDF, max 25 MB).

curl -X POST $BASE/documents \
  -H "Authorization: Bearer $SIGGY_API_KEY" \
  -F "[email protected];type=application/pdf"

# → { "id": "f1e2d3c4-…", "page_count": 3 }

POST /v1/envelopes — create & send

Creates a draft from a document, places fields, and sends it immediately. Returns a signing link per recipient (signers are also emailed automatically).

curl -X POST $BASE/envelopes \
  -H "Authorization: Bearer $SIGGY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_id": "f1e2d3c4-…",
    "title": "Engagement letter — Acme",
    "routing_mode": "sequential",
    "recipients": [
      { "name": "Jane Smith", "email": "[email protected]", "routing_order": 1 }
    ],
    "fields": [
      { "recipient_index": 0, "type": "signature",   "page": 3,
        "x": 0.10, "y": 0.80, "w": 0.30, "h": 0.08 },
      { "recipient_index": 0, "type": "date_signed", "page": 3,
        "x": 0.55, "y": 0.80, "w": 0.20, "h": 0.04 }
    ]
  }'

# → { "id": "9a8b…", "status": "sent",
#     "recipients": [ { "name": "Jane Smith", "email": "[email protected]",
#                       "sign_url": "https://siggy.com.au/sign/AbC123…" } ] }
RecipientNotes
name, emailRequired.
routing_orderDefault 1. Lower signs first when sequential.
rolesigner (default), in_person, copy.
access_codeOptional 2FA code. Professional+ only.
FieldNotes
recipient_index0-based index into recipients[].
typesignature, initials, date_signed, name, email, company, title, date, text, number, checkbox.
page1-based page number.
x, y, w, hNormalised 0–1, top-left origin (see Coordinates).
requiredDefault true.

GET /v1/envelopes/{id} — check status

curl $BASE/envelopes/9a8b… -H "Authorization: Bearer $SIGGY_API_KEY"

# → { "id": "9a8b…", "title": "…", "status": "sent",
#     "recipients": [ { "name": "Jane Smith", "email": "[email protected]", "status": "sent" } ] }

Envelope status: sent → in_progress → completed (or declined / voided). Recipient status: pending → sent → signed.

GET /v1/envelopes — list (paginated)

curl "$BASE/envelopes?limit=25&offset=0&status=completed" \
  -H "Authorization: Bearer $SIGGY_API_KEY"

# → { "data": [ { "id": "…", "title": "…", "status": "completed", … } ],
#     "has_more": false, "limit": 25, "offset": 0 }

GET /v1/envelopes/{id}/document  ·  /certificate

Download the tamper-evident sealed PDF and the completion certificate (both available once the envelope is completed; 409 until then). Returns application/pdf.

POST /v1/envelopes/{id}/remind  ·  /void

Remind resends the signing email to whoever the envelope is waiting on. Void cancels an in-flight envelope and invalidates every signing link (audited; pass an optional { "reason": "…" }). Both return 409 once the envelope is completed, declined, or voided.

GET /v1/templates  ·  POST /v1/templates/{id}/send

The recommended integration pattern. Design the document and field layout once in Templates, then send it programmatically with just a name and email — no field coordinates in your code. Provide exactly one recipient per template role, in role order.

curl "$BASE/templates" -H "Authorization: Bearer $SIGGY_API_KEY"
# → { "data": [ { "id": "tpl-…", "name": "Engagement letter",
#                 "roles": [ { "role": "signer", "routing_order": 1 } ] } ] }

curl -X POST "$BASE/templates/tpl-…/send" \
  -H "Authorization: Bearer $SIGGY_API_KEY" -H "Content-Type: application/json" \
  -d '{ "title": "Engagement letter — Acme",
        "recipients": [ { "name": "Jane Smith", "email": "[email protected]" } ] }'

# → { "id": "9a8b…", "status": "sent", "recipients": [ { …, "sign_url": "…" } ] }

3. Coordinates

Field positions are normalised so they're independent of page size or zoom. (x, y) is the top-left corner — (0,0) is the top-left of the page, (1,1) the bottom-right. w/h are fractions of the page, and x + w / y + h must stay ≤ 1.

4. Quota & billing

Each envelope counts against your plan's monthly quota. When it's spent, POST /v1/envelopes returns 402 until next month or an upgrade.

5. Errors

400Invalid request — bad PDF, field geometry, or recipient.
401Missing, unknown, or revoked API key.
402Plan lacks API access, quota spent, or access code without Professional+.
404Envelope not found (or not yours).
413File too large (> 25 MB).
422File failed the malware scan.

All errors return { "detail": "…" }.

6. Webhooks

Instead of polling, register a webhook endpoint (Security → Webhooks) and Siggy will POST a signed JSON event to your URL when things happen. Each endpoint gets its own signing secret (whsec_…).

Events

envelope.sent, recipient.signed, envelope.completed, envelope.declined.

Payload

POST https://your-app.com/webhooks/siggy
Siggy-Signature: t=1718000000,v1=3a8f...   ← HMAC-SHA256 of "{t}.{body}"

{
  "id": "evt_…",
  "type": "envelope.completed",
  "created": 1718000000,
  "data": {
    "envelope": { "id": "…", "title": "…", "status": "completed", "document_id": "…" },
    "recipients": [ { "id": "…", "name": "Jane", "email": "[email protected]", "status": "signed" } ]
  }
}

Verify the signature

Compute HMAC-SHA256(secret, "{t}.{raw_body}") and compare to the v1 value in the Siggy-Signature header (constant-time). Respond with 2xx to acknowledge — non-2xx responses are retried with backoff.

import hmac, hashlib   # Python example
t, v1 = parse(header)  # "t=...,v1=..."
expected = hmac.new(secret.encode(), f"{t}.{raw_body}".encode(), hashlib.sha256).hexdigest()
assert hmac.compare_digest(expected, v1)

7. Connect your platform

The pattern is the same everywhere: design a template in Siggy once → your platform calls POST /v1/templates/{id}/send → a webhook tells you when it's signed.

Python

import requests

BASE = "https://siggy.com.au/api/be/v1"
H = {"Authorization": "Bearer sk_live_…"}

templates = requests.get(f"{BASE}/templates", headers=H).json()["data"]
tpl = next(t for t in templates if t["name"] == "Engagement letter")
sent = requests.post(f"{BASE}/templates/{tpl['id']}/send", headers=H, json={
    "title": "Engagement letter — Acme",
    "recipients": [{"name": "Jane Smith", "email": "[email protected]"}],
}).json()
print(sent["id"], sent["recipients"][0]["sign_url"])

Node.js

const BASE = "https://siggy.com.au/api/be/v1";
const H = { Authorization: `Bearer ${process.env.SIGGY_API_KEY}`,
            "content-type": "application/json" };

const { data } = await fetch(`${BASE}/templates`, { headers: H }).then(r => r.json());
const tpl = data.find(t => t.name === "Engagement letter");
const sent = await fetch(`${BASE}/templates/${tpl.id}/send`, {
  method: "POST", headers: H,
  body: JSON.stringify({ recipients: [{ name: "Jane Smith", email: "[email protected]" }] }),
}).then(r => r.json());

Zapier (no code)

  1. Trigger: Webhooks by Zapier → Catch Hook. Paste the hook URL into Siggy under Security → Webhooks — your Zap now fires on envelope.completed and friends.
  2. Action: Webhooks by Zapier → Custom Request: POST to …/v1/templates/{id}/send with your Authorization header and the recipient mapped from any of Zapier's 6,000+ apps (new HubSpot contact, Google Sheets row, Xero invoice…).

Make (Integromat) & Power Automate

Same two halves: a custom webhook / "when an HTTP request is received" module as the trigger (paste its URL into Siggy webhooks), and an HTTP request module for sending. Typical Power Automate flow: new file in SharePoint → upload via /v1/documents → send → save the signed PDF back on envelope.completed.

Ready to start? Create an API key ›