Official Python SDK for the Docuplete API
Project description
Docuplete Python SDK
Official Python client for the Docuplete API — document automation, guided client interviews, and e-signatures for high-compliance industries.
Installation
pip install docuplete
# or
poetry add docuplete
Requires Python 3.8+ and httpx (installed automatically).
Quick start
import os
from docuplete import Docuplete
client = Docuplete(api_key=os.environ["DOCUPLETE_API_KEY"])
# Create a session — returns an interview URL to send to your client
result = client.sessions.create(
package_id=42,
prefill={
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"phone": "555-867-5309",
},
link_expiry_days=14,
reminders={"enabled": True, "interval_days": 3},
)
print(result["interview_url"]) # https://docuplete.com/...
print(result["session_token"]) # df_a1b2c3...
print(result["expires_at"]) # 2026-05-23T14:00:00Z
Sessions
Create a session
result = client.sessions.create(
package_id=42,
prefill={"first_name": "Jane", "email": "jane@example.com"},
link_expiry_days=7,
locale="es",
reminders={"enabled": True, "interval_days": 2},
)
Multi-party signing
result = client.sessions.create(
package_id=42,
prefill={"property_address": "123 Main St"},
signers=[
{"email": "buyer@example.com", "name": "Alice Buyer", "order": 0},
{"email": "seller@example.com", "name": "Bob Seller", "order": 1},
{"email": "agent@example.com", "name": "Carol Agent", "order": 2},
],
)
Bulk session creation (up to 100)
contacts = [{"email": "a@co.com", "name": "Alice"}, {"email": "b@co.com", "name": "Bob"}]
result = client.sessions.bulk_create([
{
"package_id": 42,
"prefill": {"email": c["email"], "first_name": c["name"]},
}
for c in contacts
])
for r in result["results"]:
if r["ok"]:
print("Created:", r["session_token"])
else:
print(f"Item {r['index']} failed: {r['error']}")
Get session status
session = client.sessions.get("df_a1b2c3...")
print(session["status"]) # "generated"
print(session["answers"]) # {"first_name": "Jane", ...}
print(session["pdf_url"]) # download URL (when generated)
Session audit log
log = client.sessions.audit_log("df_a1b2c3...")
for entry in log["entries"]:
print(entry["event"], entry["created_at"], entry["actor_ip"])
Multi-party signer status
result = client.sessions.signers("df_a1b2c3...")
for signer in result["signers"]:
print(signer["email"], signer["status"])
Send or re-send a link
client.sessions.send_link(
"df_a1b2c3...",
recipient_email="jane@example.com",
recipient_name="Jane Smith",
custom_message="Please complete your intake form at your earliest convenience.",
)
Void a session
client.sessions.void("df_a1b2c3...", reason="Sent to wrong client", notify_signer=True)
PDF generation (manual trigger)
import time
result = client.sessions.generate("df_a1b2c3...")
if result["status"] == "generated":
print("Ready:", result["download_url"])
else:
# Poll until ready
while True:
time.sleep(2)
status = client.sessions.get_generate_status(result["token"])
if status["status"] == "ready":
print("PDF:", status["download_url"])
break
if status["status"] == "failed":
raise RuntimeError(status.get("error", "PDF generation failed"))
Packages
# List all packages
packages = client.packages.list()
for pkg in packages:
print(pkg["id"], pkg["name"])
# Get a specific package
pkg = client.packages.get(42)
Webhook verification
Always verify the X-Docuplete-Signature header before processing a webhook payload.
FastAPI
import os
from fastapi import FastAPI, Request, HTTPException
from docuplete import construct_webhook_event
app = FastAPI()
@app.post("/webhook/docuplete")
async def docuplete_webhook(request: Request):
raw_body = (await request.body()).decode()
sig = request.headers.get("x-docuplete-signature", "")
try:
event = construct_webhook_event(
raw_body, sig, os.environ["DOCUPLETE_WEBHOOK_SECRET"]
)
except ValueError:
raise HTTPException(status_code=401, detail="Invalid signature")
if event["event"] == "pdf.generated":
print("PDF ready:", event["download_url"])
elif event["event"] == "session.submitted":
print("Submitted answers:", event["answers"])
return {"ok": True}
Flask
import os
from flask import Flask, request
from docuplete import construct_webhook_event
app = Flask(__name__)
@app.post("/webhook/docuplete")
def docuplete_webhook():
raw_body = request.get_data(as_text=True)
sig = request.headers.get("X-Docuplete-Signature", "")
try:
event = construct_webhook_event(
raw_body, sig, os.environ["DOCUPLETE_WEBHOOK_SECRET"]
)
except ValueError:
return "Invalid signature", 401
match event["event"]:
case "pdf.generated":
print("PDF ready:", event["download_url"])
case "session.submitted":
print("Submitted answers:", event["answers"])
return "", 200
Django
import os, json
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from docuplete import construct_webhook_event
@csrf_exempt
def docuplete_webhook(request):
raw_body = request.body.decode("utf-8")
sig = request.headers.get("X-Docuplete-Signature", "")
try:
event = construct_webhook_event(
raw_body, sig, os.environ["DOCUPLETE_WEBHOOK_SECRET"]
)
except ValueError:
return HttpResponse(status=401)
if event["event"] == "pdf.generated":
print("PDF ready:", event["download_url"])
return HttpResponse(status=200)
Error handling
from docuplete import Docuplete, DocupleteError
client = Docuplete(api_key=os.environ["DOCUPLETE_API_KEY"])
try:
result = client.sessions.create(package_id=999, prefill={})
except DocupleteError as e:
print(e.status) # 404
print(e.code) # "package_not_found"
print(str(e)) # "Package not found"
print(e.issues) # [] or ["field_name: message"]
Context manager
with Docuplete(api_key=os.environ["DOCUPLETE_API_KEY"]) as client:
result = client.sessions.create(package_id=42, prefill={})
# Connection pool is closed automatically on exit
Configuration
client = Docuplete(
api_key="dp_live_...",
timeout=60.0, # seconds (default: 30)
base_url="https://api.docuplete.com", # override for testing
)
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docuplete-0.1.0.tar.gz.
File metadata
- Download URL: docuplete-0.1.0.tar.gz
- Upload date:
- Size: 16.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
498c73a099a385995690d992b28530ebfa5fee403999eabd495c15056c220866
|
|
| MD5 |
557b61b857866e12e8557768178f9526
|
|
| BLAKE2b-256 |
116866081983163a2a08d699438e256b9ad06ef0d13fc50c0c62e369823714cf
|
File details
Details for the file docuplete-0.1.0-py3-none-any.whl.
File metadata
- Download URL: docuplete-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0887caec583273479e8b7705d9f1383946657541d82c4b89e3ebf0fabf010560
|
|
| MD5 |
5cb8a4e223fa147bc6e6ddd017bf61c8
|
|
| BLAKE2b-256 |
de80ad46b593b5620ea3734f5ed0cd9a0ef0b6f147d54840f3d38d49dc361e61
|