How to Automate Signature Workflows With the DocuSign API
Once signatures are part of a real workflow — onboarding, sales, procurement — the dashboard stops scaling. You want envelopes sent automatically and the signed PDF filed where it belongs. That is what the DocuSign API is for.
Quick answer: Authenticate with JWT grant, POST /restapi/v2.1/accounts/{accountId}/envelopes with a document (base64) and recipients, then set a connect webhook to receive completion events. Production access requires app review.
The authentication step is where most integrations stall. DocuSign does not do simple API keys; it wants OAuth, either Auth Code for user-context calls or JWT for server-to-server.
Which auth flow should you use?
| Flow | Use when |
|---|---|
| JWT Grant | Server-to-server, no user present |
| Auth Code | User logs in and acts on their own account |
For a backend that sends envelopes on its own, JWT is the one you want. You generate an RSA keypair, upload the public key to DocuSign, and sign a JWT assertion to get an access token.
How do you send an envelope?
import requests, base64
with open("contract.pdf", "rb") as f:
doc = base64.b64encode(f.read()).decode()
body = {
"emailSubject": "Please sign your agreement",
"documents": [{"documentBase64": doc,
"name": "Agreement", "fileExtension": "pdf",
"documentId": "1"}],
"recipients": {"signers": [{
"email": "alex@example.com", "name": "Alex Chen",
"recipientId": "1", "routingOrder": "1",
"tabs": {"signHereTabs": [{
"documentId": "1", "pageNumber": "3",
"xPosition": "100", "yPosition": "650"}]}}]},
"status": "sent"
}
r = requests.post(f"{base}/accounts/{acct}/envelopes",
headers={"Authorization": f"Bearer {token}"},
json=body)
print(r.json()["envelopeId"])
Tabs are positioned in points from the top-left of the page. Page numbers start at 1. Getting a signature block in the right place means measuring in the PDF, and it is worth automating with a template instead of hardcoding coordinates.
How do you use templates instead of coordinates?
Build the layout once in the DocuSign UI as a template, then send from the API referencing the template ID and role names. Field positions live in the template, so your code stays clean and marketing can adjust the layout without a deploy.
{"templateId": "abc-123", "status": "sent",
"templateRoles": [{"email": "alex@example.com",
"name": "Alex Chen", "roleName": "Signer"}]}
How do you know when it is signed?
Polling is a bad habit. Configure a Connect webhook and DocuSign posts the envelope status to your endpoint. On envelope-completed, download the signed PDF and archive it. Verify the event signature DocuSign sends, or anyone can forge a completed notification.
What do API limits and access cost?
API access is included with paid plans, but production requires passing a go-live review where DocuSign checks your integration. Sandbox testing is free. The API also enforces rate limits per account; a batch of thousands of envelopes needs pacing rather than a tight loop.
What breaks first?
- Consent: a JWT user must grant consent once for your app, or every call fails with an auth error.
- Coordinate drift: hardcoded positions break when the document layout changes.
- Unverified webhooks: accepting unsigned callbacks is a real security hole.
- Expired tokens: access tokens are short-lived; your client must refresh.
Who this suits: teams sending more than a handful of agreements a month or embedding signing inside their own product. Who should skip it: if you send a few documents a week, the dashboard plus templates covers it with zero integration work.
Quick Summary
- Use JWT grant for server-to-server sending, Auth Code for user actions.
- Send envelopes to
/accounts/{id}/envelopeswith base64 documents. - Templates beat hardcoded tab coordinates for maintainability.
- Use Connect webhooks and verify their signatures before trusting events.
- Production API access requires a go-live review with DocuSign.
