TNS
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
NEW! Try Stackie AI
API Management / Developer tools / JavaScript

How to Use Docusign APIs to Embed Custom Document Signing in an App

Embedding document sending and signing within your app simplifies the user experience while establishing brand consistency and trust.
May 28th, 2025 2:00pm by
Featued image for: How to Use Docusign APIs to Embed Custom Document Signing in an App
Featured image by Marko Aliaksandr on Shutterstock.
Context switching to sign or send a document can interrupt users right when they’re trying to move forward, often pulling them out of your app and into a separate experience. What seems like a small detour — such as opening an email or logging into another platform — can be the difference between completing a task in one tab or getting lost in three. Docusign embedded capabilities help streamline that flow by keeping the entire process within your application. By generating secure URLs using the Docusign eSignature REST API, you can embed document sending, signing and even template editing directly into your app. This enables you to meet users where they are, without any detours to an inbox or a separate platform. Docusign APIs let you customize these embedded workflows to not only simplify the experience, but also make it feel native and fully integrated with your brand. When users stay in your environment from start to finish, you maintain visual consistency, reinforce trust and create a seamless journey.

Building a Docusign Integration

Before you can start embedding with Docusign, you’ll need to create a free developer account. This gives you access to the Docusign demo environment, where you can build and test your integration without sending real documents or using production data. In your demo account, you can experiment with creating reusable documents (called templates), try out different signer flows and generate the API keys you need to authenticate your app. For guidance on everything from setting up your account to building your integration, visit the Docusign Developer Center. There you’ll find step-by-step code examples, detailed guides, sample apps and video tutorials to help you get started.

Embedded Signing with Docusign

The embedded signing flow is designed to keep recipients within your platform, enabling them to sign documents without leaving your app. The process is straightforward:

1. Create and Send an Envelope

To initiate an embedded signing session, create an envelope and assign at least one recipient with a 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;
};

2. Generate a Recipient View (Signing URL)

Once the envelope is created and the signer has a 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.
Focused view embedded signing

Focused-view embedded signing

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.
Classic view embedded signing

Classic view embedded signing

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;
This obtains a signingUrl from the EnvelopeViews: createRecipient endpoint.

3. Redirect the Recipient to the Signing Session

Now that you have the signing URL, you can either redirect the user to the signing session or embed the focused view directly into your app. Here’s an example of how to embed the focused view:
<!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>
Key customizations:
  • Button styling: You can adjust the color and text of the primary button to match your app’s branding.
  • Navigation button: Customize the finish text and its position on the screen, making the end of the signing process feel more personal.
  • User interface (UI) customization: The focused view is minimalist, keeping the signer’s attention solely on the document with minimal UI distractions.
This approach keeps the integration light and seamless, while offering flexibility for visual alignment with your brand. Alternatively, if you prefer the classic view, you can simply redirect your users to the signingUrl to launch the full-page signing experience:
res.redirect(signingUrl);

Embedded Sending with Docusign

The embedded sending flow is for senders: users in your app who need to prepare and send documents. This happens earlier in the envelope lifecycle, giving the user control over how the envelope is configured before it’s sent.

1. Create a Draft Envelope

First, you’ll need to create a draft envelope. This can be as simple or as structured as you need: you can start from a predefined template, or you can create a basic envelope with minimal details and let the user upload documents, add recipients and place fields during the embedded session. Here’s how to begin from a template using the Node SDK:
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 });
This creates an envelope draft using the Envelopes: create endpoint with status set to created.

2. Generate a Sender View

At this stage, the envelope is in draft. Now, generate a sender view — a one-time-use URL that opens the Docusign UI with the envelope preloaded. You can tailor the experience using 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;
This obtains the senderUrl using the EnvelopeViews: createSender endpoint.

3. Redirect the User to the Sender View

Once you have the 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:
  1. Add or remove documents.
  2. Add recipients.
  3. Place fields (tabs).
  4. Finalize and send the envelope.
Embedded sending session (tagger view).

Embedded sending session (tagger view).

By configuring the settings above, you can control exactly what the user can see and do — keeping the sending experience secure, focused and aligned with your app’s workflow. You can extend the sender experience even further by embedding flows for template editing and envelope correction. By storing a library of frequently used templates directly in your app, you can easily make routine updates, such as adjusting document layouts or recipient roles, through the embedded template editing flow without ever leaving your app. If you need to make small changes to an envelope after it has been sent but before it’s signed, you can also embed the envelope correction flow. This allows you to update the sent envelope without sending a new one or restarting the process. The process for both flows is similar to embedded sending: you generate a view request and either embed it in an iframe or redirect the user to the session, depending on the experience you want to offer.

Applying Branding in Embedded Flows

To make embedded experiences feel like a seamless extension of your app, you can apply custom branding to the Docusign UI. This way, users aren’t just staying in your platform — they’re staying in your visual world, too. With Docusign branding, you can customize:
  • Logos and colors: Replace the Docusign logo and apply your brand colors.
  • Text and labels: Customize button text, help messages and instructions.
  • Email appearance: Apply branding to Docusign-generated emails like reminders and notifications.
To apply branding in an embedded flow: 1. Create a brand profile under Settings > Brands in your Docusign account or use the API as shown below.
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;
This creates a brand using the AccountBrands: create endpoint. 2. Include the brandId when creating the envelope definition:
const envelopeDefinition = docusign.EnvelopeDefinition.constructFromObject({
  status: 'sent',
  brandId: 'YOUR_BRAND_ID',
  ...
});
This creates an envelope using the Envelopes: create endpoint and includes your brandId.
Branded embedded signing session.

Branded embedded signing session.

Once applied, your embedded flows — whether signing, sending or editing — will reflect your branding, helping reinforce user trust and visual continuity across every step.

Conclusion

By embedding signing and sending directly into your app with Docusign APIs, you can eliminate unnecessary steps for your users and create a smoother, more integrated experience. Whether you’re facilitating quick document signatures or providing a fully customizable document preparation flow, Docusign embedded APIs allow you to control the experience and ensure that users stay engaged with your platform. With Docusign APIs you can fine-tune every step of the workflow to align it with your app’s design and functionality. Ready to start building?
Group Created with Sketch.
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.