How to Sign PDFs with Python
3 steps to sign a PDF with Python: Install the TurboDocx SDK with pip install turbodocx-sdk, configure TurboSign.configure() with your API key, org ID, and sender email, then call the async TurboSign.send_signature() method with the file, recipients, and signature fields. TurboDocx emails each recipient a signing link and returns an audit trail once everyone has signed.
This guide shows you how to integrate e-signatures into your Django, FastAPI, or Flask application in under 5 minutes.
Last updated: September 23, 2026
5 min
Setup time
Python 3.9+
Type hints included
Async-Native
Built on httpx
Installation
This is the digital signature SDK for Python developers who need e-signatures without building signing UI or PDF plumbing. Install it from PyPI; the package includes full type hints for IDE support.
pip install turbodocx-sdkRequirements: Python 3.9+. TurboSign is async-native; call it with await from asyncio, FastAPI, or Django async views, or run it from sync code with asyncio.run().
Obtaining an API Key
Before you begin, you'll need your API credentials from the TurboDocx dashboard.
- Sign up for a free account at TurboDocx
- Navigate to Settings → API Keys
- Copy your API Key and Organization ID
TURBODOCX_API_KEY=your_api_key_here
TURBODOCX_ORG_ID=your_org_id_here
TURBODOCX_SENDER_EMAIL=you@company.com
TURBODOCX_SENDER_NAME=Your Company NameSending a Signing Request
Use the SDK to send a document for signature. The recipient will receive an email with a link to sign.
import asyncio
import os
from turbodocx_sdk import TurboSign
async def main():
# Configure with your API credentials
TurboSign.configure(
api_key=os.getenv("TURBODOCX_API_KEY"),
org_id=os.getenv("TURBODOCX_ORG_ID"),
sender_email=os.getenv("TURBODOCX_SENDER_EMAIL"), # REQUIRED
sender_name=os.getenv("TURBODOCX_SENDER_NAME") # Recommended
)
# Read PDF file
with open("contract.pdf", "rb") as f:
pdf_file = f.read()
# Send document for signature
result = await TurboSign.send_signature(
file=pdf_file,
document_name="Partnership Agreement",
recipients=[
{"name": "John Doe", "email": "john@example.com", "signingOrder": 1}
],
fields=[
{
"type": "signature",
"recipientEmail": "john@example.com",
"template": {
"anchor": "{signature1}",
"placement": "replace",
"size": {"width": 100, "height": 30}
}
}
]
)
print(f"Document ID: {result['documentId']}")
asyncio.run(main())Tip: To check a document without waiting for a webhook, poll await TurboSign.get_status(result["documentId"]); it returns a status of under_review, completed, voided, or expired.
Processing Results with Webhooks
Configure webhooks to receive real-time notifications when documents are signed. Verify the X-TurboDocx-Signature header with verify_webhook_signature() before trusting a payload, using the raw request body rather than the parsed JSON.
import json
import os
from fastapi import FastAPI, Request, HTTPException
from turbodocx_sdk import TurboSign, verify_webhook_signature
app = FastAPI()
@app.post("/webhooks/turbosign")
async def handle_webhook(request: Request):
# Use the raw body for verification; json.loads() first would change the bytes
raw_body = await request.body()
if not verify_webhook_signature(
raw_body,
request.headers.get("x-turbodocx-signature", ""),
request.headers.get("x-turbodocx-timestamp", ""),
os.getenv("TURBODOCX_WEBHOOK_SECRET"),
):
raise HTTPException(status_code=401, detail="invalid signature")
payload = json.loads(raw_body)
event = payload.get("event")
data = payload.get("data")
if event == "signature.document.completed":
document_id = data["document_id"]
print(f"Document signed: {document_id}")
# Download the signed PDF
signed_pdf = await TurboSign.download(document_id)
# Save to your storage
with open(f"signed-{document_id}.pdf", "wb") as f:
f.write(signed_pdf)
return {"received": True}Conclusion
You now have everything you need to integrate document signing into your Python application using the TurboDocx e-signature API. The async SDK handles authentication, document delivery, signature collection, and legally-binding audit trails.
What you can do next:
- Add multiple recipients with sequential signing order
- Use different field types: initials, dates, text, checkboxes
- Poll
TurboSign.get_status()or verify webhook deliveries for real-time status - Get audit trails and compliance certificates
Related Guides
Sign Documents with TypeScript
Fully typed e-signature integration with imported SDK types and tsconfig setup.
Sign Documents with JavaScript
Integrate document signing into Node.js or TypeScript applications.
Sign Documents with Go
Add document signing to Go applications with idiomatic patterns.
Resources
Frequently Asked Questions
How do I sign a PDF with Python?
Install the TurboDocx SDK (pip install turbodocx-sdk), configure it with your API key, then use TurboSign.send_signature() to send the document for e-signature.
Is there a Python digital signature SDK for PDFs?
Yes. Running pip install turbodocx-sdk adds async document sending, status polling, webhook events, and audit trails to a Python codebase, so you avoid hand-building the HTTP calls and PDF handling.
Does the Python SDK support async/await?
Yes, the TurboDocx Python SDK is fully async-native and built on httpx. Call it from asyncio, FastAPI, or Django async views directly, or wrap a call in asyncio.run() to use it from synchronous code.
What Python version is required?
The TurboDocx Python SDK requires Python 3.9 or higher.
Ready to Get Started?
Create a free account and get your API key. Start sending documents for signature in minutes.