pennypdf

Developer API

PDF signature API

Signature APIs are priced aggressively because the incumbent (DocuSign) defined the reference at $25-$45 per user per month with per-envelope overages. Dropbox Sign (formerly HelloSign) undercuts at $15/user/month. Adobe Sign plugs into Creative Cloud at similar numbers. All three assume you're a company with seats — none of them fit a solo product that just needs to send 50 signed contracts a month.

PennyPDF's /v1/sign takes a PDF and a list of signer emails, dispatches signing links, and returns the signed PDF + audit trail when all signers complete. 3 coins per signer (~$0.12 at Saver, $0.09 at Pro). A 2-signer contract costs $0.18-$0.24. That's the total — no per-user subscription, no per-envelope fee, no seats.

Legally binding under E-SIGN Act (US), eIDAS SES tier (EU), IT Act (India), UECA (Canada). The audit trail certificate appended to every signed PDF contains per-signer timestamp, IP, user-agent, geo (from IP), and SHA-256 of the signed document. Court-admissible; case law under these regimes has upheld this class of e-signature since 2000.

Copy, paste, ship

Same bearer-token auth across every endpoint. Set PENNYPDF_API_KEY in your environment first.

curlPOST /v1/sign
curl -X POST https://api.pennypdf.com/v1/sign \
  -H "Authorization: Bearer $PENNYPDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pdf_url": "https://your-app.com/contracts/123.pdf",
    "signers": [
      {"email": "alice@example.com", "name": "Alice Smith", "fields": [{"page": 3, "x": 100, "y": 200}]},
      {"email": "bob@example.com",   "name": "Bob Jones",   "fields": [{"page": 3, "x": 100, "y": 260}]}
    ],
    "callback_url": "https://your-app.com/webhooks/pennypdf-signed",
    "order": "sequential"
  }'
Pythonsigned-contract webhook handler
# In your Flask/FastAPI/Django app
@app.post("/webhooks/pennypdf-signed")
def handle_signed(payload: dict):
    # PennyPDF signs each webhook with HMAC-SHA256 via the PennyPDF-Signature header
    verify_hmac(request.headers["PennyPDF-Signature"], request.body, WEBHOOK_SECRET)

    if payload["event"] == "sign.completed":
        # Download signed PDF + audit trail certificate
        signed_pdf = requests.get(payload["signed_pdf_url"]).content
        store_contract(payload["envelope_id"], signed_pdf)
    return "", 200

PennyPDF vs DocuSign API

 PennyPDFDocuSign API
Price per signer3 coins (~$0.12)Bundled in $25-$45/user/mo
Entry minimum$0.99 one-time$10/mo Personal (5 envelopes)
Audit trailIncluded, per envelopeIncluded
Legal standingE-SIGN / eIDAS SESE-SIGN / eIDAS SES/QES
Salesforce integrationNo (roadmap)Yes
Per-envelope cost at 100/mo$12-$24$25-$45/user/mo

How it works

  1. 1POST the PDF (or a URL to fetch it from) + signer list to /v1/sign.
  2. 2We email signing links to each signer. They complete in-browser — no account required on their end.
  3. 3When all signers complete, we POST to your webhook with a signed-PDF URL + audit trail certificate.

Frequently asked

Will these signatures hold up in court?+

Yes in US/EU/Canada/India under E-SIGN/eIDAS SES/UECA/IT Act. The audit trail is what makes this work — every signer's timestamp, IP, user-agent, and a hash of the exact document they saw. Case law has consistently upheld this class of signature since 2000.

Can signers complete without creating an account?+

Yes. Each signer gets a single-use link tied to their email. They click, see the document, drop their signature in the designated field, click Sign. No signup, no password.

Sequential vs parallel signing?+

Set `order: sequential` to have signers notified one at a time (B signs after A completes). `order: parallel` emails all signers simultaneously. Mixed workflows (A+B parallel, then C) aren't yet supported in a single request — use two /v1/sign calls chained.

What's in the audit trail?+

For each signer: full name, email, timestamp (UTC + local), IP address, user-agent, geo-region (country/state from IP), and SHA-256 of the document at time of signing. Appended as a certificate-of-completion page.

Can I send reminders to non-signing signers?+

Automatic reminders fire at 24h, 72h, and 168h. Customize timing via the `reminders: [hours]` parameter. Disable entirely with `reminders: []`.

Rate limits?+

50 /v1/sign requests per minute (each request can have N signers). For bulk workflows like 'send 500 renewal contracts', use the async bulk-send endpoint which is rate-limited by coin balance only.

Why PennyPDF

  • No subscription. Ever.
  • Coins never expire — use them in 5 years.
  • Client-side processing for 14 of 22 tools.
  • No watermarks at any tier.
  • Per-operation pricing, shown before you click.
  • Same coins for web + public API.