Skip to content

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 (-d suffix on hosts). Swap both DOCUSIGN_BASE_URL and DOCUSIGN_OAUTH_HOST when going to production.

Setup Steps

1. Create a DocuSign App

  1. Log in to the DocuSign Developer Center (sandbox) or Admin portal (production).
  2. Go to Apps and KeysAdd App and Integration Key.
  3. Under Authentication, add a RSA Keypair — download the private key and store it on the server (referenced by DOCUSIGN_PRIVATE_KEY_FILE).
  4. Add https://<your-domain>/api/screenings/docusign/webhook as an allowed Redirect URI (required by DocuSign even for JWT grant).
  5. Note the Integration Key (client ID) and set DOCUSIGN_INTEGRATION_KEY.

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)

  1. In the DocuSign Admin portal → ConnectAdd Configuration.
  2. Set the URL to https://<your-domain>/api/screenings/docusign/webhook.
  3. Under Trigger Events, enable: Envelope Sent, Envelope Delivered, Envelope Completed, Envelope Declined, Envelope Voided.
  4. 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.

JWT assertion (RS256) → POST /oauth/token → access_token (1 h TTL)

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