How to Create Docusign Envelopes with a Variable Number of Signers

DocuSign is an electronic signature platform that allows users to digitally sign, send, and manage any type of document. I’ve been working on a Docusign integration for generating lease documents, where leases can have any number of signers – with a varied mix of primary applicants,  co-signers, co-applicants, and guarantors signing different leases.

We only know who is signing the lease at the time of envelope creation. This presented a significant challenge because DocuSign’s standard template workflow requires you to define each recipient role upfront when you create the template. All defined roles must be filled when you create an envelope. If you define five signer roles in your template but only have three people who need to sign, the envelope creation will fail.

You’re stuck either creating multiple templates for every possible scenario (which quickly becomes unmanageable) or finding a better approach. The solution? Composite templates.

What Are Composite Templates?

Composite templates let you dynamically construct envelopes by combining a server-side template (your pre-configured document stored in DocuSign) with an inline template (dynamically generated recipient and tab data) at the moment you create an envelope.

The key advantage is flexibility. You can have one base document but create infinitely varied signing experiences based on runtime data.

Here’s how it works for our lease signing use case:

1. We create a server template in DocuSign that contains our base lease document PDF
2. At runtime, when we know exactly who needs to sign (after someone submits their lease application), we generate an inline template with the specific signers and their tabs
3. We combine both into a composite template in our API request to DocuSign

This means we can maintain one lease document, but dynamically add as many signers as needed—whether it’s one primary applicant or a primary plus nine co-applicants.

The Anchor Problem

Here’s where things get tricky, and where many developers run into a wall.

Normally, when creating a DocuSign template through the web UI, you’d drag and drop signature fields, date fields, text fields, and other tabs onto your document. This works great for static templates. But the web UI has a fundamental limitation: it forces you to define all recipient roles upfront and assign specific tabs to specific roles.

Since we don’t know how many signers we’ll have until runtime, we can’t use the web UI to place tabs. If we knew we’d always have exactly three tenants, we could define “Tenant 1,” “Tenant 2,” and “Tenant 3” roles in the UI. But we need to handle one tenant just as easily as ten tenants.

The solution is to use anchor strings instead of absolute positioning.

What Are Anchor Strings?

Anchor strings are pieces of text embedded directly in your PDF that DocuSign searches for when placing tabs. When DocuSign encounters an anchor string during envelope creation, it places the corresponding tab at that location (with configurable offset adjustments).

This approach shifts tab placement from the DocuSign UI into the PDF document itself. Instead of clicking in the web UI to say “put a signature field here,” you add invisible text to your PDF that says “tenantSignature1” and then tell DocuSign via the API: “When you see ‘tenantSignature1,’ place a signature tab there.”

With this approach you can embed as many anchor strings as you might ever need (tenant1 through tenant10) in your PDF. Then at runtime, you only reference the ones you actually need for that envelope. If you only have two tenants, you only create tabs for tenantSignature1 and tenantSignature2. The unused anchors (tenantSignature3 through tenantSignature10) just sit there harmlessly in the document, never referenced.

How to Set Up Anchor Strings

Setting up anchor strings requires some initial investment in your PDF, but it pays off with complete flexibility. Here’s the process:

1. Use Adobe Acrobat (or a similar PDF editor) to add your anchor strings directly to the lease PDF.

Place them exactly where you want the corresponding tab to appear.

2. Make them invisible.

Use white text in a small font size so they don’t show up when the document is viewed or printed. The anchor strings are there for DocuSign to find programmatically—they’re not meant for human eyes.

3. Make them unique.

Each anchor string should be unique within your document so DocuSign can find the exact location you intend. If you accidentally duplicate an anchor string, DocuSign will find the first occurrence, which might not be where you want it.

4. Use a consistent naming convention.

We use patterns like tenant{Type}{Number} (e.g., tenantSignature1, tenantInitials1, tenantDate1) and leasingAgent{Type} (e.g., leasingAgentSignature, leasingAgentInitials). This makes it easy to generate anchor strings programmatically in your code.

5. Test your offsets.

This is the painful part. Different tab types (signature, initial, date, text) position differently relative to the anchor. The anchor is just a reference point—you then specify X and Y offsets in pixels to fine-tune where the tab actually appears. A signature tab might need anchorXOffset: “-8” and anchorYOffset: “6” to line up properly, while a date tab might need anchorYOffset: “-1”. You’ll need to test each type and tweak the offsets until they line up with your document’s layout.

For example, in our lease documents, we use anchor strings like:

  • tenantSignature1, tenantSignature2, tenantSignature3, etc. for each tenant’s signature field
  • tenantInitials1, tenantInitials2, etc. for tenant initial fields
  • tenantDate1, tenantDate2, etc. for signature date fields
  • tenantName1, tenantName2, etc. for printed name fields
  • leasingAgentSignature, leasingAgentInitials for the property manager’s signing fields

We pre-place up to 10 sets of these anchors in our PDF (since we cap lease signers at 10). For each envelope, we only create tabs for the number of actual signers.

Building the Request

Now for the code. Here’s a simplified example of what a composite template request looks like, focusing on the signer-specific parts:


{
  "emailSubject": "Please Sign Your Lease Document",
  "status": "created",
  "compositeTemplates": [
    {
      "serverTemplates": [
        {
          "sequence": "1",
          "templateId": "your-template-id-here"
        }
      ],
      "inlineTemplates": [
        {
          "sequence": "2",
          "recipients": {
            "signers": [
              {
                "roleName": "primaryApplicant",
                "name": "Silly Billy",
                "email": "[email protected]",
                "routingOrder": "1",
                "recipientId": "1",
                "tabs": {
                  "signHereTabs": [
                    {
                      "anchorString": "tenantSignature1",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "6"
                    }
                  ],
                  "initialHereTabs": [
                    {
                      "anchorString": "tenantInitials1",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "6"
                    }
                  ],
                  "dateSignedTabs": [
                    {
                      "anchorString": "tenantDate1",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "-1"
                    }
                  ]
                }
              },
              {
                "roleName": "coApplicant",
                "name": "Serious Merious",
                "email": "[email protected]",
                "routingOrder": "1",
                "recipientId": "2",
                "tabs": {
                  "signHereTabs": [
                    {
                      "anchorString": "tenantSignature2",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "6"
                    }
                  ],
                  "initialHereTabs": [
                    {
                      "anchorString": "tenantInitials2",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "6"
                    }
                  ],
                  "dateSignedTabs": [
                    {
                      "anchorString": "tenantDate2",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "-1"
                    }
                  ]
                }
              },
              {
                "roleName": "leasingAgent",
                "name": "Property Manager",
                "email": "[email protected]",
                "routingOrder": "2",
                "recipientId": "3",
                "tabs": {
                  "signHereTabs": [
                    {
                      "anchorString": "leasingAgentSignature",
                      "anchorMatchWholeWord": "true",
                      "anchorUnits": "pixels",
                      "anchorXOffset": "-8",
                      "anchorYOffset": "6"
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

Breaking Down the Request Structure

 

Server Template (sequence “1”)

This references your pre-uploaded PDF document in DocuSign. You create this once through the DocuSign web UI or API, upload your PDF with embedded anchor strings, and get back a templateId. That’s all you need—just the ID to reference it in future envelope creation requests.

Note: Docusign will try and create a blank role for you to use when you upload a new PDF. Make sure to delete this before saving and closing your template, or you will get errors that you’re missing a signer when you try and send your envelope.

Inline Template (sequence “2”)

This is where you dynamically define your recipients. In this example, we’re adding two tenants and one leasing agent, but you could add ten tenants just as easily by including more signer objects in the array.

Notice several key points:

  •  Each signer has a unique recipientId: DocuSign uses this to track each recipient. We use “1”, “2”, “3”, etc.
  •  Each signer references different anchor strings: The first tenant uses tenantSignature1, tenantInitials1, tenantDate1. The second tenant uses tenantSignature2, tenantInitials2, tenantDate2. This is how we connect each signer to their specific fields in the PDF.
  •  The routingOrder controls signing sequence: All tenants have routingOrder “1” (they can all sign in parallel), while the leasing agent has routingOrder “2” (they sign after all tenants complete). DocuSign won’t send the envelope to recipients in a later routing order until all recipients in earlier routing orders have completed their actions.
  •  You can add as many signers as needed: Just keep adding objects to the signers array. Each needs a unique recipientId and should reference the corresponding numbered anchor strings.
  •  The roleName field is arbitrary: Unlike when using server-side roles, in inline templates the roleName is just a label. Make it descriptive for your own reference.

Anchor Configuration Properties

When defining tabs that use anchors, pay attention to these properties:

  • anchorString: The exact text DocuSign should search for in your PDF. Must match what you embedded in the document.
  • anchorMatchWholeWord: Set to “true” to avoid partial matches. If you have both “signature” and “signature1” as anchors, you want DocuSign to distinguish between them.
  • anchorUnits: Use “pixels” for precise positioning. You could also use “mms” or “cms”, but pixels gives you the most control.
  •  anchorXOffset and anchorYOffset: The pixel offsets from the anchor location where the tab should actually appear. These will require trial and error. Start with our values (-8 for X, 6 for signatures/initials, -1 for dates) and adjust based on your PDF layout.
  • anchorIgnoreIfNotPresent: Set to “false” if the field is required—DocuSign will throw an error if it can’t find the anchor. Set to “true” if the field is optional—DocuSign will silently skip it if the anchor doesn’t exist. This is useful when you have sections of your document that might not apply to all signers.
  • anchorCaseSensitive: We set this to “true” to ensure exact matches. Without it, DocuSign might match “tenantsignature1” when you meant “tenantSignature1”.

Implementation Tips and Gotchas

Based on our experience building this system and seeing discussions in the DocuSign community forums and Stack Overflow, here are some practical tips:

1. Test with Postman first.

Before building this into your application, test your requests manually with Postman or a similar API client. Create a few test envelopes with different numbers of signers. Check that all the tabs appear in the right places. It’s much faster to iterate on anchor positioning and offset values this way than to rebuild and redeploy your application code for each test.

2. Anchor offset is painful.

Different tab types need different offsets, and there’s no formula—you just have to test. Signature tabs might need an anchorYOffset of “6”, while date tabs might need “-1”, and text tabs might need something else entirely. The tab’s registration point (the point that aligns with the offset coordinates) varies by tab type. Budget time for this fiddly work.

Also, if you ever change your PDF layout or fonts, you’ll likely need to re-test and adjust your offsets.

3. Set a reasonable maximum.

We cap our lease signers at 10. More than that, and the PDF becomes unwieldy, plus it’s an edge case we never encounter in practice. Setting a maximum lets you pre-place that many anchor sets in your PDF and move on. You don’t need to handle infinite signers—just enough to cover your realistic scenarios with some headroom.

4. Use shared tabs for common data.

If you have fields that should display the same value for all recipients (like lease start date, monthly rent, property address), mark them as shared. Set shared: “true” and locked: “true”, assign the tab to one recipient (typically the leasing agent in our case), and that field will be prepopulated and appear for everyone. This prevents you from having to define the same data multiple times and ensures consistency.

5. Status: “created” vs. “sent”.

Notice in our example we use “status”: “created”. This creates the envelope but doesn’t send it yet. This is useful if you want to verify the envelope looks correct before sending, or if you’re using embedded signing (where users sign in your app, not via email). Once you’re ready, you can update the envelope status to “sent” with a separate API call. Alternatively, set “status”: “sent” in your initial request to create and send in one step.

Wrapping Up

Composite templates combined with anchor strings solve the variable signer problem. The setup requires editing your PDF with anchor strings and tweaking offset values, but once configured, you can dynamically generate envelopes for any number of participants via the API.

I hope this guide saves you some time if you’re tackling a similar integration.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *