DocuSign Integration¶
Cruits uses the DocuSign eSignature REST API with JWT Grant (server-to-server) authentication to manage embedded signing flows for worker onboarding and placement documents.
Environment Variables¶
| Variable | Required | Default (dev) | Description |
|---|---|---|---|
DOCUSIGN_BASE_URL |
No | https://demo.docusign.net/restapi |
REST API base URL. Use https://na4.docusign.net/restapi (or region equivalent) in production. |
DOCUSIGN_OAUTH_HOST |
No | account-d.docusign.com |
OAuth host for JWT token exchange. Use account.docusign.com in production. |
DOCUSIGN_INTEGRATION_KEY |
Yes | — | Client ID (Integration Key) from the DocuSign app. |
DOCUSIGN_USER_ID |
Yes | — | GUID of the DocuSign user being impersonated (the API service account). |
DOCUSIGN_ACCOUNT_ID |
Yes | — | DocuSign account ID (GUID) for all API calls. |
DOCUSIGN_PRIVATE_KEY_FILE |
Yes | — | Absolute path to the RSA private key PEM file used to sign JWT assertions. |
DOCUSIGN_WEBHOOK_SECRET |
Yes | — | HMAC secret configured in DocuSign Connect for verifying incoming webhook signatures. |
DOCUSIGN_JWT_SCOPES |
No | signature impersonation |
Space-separated JWT scopes. |
Dev vs prod: The defaults point to the DocuSign developer sandbox (
-dsuffix on hosts). Swap bothDOCUSIGN_BASE_URLandDOCUSIGN_OAUTH_HOSTwhen going to production.
Setup Steps¶
1. Create a DocuSign App¶
- Log in to the DocuSign Developer Center (sandbox) or Admin portal (production).
- Go to Apps and Keys → Add App and Integration Key.
- Under Authentication, add a RSA Keypair — download the private key and store it on the server (referenced by
DOCUSIGN_PRIVATE_KEY_FILE). - Add
https://<your-domain>/api/screenings/docusign/webhookas an allowed Redirect URI (required by DocuSign even for JWT grant). - Note the Integration Key (client ID) and set
DOCUSIGN_INTEGRATION_KEY.
2. Grant Impersonation Consent¶
The service account user must grant consent to be impersonated. Navigate to:
https://account-d.docusign.com/oauth/auth
?response_type=code
&scope=signature%20impersonation
&client_id=<DOCUSIGN_INTEGRATION_KEY>
&redirect_uri=<your-redirect-uri>
Log in as the impersonated user and accept. This is a one-time step per environment.
3. Configure DocuSign Connect (Webhook)¶
- In the DocuSign Admin portal → Connect → Add Configuration.
- Set the URL to
https://<your-domain>/api/screenings/docusign/webhook. - Under Trigger Events, enable: Envelope Sent, Envelope Delivered, Envelope Completed, Envelope Declined, Envelope Voided.
- Under Security Settings, enable HMAC signature and copy the generated secret into
DOCUSIGN_WEBHOOK_SECRET.
How It Works¶
Authentication¶
DocuSignClient generates a short-lived RS256-signed JWT assertion and exchanges it for an access token via the /oauth/token endpoint. Tokens are cached in ExternalServiceToken (DB) and reused until expiry, avoiding redundant token requests.
Envelope Lifecycle¶
create_envelope() → Draft envelope (status = created, no documents)
add_documents() → PUT documents to draft envelope (as they arrive asynchronously)
send_envelope() → Transition draft → sent (triggers DocuSign email / embedded view)
create_recipient_view() → Short-lived embedded signing URL (clientUserId = worker.pk)
All envelope state is persisted in DocuSignEnvelope (integrations/models.py).
Phases¶
| Phase | DocuSignEnvelopePhase |
Documents | FK on DocuSignEnvelope |
|---|---|---|---|
| Phase 1 (general screening) | PHASE_ONE |
Screening pack (code of conduct, ABU, …) generated in Salesforce | worker |
| Phase 2 (placement) | PHASE_TWO |
Placement pack (Uitzendbevestiging, Arbeidscontract, …) | worker + placement |
API Endpoints¶
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/api/screenings/docusign/envelopes/<id>/sign-url |
Worker JWT | Returns a short-lived embedded signing URL (?return_url=<frontend-url> required). |
POST |
/api/screenings/docusign/webhook |
HMAC signature | DocuSign Connect event receiver. Updates DocuSignEnvelope.status. |
Webhook Verification¶
Incoming Connect requests are verified by verify_connect_signature() in integrations/docusign/client.py. The function computes HMAC-SHA256(secret, raw_body) and compares it to the X-DocuSign-Signature-1 header value (base64-encoded). Requests that fail verification receive 401.
Document Flow Reference¶
See placement-confirmation-flow.md for the end-to-end sequence showing when envelopes are created, filled, and sent within the placement confirmation journey.
Relevant Code¶
| File | Purpose |
|---|---|
integrations/docusign/client.py |
DocuSignClient (auth), DocuSignService (envelope operations) |
integrations/docusign/webhooks.py |
DocuSignWebhookProcessor — maps Connect events to DocuSignEnvelope status |
integrations/docusign/serializers.py |
DRF serializers for the Connect webhook payload |
integrations/models.py |
DocuSignEnvelope, DocuSignEnvelopeDocument, DocuSignEnvelopePhase, DocuSignEnvelopeStatus |
screenings/views.py |
DocuSignConnectWebhookView, DocuSignSignUrlView |
screenings/tasks.py |
create_phase_one_envelope — creates draft envelope and kicks document generation |
screenings/urls.py |
URL routing for DocuSign endpoints |