Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Docusign eSign
https://github.com/docusign/docusign-esign-node-client
Admin
The Official Docusign eSignature Node Client SDK enables developers to integrate eSignatures,
...
Tokens:
17,756
Snippets:
90
Trust Score:
9.4
Update:
3 weeks ago
Context
Skills
Chat
Benchmark
85.2
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Docusign eSign Node Client SDK The Docusign eSign Node Client SDK is the official Node.js library for integrating with the Docusign eSignature REST API (v2.1). It provides a comprehensive set of APIs to create and send envelopes, manage recipients, handle templates, collect signatures, and track documents directly from your Node.js applications. The SDK supports both callback and Promise-based patterns for asynchronous operations. This SDK enables developers to automate document workflows, embed signing experiences, manage accounts and users, and integrate eSignature capabilities into web and server applications. It includes built-in OAuth authentication support (JWT and Authorization Code Grant), automatic token handling, and over 400 model classes representing Docusign resources like envelopes, templates, recipients, and tabs. ## Installation Install the SDK via npm: ```bash npm install docusign-esign --save ``` ## Authentication - JWT User Token The JWT (JSON Web Token) authentication flow allows server-to-server authentication without user interaction. This is ideal for background processing and automated workflows. ```javascript const docusign = require('docusign-esign'); const fs = require('fs'); // Initialize the API client const apiClient = new docusign.ApiClient(); apiClient.setBasePath('https://demo.docusign.net/restapi'); // Configure JWT authentication const SCOPES = ['signature', 'impersonation']; const jwtLifeSec = 3600; // Token lifetime in seconds const privateKeyPath = './private.key'; async function authenticateWithJWT() { try { const privateKey = fs.readFileSync(privateKeyPath); const results = await apiClient.requestJWTUserToken( 'YOUR_INTEGRATION_KEY', // Client ID 'USER_ID_GUID', // User ID to impersonate SCOPES, privateKey, jwtLifeSec ); const accessToken = results.body.access_token; apiClient.addDefaultHeader('Authorization', 'Bearer ' + accessToken); // Get user info to determine account ID and base URI const userInfo = await apiClient.getUserInfo(accessToken); const account = userInfo.accounts.find(a => a.isDefault === 'true'); console.log('Account ID:', account.accountId); console.log('Base URI:', account.baseUri); // Update base path to account-specific URI apiClient.setBasePath(account.baseUri + '/restapi'); return { accountId: account.accountId, apiClient }; } catch (error) { console.error('JWT Authentication failed:', error); throw error; } } ``` ## Authentication - Authorization Code Grant The Authorization Code Grant flow is used for user-facing applications where users log in to authorize your application. ```javascript const docusign = require('docusign-esign'); const apiClient = new docusign.ApiClient(); apiClient.setOAuthBasePath('account-d.docusign.com'); // Use 'account.docusign.com' for production // Step 1: Generate the authorization URL const authorizationUri = apiClient.getAuthorizationUri( 'YOUR_INTEGRATION_KEY', ['signature'], 'https://your-app.com/callback', 'code', 'optional_state_value' ); console.log('Redirect user to:', authorizationUri); // Step 2: Handle the callback and exchange code for token async function handleCallback(authorizationCode) { try { const tokenResponse = await apiClient.generateAccessToken( 'YOUR_INTEGRATION_KEY', 'YOUR_SECRET_KEY', authorizationCode ); console.log('Access Token:', tokenResponse.accessToken); console.log('Refresh Token:', tokenResponse.refreshToken); console.log('Expires In:', tokenResponse.expiresIn); // Set the token for subsequent API calls apiClient.addDefaultHeader('Authorization', 'Bearer ' + tokenResponse.accessToken); return tokenResponse; } catch (error) { console.error('Token exchange failed:', error); throw error; } } ``` ## Creating and Sending an Envelope The EnvelopesApi allows you to create and send envelopes (document packages) for signature. This example creates an envelope with a document and sends it to a recipient. ```javascript const docusign = require('docusign-esign'); const fs = require('fs'); async function sendEnvelopeForSignature(apiClient, accountId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Read document content const documentBytes = fs.readFileSync('./contract.pdf'); const documentBase64 = Buffer.from(documentBytes).toString('base64'); // Define the document const document = new docusign.Document(); document.documentBase64 = documentBase64; document.name = 'Contract Agreement'; document.fileExtension = 'pdf'; document.documentId = '1'; // Define the signer recipient const signer = new docusign.Signer(); signer.email = 'signer@example.com'; signer.name = 'John Doe'; signer.recipientId = '1'; signer.routingOrder = '1'; // Define where to place the signature tab const signHere = new docusign.SignHere(); signHere.anchorString = '/sn1/'; // Text anchor in document signHere.anchorUnits = 'pixels'; signHere.anchorXOffset = '20'; signHere.anchorYOffset = '10'; // Alternative: absolute positioning // signHere.documentId = '1'; // signHere.pageNumber = '1'; // signHere.xPosition = '200'; // signHere.yPosition = '400'; // Define a date signed tab const dateSigned = new docusign.DateSigned(); dateSigned.anchorString = '/ds1/'; dateSigned.anchorUnits = 'pixels'; // Assign tabs to signer const tabs = new docusign.Tabs(); tabs.signHereTabs = [signHere]; tabs.dateSignedTabs = [dateSigned]; signer.tabs = tabs; // Create recipients object const recipients = new docusign.Recipients(); recipients.signers = [signer]; // Create the envelope definition const envelopeDefinition = new docusign.EnvelopeDefinition(); envelopeDefinition.emailSubject = 'Please sign this contract'; envelopeDefinition.emailBlurb = 'Please review and sign the attached contract.'; envelopeDefinition.documents = [document]; envelopeDefinition.recipients = recipients; envelopeDefinition.status = 'sent'; // 'sent' to send immediately, 'created' for draft try { const results = await envelopesApi.createEnvelope(accountId, { envelopeDefinition: envelopeDefinition }); console.log('Envelope created and sent!'); console.log('Envelope ID:', results.envelopeId); console.log('Status:', results.status); return results; } catch (error) { console.error('Error creating envelope:', error.response?.body || error); throw error; } } ``` ## Creating Embedded Signing Experience Generate a signing URL to embed the signing ceremony directly in your application, providing a seamless user experience. ```javascript const docusign = require('docusign-esign'); async function createEmbeddedSigningUrl(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Create the recipient view request const viewRequest = new docusign.RecipientViewRequest(); viewRequest.returnUrl = 'https://your-app.com/signing-complete'; viewRequest.authenticationMethod = 'none'; viewRequest.email = 'signer@example.com'; viewRequest.userName = 'John Doe'; viewRequest.clientUserId = 'unique-client-user-id'; // Must match the signer's clientUserId // Optional: Configure the signing experience viewRequest.pingFrequency = '300'; // Ping frequency in seconds viewRequest.pingUrl = 'https://your-app.com/ping'; try { const results = await envelopesApi.createRecipientView( accountId, envelopeId, { recipientViewRequest: viewRequest } ); console.log('Signing URL:', results.url); // Redirect the user to this URL or embed in an iframe return results.url; } catch (error) { console.error('Error creating recipient view:', error); throw error; } } // To use embedded signing, the signer must have a clientUserId when created async function createEnvelopeForEmbeddedSigning(apiClient, accountId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); const signer = new docusign.Signer(); signer.email = 'signer@example.com'; signer.name = 'John Doe'; signer.recipientId = '1'; signer.clientUserId = 'unique-client-user-id'; // Required for embedded signing const signHere = new docusign.SignHere(); signHere.documentId = '1'; signHere.pageNumber = '1'; signHere.xPosition = '200'; signHere.yPosition = '400'; signer.tabs = new docusign.Tabs(); signer.tabs.signHereTabs = [signHere]; const document = new docusign.Document(); document.documentBase64 = Buffer.from('Test document content').toString('base64'); document.name = 'Test Document'; document.fileExtension = 'txt'; document.documentId = '1'; const envelopeDefinition = new docusign.EnvelopeDefinition(); envelopeDefinition.emailSubject = 'Please sign'; envelopeDefinition.documents = [document]; envelopeDefinition.recipients = new docusign.Recipients(); envelopeDefinition.recipients.signers = [signer]; envelopeDefinition.status = 'sent'; const results = await envelopesApi.createEnvelope(accountId, { envelopeDefinition: envelopeDefinition }); return results.envelopeId; } ``` ## Using Templates Templates allow you to pre-configure documents with recipient roles, tabs, and settings for reusable signing workflows. ```javascript const docusign = require('docusign-esign'); // List available templates async function listTemplates(apiClient, accountId) { const templatesApi = new docusign.TemplatesApi(apiClient); const results = await templatesApi.listTemplates(accountId, { searchText: 'contract', // Optional: search filter count: '25', startPosition: '0' }); console.log('Total templates:', results.resultSetSize); results.envelopeTemplates.forEach(template => { console.log(`- ${template.name} (ID: ${template.templateId})`); }); return results.envelopeTemplates; } // Create an envelope from a template async function createEnvelopeFromTemplate(apiClient, accountId, templateId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Define template role (maps to roles defined in the template) const templateRole = new docusign.TemplateRole(); templateRole.email = 'signer@example.com'; templateRole.name = 'John Doe'; templateRole.roleName = 'Signer'; // Must match role name in template // Optional: Pre-fill tabs const textTab = new docusign.Text(); textTab.tabLabel = 'company_name'; // Tab label defined in template textTab.value = 'Acme Corporation'; templateRole.tabs = new docusign.Tabs(); templateRole.tabs.textTabs = [textTab]; // Create envelope definition using template const envelopeDefinition = new docusign.EnvelopeDefinition(); envelopeDefinition.templateId = templateId; envelopeDefinition.templateRoles = [templateRole]; envelopeDefinition.status = 'sent'; // Optional: Override email subject envelopeDefinition.emailSubject = 'Please sign the agreement'; try { const results = await envelopesApi.createEnvelope(accountId, { envelopeDefinition: envelopeDefinition }); console.log('Envelope created from template:', results.envelopeId); return results; } catch (error) { console.error('Error creating envelope from template:', error); throw error; } } // Create a new template async function createTemplate(apiClient, accountId) { const templatesApi = new docusign.TemplatesApi(apiClient); const document = new docusign.Document(); document.documentBase64 = Buffer.from('%PDF-1.4 test').toString('base64'); document.name = 'Sample Contract'; document.fileExtension = 'pdf'; document.documentId = '1'; // Define a template role (placeholder for future signers) const signer = new docusign.Signer(); signer.roleName = 'Signer'; signer.recipientId = '1'; signer.routingOrder = '1'; const signHere = new docusign.SignHere(); signHere.documentId = '1'; signHere.pageNumber = '1'; signHere.xPosition = '200'; signHere.yPosition = '400'; signer.tabs = new docusign.Tabs(); signer.tabs.signHereTabs = [signHere]; const recipients = new docusign.Recipients(); recipients.signers = [signer]; const templateDefinition = new docusign.EnvelopeTemplate(); templateDefinition.name = 'Standard Contract Template'; templateDefinition.description = 'Template for standard contracts'; templateDefinition.documents = [document]; templateDefinition.recipients = recipients; templateDefinition.emailSubject = 'Please sign the contract'; const results = await templatesApi.createTemplate(accountId, { envelopeTemplate: templateDefinition }); console.log('Template created:', results.templateId); return results; } ``` ## Managing Envelope Recipients Add, update, and retrieve recipients for an envelope. ```javascript const docusign = require('docusign-esign'); // Get envelope recipients async function getRecipients(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); const recipients = await envelopesApi.listRecipients(accountId, envelopeId, { includeExtended: 'true', includeTabs: 'true' }); console.log('Signers:', recipients.signers?.length || 0); console.log('Carbon Copies:', recipients.carbonCopies?.length || 0); recipients.signers?.forEach(signer => { console.log(`- ${signer.name} (${signer.email}): ${signer.status}`); }); return recipients; } // Add recipients to a draft envelope async function addRecipients(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Add a carbon copy recipient const cc = new docusign.CarbonCopy(); cc.email = 'manager@example.com'; cc.name = 'Jane Manager'; cc.recipientId = '2'; cc.routingOrder = '2'; // Add an additional signer const signer = new docusign.Signer(); signer.email = 'cosigner@example.com'; signer.name = 'Co-Signer'; signer.recipientId = '3'; signer.routingOrder = '1'; const recipients = new docusign.Recipients(); recipients.carbonCopies = [cc]; recipients.signers = [signer]; const results = await envelopesApi.createRecipient(accountId, envelopeId, { recipients: recipients }); console.log('Recipients added'); return results; } // Update recipient information async function updateRecipient(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); const signer = new docusign.Signer(); signer.recipientId = '1'; signer.email = 'newemail@example.com'; signer.name = 'Updated Name'; const recipients = new docusign.Recipients(); recipients.signers = [signer]; const results = await envelopesApi.updateRecipients(accountId, envelopeId, { recipients: recipients }); return results; } ``` ## Retrieving Envelope Status and Documents Check envelope status and download completed documents. ```javascript const docusign = require('docusign-esign'); const fs = require('fs'); // Get envelope status async function getEnvelopeStatus(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); const envelope = await envelopesApi.getEnvelope(accountId, envelopeId, { include: 'recipients,documents' }); console.log('Status:', envelope.status); console.log('Subject:', envelope.emailSubject); console.log('Sent:', envelope.sentDateTime); console.log('Completed:', envelope.completedDateTime); return envelope; } // List envelopes with filters async function listEnvelopes(apiClient, accountId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Get envelopes from the last 30 days const fromDate = new Date(); fromDate.setDate(fromDate.getDate() - 30); const results = await envelopesApi.listStatusChanges(accountId, { fromDate: fromDate.toISOString(), status: 'completed', // Filter by status count: '25', startPosition: '0', include: 'recipients' }); console.log('Total envelopes:', results.totalSetSize); results.envelopes?.forEach(env => { console.log(`- ${env.envelopeId}: ${env.status} (${env.emailSubject})`); }); return results.envelopes; } // Download signed documents async function downloadDocuments(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Get list of documents const docList = await envelopesApi.listDocuments(accountId, envelopeId); console.log('Documents in envelope:'); docList.envelopeDocuments.forEach(doc => { console.log(`- ${doc.documentId}: ${doc.name}`); }); // Download combined PDF (all documents) const combinedDoc = await envelopesApi.getDocument( accountId, envelopeId, 'combined' // 'combined', 'archive', 'certificate', or specific documentId ); fs.writeFileSync('./signed_documents.pdf', combinedDoc, 'binary'); console.log('Documents saved to signed_documents.pdf'); // Download specific document const singleDoc = await envelopesApi.getDocument(accountId, envelopeId, '1'); fs.writeFileSync('./document_1.pdf', singleDoc, 'binary'); return docList; } // Get envelope form data (filled-in field values) async function getFormData(apiClient, accountId, envelopeId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); const formData = await envelopesApi.getFormData(accountId, envelopeId); console.log('Form data:'); formData.recipientFormData?.forEach(recipient => { console.log(`Recipient: ${recipient.name}`); recipient.formData?.forEach(field => { console.log(` ${field.name}: ${field.value}`); }); }); return formData; } ``` ## Account and User Management Manage accounts, users, and permissions. ```javascript const docusign = require('docusign-esign'); // Get account information async function getAccountInfo(apiClient, accountId) { const accountsApi = new docusign.AccountsApi(apiClient); const accountInfo = await accountsApi.getAccountInformation(accountId); console.log('Account Name:', accountInfo.accountName); console.log('Account ID:', accountInfo.accountIdGuid); console.log('Plan:', accountInfo.currentPlanId); console.log('Envelopes Sent:', accountInfo.envelopesSent); return accountInfo; } // List users in account async function listUsers(apiClient, accountId) { const usersApi = new docusign.UsersApi(apiClient); const users = await usersApi.list(accountId, { count: '100', startPosition: '0' }); console.log('Total users:', users.totalSetSize); users.users?.forEach(user => { console.log(`- ${user.userName} (${user.email}): ${user.userStatus}`); }); return users; } // Create a new user async function createUser(apiClient, accountId) { const usersApi = new docusign.UsersApi(apiClient); const newUser = new docusign.UserInformation(); newUser.email = 'newuser@example.com'; newUser.userName = 'New User'; newUser.firstName = 'New'; newUser.lastName = 'User'; const newUsersDefinition = new docusign.NewUsersDefinition(); newUsersDefinition.newUsers = [newUser]; const results = await usersApi.create(accountId, { newUsersDefinition: newUsersDefinition }); console.log('User created:', results.newUsers[0].userId); return results; } // Get user profile async function getUserProfile(apiClient, accountId, userId) { const usersApi = new docusign.UsersApi(apiClient); const profile = await usersApi.getProfile(accountId, userId); console.log('Display Name:', profile.displayName); console.log('Company:', profile.companyName); console.log('Title:', profile.title); return profile; } ``` ## Working with Tabs (Form Fields) Tabs are the interactive fields placed on documents for recipients to fill out or sign. ```javascript const docusign = require('docusign-esign'); function createSignerWithTabs() { const signer = new docusign.Signer(); signer.email = 'signer@example.com'; signer.name = 'John Doe'; signer.recipientId = '1'; // Signature tab const signHere = new docusign.SignHere(); signHere.documentId = '1'; signHere.pageNumber = '1'; signHere.xPosition = '200'; signHere.yPosition = '400'; // Initial tab const initialHere = new docusign.InitialHere(); initialHere.documentId = '1'; initialHere.pageNumber = '1'; initialHere.xPosition = '100'; initialHere.yPosition = '400'; // Text input tab const textTab = new docusign.Text(); textTab.documentId = '1'; textTab.pageNumber = '1'; textTab.xPosition = '200'; textTab.yPosition = '300'; textTab.tabLabel = 'company_name'; textTab.required = 'true'; textTab.width = '200'; textTab.height = '20'; // Date tab const dateTab = new docusign.ModelDate(); dateTab.documentId = '1'; dateTab.pageNumber = '1'; dateTab.xPosition = '200'; dateTab.yPosition = '350'; dateTab.tabLabel = 'start_date'; // Checkbox tab const checkbox = new docusign.Checkbox(); checkbox.documentId = '1'; checkbox.pageNumber = '1'; checkbox.xPosition = '100'; checkbox.yPosition = '500'; checkbox.tabLabel = 'agree_terms'; // Radio group const radioGroup = new docusign.RadioGroup(); radioGroup.groupName = 'payment_method'; radioGroup.documentId = '1'; const radio1 = new docusign.Radio(); radio1.pageNumber = '1'; radio1.xPosition = '100'; radio1.yPosition = '550'; radio1.value = 'credit_card'; const radio2 = new docusign.Radio(); radio2.pageNumber = '1'; radio2.xPosition = '100'; radio2.yPosition = '570'; radio2.value = 'bank_transfer'; radioGroup.radios = [radio1, radio2]; // Number tab const numberTab = new docusign.ModelNumber(); numberTab.documentId = '1'; numberTab.pageNumber = '1'; numberTab.xPosition = '200'; numberTab.yPosition = '250'; numberTab.tabLabel = 'amount'; numberTab.validationPattern = '^\\d+\\.?\\d*$'; // Assign all tabs to signer const tabs = new docusign.Tabs(); tabs.signHereTabs = [signHere]; tabs.initialHereTabs = [initialHere]; tabs.textTabs = [textTab]; tabs.dateTabs = [dateTab]; tabs.checkboxTabs = [checkbox]; tabs.radioGroupTabs = [radioGroup]; tabs.numberTabs = [numberTab]; signer.tabs = tabs; return signer; } // Using anchor strings for tab positioning function createTabsWithAnchors() { const signHere = new docusign.SignHere(); signHere.anchorString = '{{sign_here}}'; signHere.anchorUnits = 'pixels'; signHere.anchorXOffset = '0'; signHere.anchorYOffset = '-5'; signHere.anchorIgnoreIfNotPresent = 'true'; const dateTab = new docusign.DateSigned(); dateTab.anchorString = '{{date}}'; dateTab.anchorUnits = 'pixels'; dateTab.anchorXOffset = '0'; dateTab.anchorYOffset = '0'; const textTab = new docusign.Text(); textTab.anchorString = '{{company}}'; textTab.anchorUnits = 'pixels'; textTab.tabLabel = 'company'; textTab.width = '150'; return { signHereTabs: [signHere], dateSignedTabs: [dateTab], textTabs: [textTab] }; } ``` ## Webhook Event Notifications (Connect) Configure webhooks to receive real-time notifications about envelope events. ```javascript const docusign = require('docusign-esign'); // Create envelope with event notification async function createEnvelopeWithWebhook(apiClient, accountId) { const envelopesApi = new docusign.EnvelopesApi(apiClient); // Configure event notification const eventNotification = new docusign.EventNotification(); eventNotification.url = 'https://your-app.com/docusign/webhook'; eventNotification.loggingEnabled = 'true'; eventNotification.requireAcknowledgment = 'true'; eventNotification.includeDocuments = 'false'; eventNotification.includeCertificateOfCompletion = 'true'; eventNotification.includeDocumentFields = 'true'; // Define envelope events to track const envEvent1 = new docusign.EnvelopeEvent(); envEvent1.envelopeEventStatusCode = 'sent'; const envEvent2 = new docusign.EnvelopeEvent(); envEvent2.envelopeEventStatusCode = 'completed'; const envEvent3 = new docusign.EnvelopeEvent(); envEvent3.envelopeEventStatusCode = 'declined'; const envEvent4 = new docusign.EnvelopeEvent(); envEvent4.envelopeEventStatusCode = 'voided'; eventNotification.envelopeEvents = [envEvent1, envEvent2, envEvent3, envEvent4]; // Define recipient events to track const recEvent1 = new docusign.RecipientEvent(); recEvent1.recipientEventStatusCode = 'Sent'; const recEvent2 = new docusign.RecipientEvent(); recEvent2.recipientEventStatusCode = 'Delivered'; const recEvent3 = new docusign.RecipientEvent(); recEvent3.recipientEventStatusCode = 'Completed'; const recEvent4 = new docusign.RecipientEvent(); recEvent4.recipientEventStatusCode = 'Declined'; eventNotification.recipientEvents = [recEvent1, recEvent2, recEvent3, recEvent4]; // Build envelope definition const document = new docusign.Document(); document.documentBase64 = Buffer.from('Test document').toString('base64'); document.name = 'Test'; document.fileExtension = 'txt'; document.documentId = '1'; const signer = new docusign.Signer(); signer.email = 'signer@example.com'; signer.name = 'Test Signer'; signer.recipientId = '1'; const signHere = new docusign.SignHere(); signHere.documentId = '1'; signHere.pageNumber = '1'; signHere.xPosition = '100'; signHere.yPosition = '100'; signer.tabs = new docusign.Tabs(); signer.tabs.signHereTabs = [signHere]; const envelopeDefinition = new docusign.EnvelopeDefinition(); envelopeDefinition.emailSubject = 'Document with webhook'; envelopeDefinition.documents = [document]; envelopeDefinition.recipients = new docusign.Recipients(); envelopeDefinition.recipients.signers = [signer]; envelopeDefinition.eventNotification = eventNotification; envelopeDefinition.status = 'sent'; const results = await envelopesApi.createEnvelope(accountId, { envelopeDefinition: envelopeDefinition }); console.log('Envelope with webhook created:', results.envelopeId); return results; } // Express.js webhook handler example function handleWebhook(req, res) { const docusignEvent = req.body; console.log('Received webhook event'); console.log('Envelope ID:', docusignEvent.envelopeId); console.log('Status:', docusignEvent.status); // Process different event types switch (docusignEvent.status) { case 'completed': console.log('Envelope completed!'); // Download documents, update database, etc. break; case 'declined': console.log('Envelope declined'); console.log('Reason:', docusignEvent.declinedReason); break; case 'voided': console.log('Envelope voided'); break; } // Acknowledge receipt res.status(200).send('OK'); } ``` ## Bulk Send Operations Send the same envelope to multiple recipients efficiently. ```javascript const docusign = require('docusign-esign'); async function bulkSendEnvelopes(apiClient, accountId, templateId) { const bulkEnvelopesApi = new docusign.BulkEnvelopesApi(apiClient); const envelopesApi = new docusign.EnvelopesApi(apiClient); // Create bulk send list const bulkCopy1 = new docusign.BulkSendingCopy(); const recipient1 = new docusign.BulkSendingCopyRecipient(); recipient1.roleName = 'Signer'; recipient1.name = 'Alice Smith'; recipient1.email = 'alice@example.com'; bulkCopy1.recipients = [recipient1]; const bulkCopy2 = new docusign.BulkSendingCopy(); const recipient2 = new docusign.BulkSendingCopyRecipient(); recipient2.roleName = 'Signer'; recipient2.name = 'Bob Jones'; recipient2.email = 'bob@example.com'; bulkCopy2.recipients = [recipient2]; const bulkSendingList = new docusign.BulkSendingList(); bulkSendingList.name = 'Marketing Campaign Recipients'; bulkSendingList.bulkCopies = [bulkCopy1, bulkCopy2]; // Create the bulk send list const listResult = await bulkEnvelopesApi.createBulkSendList(accountId, { bulkSendingList: bulkSendingList }); console.log('Bulk list ID:', listResult.listId); // Create draft envelope from template const envelopeDefinition = new docusign.EnvelopeDefinition(); envelopeDefinition.templateId = templateId; envelopeDefinition.status = 'created'; // Must be draft for bulk send const draftEnvelope = await envelopesApi.createEnvelope(accountId, { envelopeDefinition: envelopeDefinition }); // Send bulk envelopes const bulkSendRequest = new docusign.BulkSendRequest(); bulkSendRequest.envelopeOrTemplateId = draftEnvelope.envelopeId; const bulkResult = await bulkEnvelopesApi.createBulkSendRequest( accountId, listResult.listId, { bulkSendRequest: bulkSendRequest } ); console.log('Batch ID:', bulkResult.batchId); console.log('Queued:', bulkResult.totalQueued); return bulkResult; } // Check bulk send status async function getBulkSendStatus(apiClient, accountId, batchId) { const bulkEnvelopesApi = new docusign.BulkEnvelopesApi(apiClient); const status = await bulkEnvelopesApi.getBulkSendBatchStatus(accountId, batchId); console.log('Batch Status:', status.batchStatus); console.log('Sent:', status.sent); console.log('Failed:', status.failed); console.log('Queued:', status.queued); return status; } ``` ## Summary The Docusign eSign Node Client SDK provides comprehensive access to the Docusign eSignature platform, enabling developers to build sophisticated document signing workflows. The most common use cases include creating and sending envelopes for signature, embedding signing experiences within web applications, using pre-configured templates for standardized documents, managing recipients and their signing order, and tracking envelope status through polling or webhook notifications. The SDK's Promise-based API makes it easy to integrate with modern async/await patterns in Node.js applications. For enterprise integrations, the SDK supports advanced features such as bulk sending for high-volume operations, composite templates for complex document assembly, and Connect webhooks for real-time event notifications. Authentication is flexible, supporting both JWT for server-to-server communication and OAuth authorization code flow for user-facing applications. The extensive model classes provide type-safe access to all Docusign API resources, making it straightforward to build robust integrations that handle document generation, signature collection, and compliance tracking at scale.