> You are reading the Docusign Developer Documentation. For clean Markdown of any page, append .md to the page URL.
>
> Documentation indexes by section:
> - APIs and SDKs: https://docusign.docs.buildwithfern.com/docs/llms.txt
> - Platform 101: https://docusign.docs.buildwithfern.com/platform/llms.txt
> - Extension Apps: https://docusign.docs.buildwithfern.com/extension-apps/llms.txt
> - Docusign CLI: https://docusign.docs.buildwithfern.com/docusign-cli/llms.txt
>
> Authentication (OAuth, JWT Grant, M2M): https://docusign.docs.buildwithfern.com/platform/auth
> Webhooks and Connect: https://docusign.docs.buildwithfern.com/platform/webhooks
>
> OpenAPI specifications: https://docusign.docs.buildwithfern.com/openapi.json
> MCP server: https://docusign.docs.buildwithfern.com/_mcp/server

# How to send an envelope with merge fields

> Learn how to use merge fields in your envelopes sent with the Apex Toolkit.

This topic demonstrates how to send an envelope with [merge fields](https://support.docusign.com/s/document-item?language=en_US\&bundleId=evk1581360654067\&topicId=ipy1581360621906.html&_LANG=enus) using the Apex Toolkit. Merge fields are Docusign tabs that are tied to [Salesforce objects](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_concepts.htm). Merge fields pull their values from the data stored in a Salesforce object. This topic also demonstrates how to use merge fields with the writeback option enabled, which allows the merge field to update the data in the associated Salesforce record when a recipient edits the information in the merge field.

## Prerequisites

1. Install the [Docusign eSignature for Salesforce](/docs/salesforce/how-to/apex-toolkit-install)  managed package.
2. Create a subdomain for your Salesforce organization by enabling "My Domain."
3. Select the **Docusign Setup** tab and complete the login step.
4. Create an [Opportunity](https://developer.salesforce.com/docs/atlas.en-us.sfFieldRef.meta/sfFieldRef/salesforce_field_reference_Opportunity.htm) object in your Salesforce org. The code in this how-to will create a merge field that pulls data from this opportunity and allows writeback to it.
5. Upload a document to a Salesforce library by going to **App Launcher > Sales Console > Files** and selecting **Upload Files**.
6. To use merge fields in a production Salesforce org, Docusign Connect must be enabled for your account.

## Required data

Running the code in this how-to requires this data:

| Data element         | Description                                                                                                                                                                                                              |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Content Document ID  | The ID of a document stored in a Salesforce library.                                                                                                                                                                     |
| Contact ID           | The ID of the Salesforce Contact that will receive the envelope.                                                                                                                                                         |
| Salesforce source ID | The Salesforce ID of the object from which the Docusign envelopes will be sent. For this example, this value should be the ID of the opportunity that will provide the data for the merge field defined in the envelope. |

## Step 1. Define your public class and method

Create the class and method that will contain the code in this example. You can skip this step if you are adding this code to an existing class.

**`Apex`**

```java title="Apex"
public with sharing class CreateMergeFieldInEnvelope {

    @AuraEnabled
    public static void sendEnvelope() {
    }
}
```

## Step 2. Create an envelope with a document

First use the [dfsle.EnvelopeService.getEmptyEnvelope](/docs/salesforce/apex-toolkit-reference/envelopeservice.html)  method to create an empty envelope object using the ID of your opportunity as the source ID. Use the [dfsle.Envelope.withDocuments](/docs/salesforce/apex-toolkit-reference/envelope.html)  method to add the document to the envelope.

**`Apex`**

```java title="Apex"
Id mySourceId = '00XXXXXXXXXXXXXXAM'; // The ID of the initiating Salesforce Opportunity

// Create an empty envelope
dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
new dfsle.Entity(mySourceId));
// The initiating Salesforce entity

// Add document to the envelope
Id myDocumentId = '00XXXXXXXXXXXXXXA4'; // The ID of a document stored in a Salesforce library
Id myFileId = [SELECT id from ContentVersion where ContentDocumentId = :myDocumentId LIMIT 1].id;
myEnvelope = myEnvelope.withDocuments(dfsle.DocumentService.getDocuments(ContentVersion.getSObjectType(), new Set<Id> { myFileId }));
```

## Step 3. Define a merge field and text tab

Create a new [dfsle.Tab.MergeField](/docs/salesforce/apex-toolkit-reference/tab.html) object. Set the path parameter to 'opportunity.name' to indicate that the merge field’s value will be populated by the name field of the opportunity object. The true parameter in the accompanying code allows writeback to the opportunity object, meaning that the opportunity record in Salesforce will be updated to reflect any changes to the text in the tab. The false parameter states that the tab is not read-only for the sender of the envelope.

After you have created the MergeField object, create a new dfsle.TextTab object. Pass the merge field that you created previously as a parameter to the [dfsle.ReadWriteTab.withMergeField](/docs/salesforce/apex-toolkit-reference/readwritetab.html) method on the text tab. Ensure the tab is editable by the recipient with the withReadOnly method. Use the withPosition method to place the tab in the document at a location defined by *x* and *y* coordinates.

**`Apex`**

```java title="Apex"
//Define a merge field
//This field will be associated with the initiating source object represented by mySourceId
		dfsle.Tab.MergeField myMergeField = new dfsle.Tab.MergeField (
    'opportunity.name', //The data that this merge field will pull its value from
    null, //N/A
    null, //N/A
    true, //Allows writeback to the Salesforce object
    false //Whether or not the field is read only for the sender
);

		//Create a text tab that will be mapped to the merge field
		dfsle.Tab myTextTab = new dfsle.TextTab()
 .withMergeField(myMergeField) //Associate this tab with the mergeField
    		.withReadOnly(false) //true = read only or locked
    		.withPosition(new dfsle.Tab.Position(1, 1, 200, 300, null, null))
    		.withDataLabel('Contact Name');
```

## Step 4. Create a recipient and add it to the envelope

Make a  [SOQL](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm) query to get a Contact object from a Contact ID. Then use the [dfsle.Recipient.fromSource](/docs/salesforce/apex-toolkit-reference/recipient.html)  method to create a recipient using the contact’s name and email. Use the [dfsle.Recipient.withTabs](/docs/salesforce/apex-toolkit-reference/recipient.html) method to assign your text tab from the previous step to the recipient.

**`Apex`**

```java title="Apex"
// Create a new recipient
Id myContactId = '00XXXXXXXXXXXXXXA4';
Contact myContact = [SELECT Id, Name, Email FROM Contact WHERE Id = :myContactId];

dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
    myContact.Name, // Signer name
    myContact.Email, // Signer email
    null, // Signer phone number
    null, // Template role n/a
    null) // No Salesforce association
    .withTabs(new List<dfsle.Tab> { // Associate the tabs with this recipient
        myTextTab
    });

// Add recipient to the envelope
myEnvelope = myEnvelope.withRecipients(new List<dfsle.Recipient> { myRecipient });
```

## Step 5. Send the envelope

Send the envelope using the [dfsle.EnvelopeService.sendEnvelope](/docs/salesforce/apex-toolkit-reference/envelopeservice.html)  method. The sendNow parameter is set to true to indicate that you want to send the envelope immediately. Setting the sendNow parameter to false will save the envelope as a draft. The Apex Toolkit does not support sending a draft envelope. To send a draft envelope, you will need to call the [eSignature REST API](/docs/esign-rest-api) outside of the Apex Toolkit.

**`Apex`**

```java title="Apex"
// Send the envelope
myEnvelope = dfsle.EnvelopeService.sendEnvelope(
    myEnvelope, // The envelope to send
    true); // Send now?
```

## Step 6. Execute your method

To execute your code, go to the [Developer Console](https://help.salesforce.com/s/articleView?language=en_US\&id=sf.code_dev_console.htm\&type=5) in Salesforce, open the **Debug** menu, then select **Open Execute Anonymous Window**. Type the accompanying code in the window and select **Execute**.

If you skipped Step 1 and added your code to an existing class or method, you'll need to replace the class and method names with your own.

> **Note**
>
> View the source code for this how-to on GitHub: [Apex](https://github.com/docusign/code-examples-apex/blob/master/force-app/main/default/classes/CreateMergeFieldInEnvelope.cls)

**`Apex`**

```java title="Apex"
CreateMergeFieldInEnvelope.sendEnvelope();
```

## Expected results

If your API call is successful, an envelope will be sent to the email of the Salesforce contact that was used to create your recipient. When the recipient opens the envelope, they will see a tab containing the name of the opportunity that was used to create the merge field. If the recipient edits the text in the tab, the opportunity name in your Salesforce org will be updated accordingly.

## Next steps

* See all available Apex Toolkit [How-to guides](/docs/salesforce/how-to).
* Learn [How to send an envelope with tabs](/docs/salesforce/how-to/send-envelope-with-tabs).
* See [How to perform unit testing](/docs/salesforce/how-to/unit-testing) to ensure that you have adequate code coverage.