![]() |
VOOZH | about |
We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.
Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.
Follow TNS on your favorite social media networks.
Become a TNS follower on LinkedIn.
Check out the latest featured and trending stories while you wait for your first TNS newsletter.
clientUserId. This value tells Docusign that the signer will complete the document within your app rather than via the standard email workflow. The clientUserId can be any string that uniquely identifies the signer in your system. When you combine it with the recipientId and email, you can generate the embedded signing URL in a later step.
Create an envelope using the Envelopes: create endpoint:
const createEnvelope = async (signerEmail, signerName, clientUserId, accessToken, accountId) => {
const apiClient = new docusign.ApiClient();
apiClient.setBasePath('https://demo.docusign.net/restapi');
apiClient.addDefaultHeader('Authorization', 'Bearer ' + accessToken);
const envelopesApi = new docusign.EnvelopesApi(apiClient);
// Read document file
const fileBytes = fs.readFileSync(path.resolve(__dirname, 'test.pdf'));
const documentBase64 = Buffer.from(fileBytes).toString('base64');
// Create the document definition
const document = new docusign.Document();
document.documentBase64 = documentBase64;
document.name = 'Test Document';
document.fileExtension = 'pdf';
document.documentId = '1';
// Create the signer with a clientUserId for embedded signing
const signer = docusign.Signer.constructFromObject({
email: signerEmail,
name: signerName,
recipientId: '1',
clientUserId: clientUserId, // Required for embedded signing
tabs: {
signHereTabs: [
docusign.SignHere.constructFromObject({
anchorString: '/sn1/',
anchorUnits: 'pixels',
anchorYOffset: '10',
anchorXOffset: '20'
})
]
}
});
const recipients = docusign.Recipients.constructFromObject({ signers: [signer] });
// Create the envelope definition
const envelopeDefinition = new docusign.EnvelopeDefinition();
envelopeDefinition.emailSubject = 'Please sign this document';
envelopeDefinition.documents = [document];
envelopeDefinition.recipients = recipients;
envelopeDefinition.status = 'sent';
// Send the envelope
const results = await envelopesApi.createEnvelope(accountId, { envelopeDefinition });
return results.envelopeId;
};
clientUserId, you can generate the embedded signing URL using the createRecipientView method. You can choose from two types of signing sessions: focused view or classic view.
Focused view (embedded experience): A clean, minimalist signing experience embedded directly into your app. This view shows only the agreement and a navigation button, keeping the signer focused on the document. Customizations are available through the Docusign JS library, enabling you to adjust button appearance and handle completion events within the Document Object Model (DOM) event.
Classic view (redirect experience): Redirects the user to the full Docusign signing session, where they interact with the Docusign standard interface and navigation. Once the signer completes the process, they are redirected back to your application. This view supports advanced features such as ID verification and payment tabs, making it ideal for workflows that require these capabilities.
The code is similar for both classic and focused views, but focused view requires two additional properties to enhance iframe security.
Here’s an example of how to create a recipient view using the Node.js SDK:
const viewRequest = new docusign.RecipientViewRequest.constructFromObject({
authenticationMethod: 'none',
clientUserId: clientUserId, // Must match the one used when creating the envelope
returnUrl: 'https://yourapp.com/signing-complete',
userName: signerName,
email: signerEmail,
//The following properties are only required for focused view
messageOrigins: ['https://apps-d.docusign.com'],
frameAncestors: ['https://yourapp.com', 'https://apps-d.docusign.com']
});
const results = await envelopesApi.createRecipientView(accountId, envelopeId, { recipientViewRequest: viewRequest });
const signingUrl = results.url;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Embedded Signing</title>
<style>
body { font-family: Helvetica, Arial, sans-serif; margin-top: 15px; }
.docusign-agreement { width: 75%; height: 800px; }
</style>
</head>
<body>
<div class="docusign-agreement" id="agreement"></div>
<script src="https://js.docusign.com/bundle.js"></script>
<script>
window.DocuSign.loadDocuSign('<%= integrationKey %>')
.then(docusign => {
const signing = docusign.signing({
url: '<%= url %>', // URL for the signing session
displayFormat: 'focused', // Focused view for a clean, embedded experience
style: {
branding: {
primaryButton: {
backgroundColor: '#333', // Customize primary button
color: '#fff', // Button text color
}
},
signingNavigationButton: {
finishText: 'Document Complete! Thank you!', // Customize finish message
position: 'bottom-center' // Position of navigation button
}
}
});
signing.on('ready', () => console.log('Signing UI is ready'));
signing.on('sessionEnd', event => console.log('Session ended:', event));
signing.mount('#agreement'); // Embeds the signing session
})
.catch(ex => console.error('Error initializing DocuSign:', ex));
</script>
</body>
</html>
signingUrl to launch the full-page signing experience:
res.redirect(signingUrl);
const envelopeDefinition = docusign.EnvelopeDefinition.constructFromObject({
status: 'created',
templateId: 'TEMPLATE_ID',
templateRoles: [{
email: 'user@example.com',
name: 'User Name',
roleName: 'Signer'
}]
});
const envelope = await envelopesApi.createEnvelope(accountId, { envelopeDefinition });
status set to created.
EnvelopeViewSettings. This lets you control the user’s visibility and access to various envelope elements during the embedded session.
let viewRequest = docusign.EnvelopeViewRequest.constructFromObject({
returnUrl: 'https://yourapp.com/return',
viewAccess: 'envelope',
settings: docusign.EnvelopeViewSettings.constructFromObject({
startingScreen: 'prepare',
sendButtonAction: 'send',
showBackButton: 'false',
backButtonAction: 'previousPage',
showHeaderActions: 'false',
showDiscardAction: 'false',
recipientSettings: docusign.EnvelopeViewRecipientSettings.constructFromObject({
showEditRecipients: 'false',
showContactsList: 'false'
}),
documentSettings: docusign.EnvelopeViewDocumentSettings.constructFromObject({
showEditDocuments: 'false',
showEditDocumentVisibility: 'false',
showEditPages: 'false'
}),
taggerSettings: docusign.EnvelopeViewTaggerSettings.constructFromObject({
paletteSections: 'default',
paletteDefault: 'custom'
}),
templateSettings: docusign.EnvelopeViewTemplateSettings.constructFromObject({
showMatchingTemplatesPrompt: 'true'
})
})
});
const senderView = await envelopesApi.createSenderView(accountId, envelope.envelopeId, { envelopeViewRequest: viewRequest });
const senderUrl = senderView.url;
senderUrl using the EnvelopeViews: createSender endpoint.
senderUrl, you can either embed it in an iframe within your app to provide a seamless user experience or redirect the user to this URL. After they complete the envelope configuration and send, Docusign will automatically redirect the user back to the returnUrl specified in the viewRequest.
During the session, the user can:
const brand = docusign.Brand.constructFromObject({
name: 'Your Brand Name',
logoUri: 'https://yourapp.com/logo.png',
colorPalette: {
primary: '#ff5733',
secondary: '#33ff57'
}
});
const brandApi = new docusign.BrandsApi();
const createdBrand = await brandApi.createBrand(accountId, { brand });
const brandId = createdBrand.brandId;
brandId when creating the envelope definition:
const envelopeDefinition = docusign.EnvelopeDefinition.constructFromObject({
status: 'sent',
brandId: 'YOUR_BRAND_ID',
...
});
brandId.
Once applied, your embedded flows — whether signing, sending or editing — will reflect your branding, helping reinforce user trust and visual continuity across every step.