Skip to main content

Migrating from DocuSign

This guide helps you migrate an existing DocuSign eSignature integration to Propper Sign API with minimal code changes.

Executive Summary

What: Move your e-signature workflows from DocuSign to Propper Sign.

Why it's straightforward: Propper Sign offers backwards-compatible API endpoints for common DocuSign operations, so migrations require minimal code changes—primarily updating the base URL and authentication.

Two options: Switch everything at once (hard cutover) or run both systems in parallel during transition.

Propper Sign offers backwards-compatible API endpoints for core DocuSign v2.1 signing workflows, including envelope creation, embedded signing, recipient routing, document retrieval, and status tracking. See Feature Parity for detailed compatibility information.

Related Guides

Who This Guide Is For

This guide is for you if:

  • You currently call DocuSign eSignature REST API v2.1 from your backend and want to switch to Propper
  • You want minimal code changes and a predictable cutover process

Overview

Most migrations involve three changes:

  1. Base URL — Change where API requests are sent (from DocuSign servers to Propper servers)
  2. Authentication — Change how your system proves its identity (from DocuSign's JWT tokens to Propper's OAuth client credentials)
  3. Webhook strategy — Decide how you'll receive notifications about signing events
DocuSign Base URL

Do not hardcode na1.docusign.net or any specific DocuSign region. DocuSign recommends retrieving the correct base_uri via the UserInfo endpoint ↗ (/oauth/userinfo). The base URI depends on where your DocuSign account is hosted.

Migration Paths

Choose the approach that fits your situation:

Option A: Hard Cutover

Switch base URL and auth in one deployment. Best for:

  • Simple integrations with few endpoints
  • No in-flight DocuSign envelopes to track
  • Teams comfortable with a clean break

Option B: Parallel Operation + Sync

Keep DocuSign running during transition, import into Propper via Connect. Best for:

  • Complex integrations needing gradual migration
  • Existing DocuSign envelopes that need to complete
  • Teams wanting to test Propper before full cutover

See Migration Strategy with DocuSign Connect for the parallel approach.

Quick Migration Checklist

  • Update API base URL to Propper
  • Replace DocuSign auth with Propper OAuth (client credentials)
  • Swap DocuSign SDK usage for:
    • Direct HTTP calls (recommended), or
    • A thin compatibility wrapper
  • Update webhook strategy:
    • If you used DocuSign Connect, decide whether to keep it during transition
    • If you need Propper outbound events, configure Propper Webhooks
  • Test core flows end-to-end (see Testing Checklist)
  • Review Feature Parity (especially tabs and templates)
  • Update error handling for Propper error codes

API Endpoint Mapping

Base URL

EnvironmentDocuSignPropper
Productionhttps://{base_uri} (from UserInfo ↗)https://api.propper.ai
DocuSign Base URI

DocuSign base URI is account-region specific. Always fetch it from /oauth/userinfo rather than hardcoding a region like na1, eu, or au.

Endpoint Paths

Propper uses the same path structure as DocuSign for core eSignature v2.1 envelope operations. Simply replace the base URL:

OperationPath
Create envelopePOST /accounts/{accountId}/envelopes
Get envelopeGET /accounts/{accountId}/envelopes/{envelopeId}
List envelopesGET /accounts/{accountId}/envelopes
Update envelopePUT /accounts/{accountId}/envelopes/{envelopeId}
Get recipientsGET /accounts/{accountId}/envelopes/{envelopeId}/recipients
Recipient viewPOST /accounts/{accountId}/envelopes/{envelopeId}/views/recipient
Sender viewPOST /accounts/{accountId}/envelopes/{envelopeId}/views/sender
List documentsGET /accounts/{accountId}/envelopes/{envelopeId}/documents
Download documentGET /accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}

All paths are prefixed with /restapi/v2.1. See the DocuSign Envelopes API reference ↗ for detailed request/response schemas.

Account ID

In Propper, the {accountId} path parameter is your Propper Organization ID. Find this in your Organization Settings.

Known Differences

Field/FeatureDocuSignPropperNotes
Account IDDocuSign account GUIDPropper org IDDifferent value, same path position
Recipient view returnUrlRequiredRequiredSame field, same behavior
Recipient view clientUserIdRequired for embeddedRequired for embeddedSame field, same behavior

Authentication Migration

DocuSign JWT → Propper OAuth

DocuSign JWT grant ↗ is an OAuth flow for service integrations that commonly uses the signature and impersonation scopes (requiring user consent).

Propper uses OAuth client credentials, which is simpler—no user consent flow required:

// DocuSign JWT authentication
const docusign = require('docusign-esign');

const apiClient = new docusign.ApiClient();
// Note: In production, get base_uri from /oauth/userinfo
apiClient.setBasePath('https://na1.docusign.net/restapi');

const results = await apiClient.requestJWTUserToken(
integrationKey,
userId,
'signature',
privateKey,
3600,
);

const accessToken = results.body.access_token;

Scope Mapping

DocuSign ScopePropper ScopeNotes
signaturesign:read sign:writeFull signing access
extendedsign:read sign:writeTreated as standard signing access
impersonationNot supportedUse Propper service credentials instead

DocuSign scope definitions are documented in their OAuth scopes reference ↗.

SDK Migration Options

This is the most portable approach and avoids SDK coupling:

const docusign = require('docusign-esign');

const envelopesApi = new docusign.EnvelopesApi(apiClient);

const envelope = await envelopesApi.createEnvelope(accountId, {
envelopeDefinition: {
emailSubject: 'Please sign',
documents: [{ documentBase64: '...', documentId: '1', name: 'Contract.pdf' }],
recipients: {
signers: [{ email: 'signer@example.com', name: 'John', recipientId: '1' }],
},
status: 'sent',
},
});

Option B: Thin Compatibility Wrapper

If you have extensive SDK usage, create a compatibility wrapper to minimize code changes:

// propper-docusign-compat.js
class PropperEnvelopesApi {
constructor(baseUrl, accessToken) {
this.baseUrl = baseUrl;
this.accessToken = accessToken;
}

async createEnvelope(accountId, { envelopeDefinition }) {
const response = await fetch(`${this.baseUrl}/restapi/v2.1/accounts/${accountId}/envelopes`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(envelopeDefinition),
});
return response.json();
}

async getEnvelope(accountId, envelopeId) {
const response = await fetch(
`${this.baseUrl}/restapi/v2.1/accounts/${accountId}/envelopes/${envelopeId}`,
{
headers: { Authorization: `Bearer ${this.accessToken}` },
},
);
return response.json();
}

async createRecipientView(accountId, envelopeId, viewRequest) {
const response = await fetch(
`${this.baseUrl}/restapi/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(viewRequest),
},
);
return response.json();
}

// Add more methods as needed...
}

// Usage - minimal code changes from DocuSign SDK
const envelopesApi = new PropperEnvelopesApi('https://api.propper.ai', accessToken);

const envelope = await envelopesApi.createEnvelope(accountId, {
envelopeDefinition: {
/* same structure as before */
},
});

Embedded Signing Migration

When migrating recipient views (embedded signing ↗), ensure your request includes the required fields:

// Recipient view request - same structure for both DocuSign and Propper
const viewRequest = {
returnUrl: 'https://yourapp.com/signing-complete', // Required
authenticationMethod: 'none',
clientUserId: 'user-123', // Required for embedded signing
email: 'signer@example.com',
userName: 'John Smith',
recipientId: '1',
};

const response = await fetch(
`${baseUrl}/restapi/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(viewRequest),
},
);

const { url } = await response.json();
// Redirect user to `url` for signing

Request/Response Compatibility

For core envelope operations, Propper follows DocuSign v2.1 request shapes (envelopeDefinition, recipients, documents, tabs). The DocuSign envelope resource reference ↗ is the baseline for payload structure.

Create Envelope Request

{
"emailSubject": "Please sign this document",
"emailBlurb": "Please review and sign at your convenience.",
"status": "sent",
"documents": [
{
"documentId": "1",
"name": "Contract.pdf",
"documentBase64": "JVBERi0xLjQKJeLjz9M...",
"order": "1"
}
],
"recipients": {
"signers": [
{
"email": "signer@example.com",
"name": "John Smith",
"recipientId": "1",
"routingOrder": "1",
"clientUserId": "user-123",
"tabs": {
"signHereTabs": [
{
"documentId": "1",
"pageNumber": "1",
"xPosition": "100",
"yPosition": "500"
}
]
}
}
]
}
}

This exact payload structure works with both DocuSign and Propper.

Webhooks: Choose the Right Model

DocuSign Connect and Propper Webhooks are separate systems with different purposes:

SystemDirectionPurpose
DocuSign ConnectDocuSign → PropperImport envelopes, sync status during migration
Propper WebhooksPropper → Your appNotify your backend of Propper events

If You Previously Used DocuSign Connect

DocuSign Connect is DocuSign's webhook system with defined event triggers ↗ (e.g., envelope-completed, recipient-completed).

During migration, you can keep DocuSign Connect running and configure Propper to receive those events. This is recommended for gradual transition and historical import. See Migrating Data from DocuSign.

If You Want Propper → Your Backend Notifications

Use Propper Webhooks and subscribe to Propper event names.

Propper Webhook Event Names:

EventDescription
document.sentAgreement sent for signature
document.viewedRecipient opened the signing page
document.signedIndividual recipient completed signing
document.completedAll recipients completed, envelope finalized
document.declinedRecipient declined to sign
document.voidedEnvelope was cancelled
Separate Secrets

Do not reuse your DocuSign Connect HMAC key for Propper webhook verification. These are separate systems with separate secrets. Generate a new webhook secret in the Propper dashboard.

Running Both During Migration

You can run DocuSign Connect (DocuSign → Propper) and Propper Webhooks (Propper → your app) simultaneously:

DocuSign → DocuSign Connect → Propper (imports envelope)

Propper Webhooks → Your Backend (notifies of import)

Feature Parity

Fully Supported (Core Workflows)

FeatureCompatibilityNotes
Envelope create/send✅ FullSame API structure
Multiple recipients✅ FullSequential and parallel routing
Embedded signing (recipient view)✅ FullSame views/recipient ↗ API
Document upload (Base64)✅ FullSame format
Envelope status tracking✅ FullDocuSign-compatible lifecycle ↗
Document download✅ FullSame documents API
Void envelopes✅ FullSame API
Audit trail✅ FullJSON and PDF certificate

Tabs (Signature Fields)

DocuSign supports many tab types ↗. Propper supports the most commonly used:

Tab TypeStatusNotes
signHereTabs✅ SupportedPrimary signature placement
initialHereTabs✅ SupportedInitial placement
dateSignedTabs✅ SupportedAuto-filled signing date
textTabs✅ SupportedFree-form text input
fullNameTabs✅ SupportedAuto-filled signer name
emailTabs✅ SupportedAuto-filled signer email
companyTabs✅ SupportedCompany name field
titleTabs✅ SupportedTitle/role field
checkboxTabs⚠️ PartialBasic support, complex validation coming
radioGroupTabs⚠️ PartialBasic support
listTabs (dropdowns)⚠️ PartialBasic support
formulaTabs❌ Not yetCalculated fields on roadmap
notaryTabs❌ Not yetNotarization not supported
attachmentTabs❌ Not yetOn roadmap
Tab Migration

If your integration uses unsupported tab types, contact support to discuss alternatives or timeline.

Templates

FeatureStatusNotes
Create templates✅ SupportedSame template API structure
Use templates for envelopes✅ SupportedReference by template ID
Template roles✅ SupportedMap recipients to roles
Template tabs⚠️ PartialDepends on tab type support

Not Supported (Use Alternatives)

FeatureAlternative
DocuSign Admin APIUse Propper Admin dashboard
Bulk sendLoop with standard envelope API
PowerFormsUse embedded signing with your own forms
SMS deliveryEmail delivery only
In-person signingStandard embedded signing
IDV (ID Verification)On roadmap

Error Handling

Propper Error Response Format

All Propper API errors return a consistent structure:

{
"error": {
"code": "ENVELOPE_NOT_FOUND",
"message": "The requested envelope does not exist",
"details": {
"envelopeId": "abc123-def456"
},
"requestId": "req_7f8g9h0i1j2k"
}
}
FieldDescription
codeMachine-readable error code for programmatic handling
messageHuman-readable error description
detailsAdditional context (optional, varies by error)
requestIdUnique identifier for support/debugging

Error Code Mapping

DocuSign ErrorPropper ErrorHTTP Status
ENVELOPE_NOT_IN_CORRECT_STATEENVELOPE_CANNOT_BE_MODIFIED400
ENVELOPE_DOES_NOT_EXISTENVELOPE_NOT_FOUND404
RECIPIENT_NOT_IN_SEQUENCERECIPIENT_NOT_FOUND404
INVALID_REQUEST_BODYINVALID_REQUEST_BODY400
USER_AUTHENTICATION_FAILEDUNAUTHORIZED401
USER_NOT_AUTHORIZED_FOR_ACCOUNTFORBIDDEN403
HOURLY_API_LIMIT_EXCEEDEDRATE_LIMIT_EXCEEDED429

Step-by-Step Migration

1. Update Environment Variables

# Before (DocuSign)
# Note: Don't hardcode na1 - use UserInfo to get base_uri
DOCUSIGN_BASE_URL=https://na1.docusign.net
DOCUSIGN_ACCOUNT_ID=abc123
DOCUSIGN_INTEGRATION_KEY=xyz789
DOCUSIGN_USER_ID=user123
DOCUSIGN_PRIVATE_KEY_PATH=./private.key

# After (Propper)
PROPPER_BASE_URL=https://api.propper.ai
PROPPER_AUTH_URL=https://auth.propper.ai
PROPPER_ORG_ID=your-org-id
PROPPER_CLIENT_ID=your-client-id
PROPPER_CLIENT_SECRET=your-client-secret

2. Update Authentication

Replace DocuSign JWT with Propper OAuth client credentials:

// auth.js
let tokenCache = { token: null, expiresAt: 0 };

const getAccessToken = async () => {
// Return cached token if still valid
if (tokenCache.token && Date.now() < tokenCache.expiresAt) {
return tokenCache.token;
}

const response = await fetch(`${process.env.PROPPER_AUTH_URL}/oauth2/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.PROPPER_CLIENT_ID,
client_secret: process.env.PROPPER_CLIENT_SECRET,
scope: 'sign:read sign:write',
}),
});

if (!response.ok) {
const error = await response.json();
throw new Error(`Auth failed: ${error.error?.message || response.statusText}`);
}

const { access_token, expires_in } = await response.json();

// Cache token with 1 minute buffer
tokenCache = {
token: access_token,
expiresAt: Date.now() + expires_in * 1000 - 60000,
};

return access_token;
};

3. Update Base URL

// Before (DocuSign)
// const BASE_URL = 'https://na1.docusign.net/restapi/v2.1';

// After (Propper)
const BASE_URL = 'https://api.propper.ai/restapi/v2.1';

4. Verify Embedded Signing

Test that recipient views work correctly:

// Generate signing URL
const response = await fetch(
`${BASE_URL}/accounts/${orgId}/envelopes/${envelopeId}/views/recipient`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
returnUrl: 'https://yourapp.com/signing-complete',
authenticationMethod: 'none',
clientUserId: 'user-123',
email: 'signer@example.com',
userName: 'John Smith',
recipientId: '1',
}),
},
);

const { url } = await response.json();
// Redirect user to `url` - signer should complete successfully

5. Decide Your Sync Strategy

Hard cutover:

  • Stop creating DocuSign envelopes on cutover date
  • Only import in-flight DocuSign envelopes until they complete

Parallel operation:

Golden Path Example (End-to-End)

Here's a complete flow showing the full signing lifecycle:

// 1. Get access token
const accessToken = await getAccessToken();

// 2. Create and send envelope
const createResponse = await fetch(`${BASE_URL}/accounts/${orgId}/envelopes`, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
emailSubject: 'Please sign: Sales Agreement',
status: 'sent',
documents: [
{
documentId: '1',
name: 'Agreement.pdf',
documentBase64: pdfBase64Content,
},
],
recipients: {
signers: [
{
email: 'customer@example.com',
name: 'Jane Customer',
recipientId: '1',
clientUserId: 'customer-456', // For embedded signing
tabs: {
signHereTabs: [
{ documentId: '1', pageNumber: '1', xPosition: '200', yPosition: '600' },
],
},
},
],
},
}),
});

const { envelopeId } = await createResponse.json();
console.log('Created envelope:', envelopeId);

// 3. Generate embedded signing URL
const viewResponse = await fetch(
`${BASE_URL}/accounts/${orgId}/envelopes/${envelopeId}/views/recipient`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
returnUrl: 'https://yourapp.com/signing-complete?envelopeId=' + envelopeId,
authenticationMethod: 'none',
clientUserId: 'customer-456',
email: 'customer@example.com',
userName: 'Jane Customer',
recipientId: '1',
}),
},
);

const { url: signingUrl } = await viewResponse.json();
console.log('Redirect user to:', signingUrl);

// 4. After signing completes, check status
const statusResponse = await fetch(`${BASE_URL}/accounts/${orgId}/envelopes/${envelopeId}`, {
headers: { Authorization: `Bearer ${accessToken}` },
});

const envelope = await statusResponse.json();
console.log('Envelope status:', envelope.status); // "completed"

// 5. Download signed document
const docResponse = await fetch(
`${BASE_URL}/accounts/${orgId}/envelopes/${envelopeId}/documents/1`,
{
headers: { Authorization: `Bearer ${accessToken}` },
},
);

const signedPdf = await docResponse.arrayBuffer();
console.log('Downloaded signed PDF:', signedPdf.byteLength, 'bytes');

Testing Checklist

Use this checklist to verify your migration. Each checkpoint has specific pass/fail criteria.

Checkpoint 1: Authentication

TestCommandExpected Result
Get tokenPOST /oauth2/token with credentialsReturns access_token and expires_in
Token formatInspect responseaccess_token is non-empty string
Token refreshRequest new token near expiryNew token returned successfully
# Test command
curl -X POST https://auth.propper.ai/oauth2/token \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials","client_id":"...","client_secret":"...","scope":"sign:read sign:write"}'

Checkpoint 2: Envelope Operations

TestExpected Result
Create draft envelope (status: "created")Returns envelopeId, status is "created"
Get envelope by IDReturns envelope with correct fields
List envelopesReturns array including created envelope
Send envelope (status: "sent")Status changes to "sent"

Checkpoint 3: Embedded Signing Flow

TestExpected Result
Create recipient view URLReturns valid url field
Navigate to signing URLSigning page loads, no errors
Complete signatureRedirected to returnUrl
Check envelope statusStatus is "completed"

Checkpoint 4: Document Retrieval

TestExpected Result
List documentsReturns document list with IDs
Download signed PDFReturns valid PDF binary
Verify PDFPDF opens, shows signatures

Checkpoint 5: Webhooks (If Applicable)

TestExpected Result
Receive webhook on envelope sendEvent received, signature verified
Receive webhook on completionEvent received with envelope data
Invalid signature rejected401 returned, event not processed

Common Migration Issues

"Account not found" errors

Cause: Using your DocuSign account ID instead of your Propper organization ID.

Solution: Get your organization ID from Organization Settings in the Propper dashboard.

Authentication failures

Cause: Using DocuSign JWT assumptions (impersonation, user-specific tokens).

Solution: Switch to OAuth client credentials. See DocuSign JWT flow documentation ↗ for what you're migrating from.

Webhook signature verification fails

Cause: Using DocuSign Connect HMAC key for Propper webhooks.

Solution: These are separate systems with separate secrets. Get your Propper webhook secret from the dashboard.

Tabs missing or not rendering

Cause: Using a tab type not yet supported in Propper.

Solution: Check the Tabs compatibility table. Use supported tab types or contact support for timeline on specific tabs.

"Base URL not reachable" in production

Cause: Firewall or network rules allowing only DocuSign domains.

Solution: Allow outbound traffic to api.propper.ai and auth.propper.ai.

Migration Strategy with DocuSign Connect

For gradual migrations, use DocuSign Connect to keep both systems in sync.

Phase 1: Set Up Sync

  1. Configure DocuSign Connect in Propper (setup guide)
  2. Enable auto-import for completed envelopes
  3. Test with a single envelope
  4. Checkpoint: New DocuSign completions appear in Propper

Phase 2: Parallel Operation

  • Continue creating envelopes in DocuSign
  • Completed envelopes sync to Propper automatically
  • Start testing Propper API for new workflows
  • Checkpoint: Can create and complete envelopes in both systems

Phase 3: Gradual Cutover

  • New workflows use Propper API
  • Existing DocuSign envelopes continue syncing
  • Train users on Propper interface
  • Checkpoint: Majority of new envelopes created in Propper

Phase 4: Full Migration

  • All new envelopes created via Propper API
  • DocuSign Connect continues for any in-flight envelopes
  • Once all DocuSign envelopes complete, optionally disable Connect
  • Checkpoint: No new DocuSign envelopes, all operations in Propper

AI-Assisted Migration

Use this prompt with Claude, ChatGPT, or your preferred AI assistant to analyze your codebase and generate a structured migration plan:

📋 Copy Migration Assistant Prompt
You are an expert at migrating DocuSign eSignature REST API v2.1 integrations to Propper Sign API.

## Your Task

Scan the repository and identify all DocuSign usages, then produce a structured migration plan.

## What to Search For

1. **SDK imports:**
- `docusign-esign` (Node.js)
- `DocuSign.eSign` (.NET)
- Similar patterns in other languages

2. **Direct REST calls:**
- URLs containing `docusign.net` or `docusign.com`
- Paths matching `/restapi/v2.1/accounts/`

3. **Auth flows:**
- JWT token requests (`requestJWTUserToken`)
- Auth code flow implementations
- Integration key / user ID references

4. **Recipient views (embedded signing):**
- `/views/recipient` endpoint calls
- `clientUserId` usage patterns

5. **Webhook handlers:**
- DocuSign Connect event processing
- HMAC signature verification
- Event types handled (envelope-completed, recipient-completed, etc.)

6. **Environment variables:**
- `DOCUSIGN_*` prefixed variables
- Base URL configurations

## Required Output

Produce the following sections:

### 1. Inventory Table

| File | Line(s) | Usage Type | DocuSign Feature |
|------|---------|------------|------------------|
| path/to/file.js | 45-60 | SDK import | Authentication |
| ... | ... | ... | ... |

### 2. Tab Types Used

List all tab types found in envelope creation code:
- signHereTabs: ✅ Supported
- dateSignedTabs: ✅ Supported
- formulaTabs: ❌ Not supported (needs alternative)

### 3. Auth Flow Summary

Current: [JWT / Auth Code / other]
Migration: OAuth client credentials

### 4. Webhook Flows

Events currently handled:
- envelope-completed → document.completed
- recipient-completed → document.signed

### 5. PR-Sized Migration Steps

Break the migration into reviewable chunks:

**PR 1: Authentication Migration**
Files: auth.js, config.js
Changes: Replace JWT with client credentials

**PR 2: Base URL Update**
Files: api-client.js
Changes: Update base URL, account ID

**PR 3: Webhook Handler Update**
Files: webhooks/docusign.js
Changes: Update event names, add Propper signature verification

### 6. Compatibility Risks

| Risk | Impact | Mitigation |
|------|--------|------------|
| formulaTabs not supported | Medium | Replace with textTabs, calculate server-side |
| ... | ... | ... |

### 7. End-to-End Test Plan

After migration, verify:

1. [ ] Create envelope with all tab types used
2. [ ] Generate embedded signing URL
3. [ ] Complete signing flow
4. [ ] Verify webhook received with correct event
5. [ ] Download signed document
6. [ ] Confirm audit trail available

Start by searching the codebase for DocuSign integration points.
Pro Tip

For best results, use this prompt with an AI coding assistant that has access to your codebase (like Claude Code, Cursor, or GitHub Copilot). The AI can search files directly and provide specific paths and line numbers.

Need Help?