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.
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"
}'# 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 "", 200PennyPDF vs DocuSign API
| PennyPDF | DocuSign API | |
|---|---|---|
| Price per signer | 3 coins (~$0.12) | Bundled in $25-$45/user/mo |
| Entry minimum | $0.99 one-time | $10/mo Personal (5 envelopes) |
| Audit trail | Included, per envelope | Included |
| Legal standing | E-SIGN / eIDAS SES | E-SIGN / eIDAS SES/QES |
| Salesforce integration | No (roadmap) | Yes |
| Per-envelope cost at 100/mo | $12-$24 | $25-$45/user/mo |
How it works
- 1POST the PDF (or a URL to fetch it from) + signer list to /v1/sign.
- 2We email signing links to each signer. They complete in-browser — no account required on their end.
- 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.