> 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 request a signature by email

> This topic demonstrates how to use the eSignature REST API and SDKs to send a signature request for a signer to read and sign via an email, also known as a remote signing.

This topic demonstrates how to send a signature request via an email, also known as a *remote signature request* or *remote signing*. The email will contain a signing link that the recipient can use to open and electronically sign a document using the Docusign mobile app or the Docusign website. After signing is complete, the recipient receives a carbon copy (CC) of the email that includes all of the completed and signed documents.

This example scenario also demonstrates how to:

1. Use [anchor tabs](/docs/esign-rest-api/esign101/concepts/tabs/auto-place) to automatically position tabs in documents at instances of a specified string.
2. Include signing documents in several formats (a customized HTML file, a [DOCX file](https://github.com/docusign/code-examples-java/blob/master/src/main/resources/World_Wide_Corp_Battle_Plan_Trafalgar.docx), and a [PDF file](https://github.com/docusign/code-examples-java/blob/master/src/main/resources/World_Wide_Corp_lorem.pdf) in the envelope).

> **Note**
>
> Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects: [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).

## Required data

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

| Data element           | Description                                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \{API_ACCOUNT_ID}      | A [GUID](http://guid.one/) value that identifies your account. This value is automatically generated by Docusign for any account you create. Copy the value from the **API Account ID** field on the [Apps and Keys](https://admindemo.docusign.com/authenticate?goTo=appsAndKeys) page.                                                                                                                                  |
| \{BASE_PATH}           | A string value that forms the root of the URL required to make API calls. The base path value in the example code is set to target the developer environment at https\://\<domain>/restapi Where \<domain> is demo.docusign.net for the developer environment and is the result of the GetUserInfo call in production.                                                                                                    |
| Documents to be signed | You must provide at least one document to be signed. Documents used in this how-to:- [DOCX file](https://github.com/docusign/code-examples-java/blob/master/src/main/resources/World_Wide_Corp_Battle_Plan_Trafalgar.docx)
- [PDF file](https://github.com/docusign/code-examples-java/blob/master/src/main/resources/World_Wide_Corp_lorem.pdf)
- A third document in HTML is constructed dynamically by the sample code |
| \{SIGNER_EMAIL}        | A string value for the email address where the signer will receive a notification of the signing request.                                                                                                                                                                                                                                                                                                                 |
| \{SIGNER_NAME}         | A string value for the full name of the signer.                                                                                                                                                                                                                                                                                                                                                                           |

## Step 1. Obtain your OAuth token

To make the API call shown in this how-to, you need a valid OAuth access token. Docusign supports access tokens for three different recommended OAuth grant types: Public Authorization Code Grant, Confidential Authorization Code Grant, and JSON Web Token (JWT) Grant. Choose the OAuth grant type appropriate for your scenario.

> **Note**
>
> See [Confidential Authorization Code Grant](/platform/auth/authcode#confidential-authorization-code-grant) for guidance on your options to get an Confidential Authorization Code Grant  OAuth token.

![Three icons that represent the three methods a user can use to obtain an OAuth token: JSON Web Token (JWT), Public Authorization Code Grant (ACG), and Confidential Authorization Code grant](/_fern-files/_img/64f473773042ee439449a096bf7673292b1585b86a4ccc55f82ba0dda41f61a1.webp)

## Step 2. Create the envelope definition

The first step in requesting a signature by email is to create a new envelope definition. This topic shows how to create an individual envelope by defining a method named `makeEnvelope` that creates the envelope definition. The `makeEnvelope` method demonstrates how to:

* Create a new, signable HTML document in code.
* Attach multiple documents to the envelope.
* Set signer and CC recipient data.
* Create a routing order for the documents.
* Create and assign signable fields to specific signers within the documents.

Define the `makeEnvelope` method with this code.

**`Bash`**

```bash title="Bash"
printf \
'{
    "emailSubject": "Please sign this document set",
    "documents": [
        {
            "documentBase64": "' > $request_data
            cat $doc1_base64 >> $request_data
            printf '",
            "name": "Order acknowledgement",
            "fileExtension": "html",
            "documentId": "1"
        },
        {
            "documentBase64": "' >> $request_data
            cat $doc2_base64 >> $request_data
            printf '",
            "name": "Battle Plan",
            "fileExtension": "docx",
            "documentId": "2"
        },
        {
            "documentBase64": "' >> $request_data
            cat $doc3_base64 >> $request_data
            printf '",
            "name": "Lorem Ipsum",
            "fileExtension": "pdf",
            "documentId": "3"
        }
    ],
    "recipients": {
        "carbonCopies": [
            {
                "email": "'"${CC_EMAIL}"'",
                "name": "'"${CC_NAME}"'",
                "recipientId": "2",
                "routingOrder": "2"
            }
        ],
        "signers": [
            {
                "email": "'"${SIGNER_EMAIL}"'",
                "name": "'"${SIGNER_NAME}"'",
                "recipientId": "1",
                "routingOrder": "1",
                "tabs": {
                    "signHereTabs": [
                        {
                            "anchorString": "**signature_1**",
                            "anchorUnits": "pixels",
                            "anchorXOffset": "20",
                            "anchorYOffset": "10"
                        },
                        {
                            "anchorString": "/sn1/",
                            "anchorUnits": "pixels",
                            "anchorXOffset": "20",
                            "anchorYOffset": "10"
                        }
                    ]
                }
            }
        ]
    },
    "status": "sent"
}' >> $request_data
```

**`C#`**

```csharp title="C#"
EnvelopeDefinition env = new EnvelopeDefinition();
env.EmailSubject = "Please sign this document set";

// Create document objects, one per document
Document doc1 = new Document();
string b64 = Convert.ToBase64String(Document1(signerEmail, signerName, ccEmail, ccName));
doc1.DocumentBase64 = b64;
doc1.Name = "Order acknowledgement"; // can be different from actual file name
doc1.FileExtension = "html"; // Source data format. Signed docs are always pdf.
doc1.DocumentId = "1"; // a label used to reference the doc
Document doc2 = new Document
{
    DocumentBase64 = doc2DocxBytes,
    Name = "Battle Plan", // can be different from actual file name
    FileExtension = "docx",
    DocumentId = "2",
};
Document doc3 = new Document
{
    DocumentBase64 = doc3PdfBytes,
    Name = "Lorem Ipsum", // can be different from actual file name
    FileExtension = "pdf",
    DocumentId = "3",
};

// The order in the docs array determines the order in the envelope
env.Documents = new List<Document> { doc1, doc2, doc3 };

// create a signer recipient to sign the document, identified by name and email
// We're setting the parameters via the object creation
Signer signer1 = new Signer
{
    Email = signerEmail,
    Name = signerName,
    RecipientId = "1",
    RoutingOrder = "1",
};

// routingOrder (lower means earlier) determines the order of deliveries
// to the recipients. Parallel routing order is supported by using the
// same integer as the order for two or more recipients.

// create a cc recipient to receive a copy of the documents, identified by name and email
// We're setting the parameters via setters
CarbonCopy cc1 = new CarbonCopy
{
    Email = ccEmail,
    Name = ccName,
    RecipientId = "2",
    RoutingOrder = "2",
};

// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
//
// The DocuSign platform searches throughout your envelope's
// documents for matching anchor strings. So the
// signHere2 tab will be used in both document 2 and 3 since they
// use the same anchor string for their "signer 1" tabs.
SignHere signHere1 = new SignHere
{
    AnchorString = "**signature_1**",
    AnchorUnits = "pixels",
    AnchorYOffset = "10",
    AnchorXOffset = "20",
};

SignHere signHere2 = new SignHere
{
    AnchorString = "/sn1/",
    AnchorUnits = "pixels",
    AnchorYOffset = "10",
    AnchorXOffset = "20",
};

// Tabs are set per recipient / signer
Tabs signer1Tabs = new Tabs
{
    SignHereTabs = new List<SignHere> { signHere1, signHere2 },
};
signer1.Tabs = signer1Tabs;

// Add the recipients to the envelope object
Recipients recipients = new Recipients
{
    Signers = new List<Signer> { signer1 },
    CarbonCopies = new List<CarbonCopy> { cc1 },
};
env.Recipients = recipients;

// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
env.Status = envStatus;

return env;
```

**`Java`**

```java title="Java"
	public static EnvelopeDefinition makeEnvelope(
			String signerEmail,
			String signerName,
			String ccEmail,
			String ccName,
			String status,
			WorkArguments args) throws IOException {
		// The DocuSign platform searches throughout your envelope's documents
		// for matching anchor strings. So the signHere2 tab will be used in
		// both document 2 and 3 since they use the same anchor string for
		// their "signer 1" tabs.
		Tabs signerTabs = EnvelopeHelpers.createSignerTabs(
				EnvelopeHelpers.createSignHere("**signature_1**", ANCHOR_OFFSET_Y, ANCHOR_OFFSET_X),
				EnvelopeHelpers.createSignHere("/sn1/", ANCHOR_OFFSET_Y, ANCHOR_OFFSET_X));

		// Create a signer recipient to sign the document, identified by name
		// and email. We're setting the parameters via the object creation.
		// RoutingOrder (lower means earlier) determines the order of deliveries
		// to the recipients. Parallel routing order is supported by using the
		// same integer as the order for two or more recipients.
		Signer signer = new Signer();
		signer.setEmail(signerEmail);
		signer.setName(signerName);
		signer.setRecipientId("1");
		signer.setRoutingOrder("1");
		signer.setTabs(signerTabs);

		// create a cc recipient to receive a copy of the documents, identified by name
		// and email
		CarbonCopy cc = new CarbonCopy();
		cc.setEmail(ccEmail);
		cc.setName(ccName);
		cc.setRecipientId("2");
		cc.setRoutingOrder("2");

		// The order in the docs array determines the order in the envelope
		byte[] htmlDocument = EnvelopeHelpers.createHtmlFromTemplateFile(HTML_DOCUMENT_FILE_NAME, "args", args)
				.getBytes(StandardCharsets.UTF_8);
		EnvelopeDefinition envelope = new EnvelopeDefinition();
		envelope.setEmailSubject("Please sign this document set");
		envelope.setDocuments(Arrays.asList(
				EnvelopeHelpers.createDocument(htmlDocument, HTML_DOCUMENT_NAME,
						DocumentType.HTML.getDefaultFileExtention(), "1"),
				EnvelopeHelpers.createDocumentFromFile(DOCX_DOCUMENT_FILE_NAME, DOCX_DOCUMENT_NAME,
						"2"),
				EnvelopeHelpers.createDocumentFromFile(PDF_DOCUMENT_FILE_NAME, PDF_DOCUMENT_NAME,
						"3")));
		envelope.setRecipients(EnvelopeHelpers.createRecipients(signer, cc));
		// Request that the envelope be sent by setting |status| to "sent".
		// To request that the envelope be created as a draft, set to "created"
		envelope.setStatus(status);

		return envelope;
	}
```

**`Node.js`**

```javascript title="Node.js"
function makeEnvelope(args) {
  // Data for this method
  // args.signerEmail
  // args.signerName
  // args.ccEmail
  // args.ccName
  // args.status
  // doc2File
  // doc3File

  // document 1 (html) has tag **signature_1**
  // document 2 (docx) has tag /sn1/
  // document 3 (pdf) has tag /sn1/
  //
  // The envelope has two recipients.
  // recipient 1 - signer
  // recipient 2 - cc
  // The envelope will be sent first to the signer.
  // After it is signed, a copy is sent to the cc person.

  let doc2DocxBytes, doc3PdfBytes;
  // read files from a local directory
  // The reads could raise an exception if the file is not available!
  doc2DocxBytes = fs.readFileSync(args.doc2File);
  doc3PdfBytes = fs.readFileSync(args.doc3File);

  // create the envelope definition
  let env = new docusign.EnvelopeDefinition();
  env.emailSubject = 'Please sign this document set';

  // add the documents
  let doc1 = new docusign.Document();
    let doc1b64 = Buffer.from(document1(args)).toString('base64');
    let doc2b64 = Buffer.from(doc2DocxBytes).toString('base64');
    let doc3b64 = Buffer.from(doc3PdfBytes).toString('base64');
  doc1.documentBase64 = doc1b64;
  doc1.name = 'Order acknowledgement'; // can be different from actual file name
  doc1.fileExtension = 'html'; // Source data format. Signed docs are always pdf.
  doc1.documentId = '1'; // a label used to reference the doc

  // Alternate pattern: using constructors for docs 2 and 3...
  let doc2 = new docusign.Document.constructFromObject({
    documentBase64: doc2b64,
    name: 'Battle Plan', // can be different from actual file name
    fileExtension: 'docx',
    documentId: '2',
  });

  let doc3 = new docusign.Document.constructFromObject({
    documentBase64: doc3b64,
    name: 'Lorem Ipsum', // can be different from actual file name
    fileExtension: 'pdf',
    documentId: '3',
  });

  // The order in the docs array determines the order in the envelope
  env.documents = [doc1, doc2, doc3];

  // create a signer recipient to sign the document, identified by name and email
  // We're setting the parameters via the object constructor
  let signer1 = docusign.Signer.constructFromObject({
    email: args.signerEmail,
    name: args.signerName,
    recipientId: '1',
    routingOrder: '1',
  });
  // routingOrder (lower means earlier) determines the order of deliveries
  // to the recipients. Parallel routing order is supported by using the
  // same integer as the order for two or more recipients.

  // create a cc recipient to receive a copy of the documents, identified by name and email
  // We're setting the parameters via setters
  let cc1 = new docusign.CarbonCopy();
  cc1.email = args.ccEmail;
  cc1.name = args.ccName;
  cc1.routingOrder = '2';
  cc1.recipientId = '2';

  // Create signHere fields (also known as tabs) on the documents,
  // We're using anchor (autoPlace) positioning
  //
  // The DocuSign platform searches throughout your envelope's
  // documents for matching anchor strings. So the
  // signHere2 tab will be used in both document 2 and 3 since they
  // use the same anchor string for their "signer 1" tabs.
  let signHere1 = docusign.SignHere.constructFromObject({
      anchorString: '**signature_1**',
      anchorYOffset: '10',
      anchorUnits: 'pixels',
      anchorXOffset: '20',
    });
    let signHere2 = docusign.SignHere.constructFromObject({
      anchorString: '/sn1/',
      anchorYOffset: '10',
      anchorUnits: 'pixels',
      anchorXOffset: '20',
    });
  // Tabs are set per recipient / signer
  let signer1Tabs = docusign.Tabs.constructFromObject({
    signHereTabs: [signHere1, signHere2],
  });
  signer1.tabs = signer1Tabs;

  // Add the recipients to the envelope object
  let recipients = docusign.Recipients.constructFromObject({
    signers: [signer1],
    carbonCopies: [cc1],
  });
  env.recipients = recipients;

  // Request that the envelope be sent by setting |status| to "sent".
  // To request that the envelope be created as a draft, set to "created"
  env.status = args.status;

  return env;
}

/**
 * Creates document 1
 * @function
 * @private
 * @param {Object} args parameters for the envelope
 * @returns {string} A document in HTML format
 */

function document1(args) {
  // Data for this method
  // args.signerEmail
  // args.signerName
  // args.ccEmail
  // args.ccName

  return `
    <!DOCTYPE html>
    <html>
        <head>
          <meta charset="UTF-8">
        </head>
        <body style="font-family:sans-serif;margin-left:2em;">
        <h1 style="font-family: 'Trebuchet MS', Helvetica, sans-serif;
            color: darkblue;margin-bottom: 0;">World Wide Corp</h1>
        <h2 style="font-family: 'Trebuchet MS', Helvetica, sans-serif;
          margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
          color: darkblue;">Order Processing Division</h2>
        <h4>Ordered by ${args.signerName}</h4>
        <p style="margin-top:0em; margin-bottom:0em;">Email: ${args.signerEmail}</p>
        <p style="margin-top:0em; margin-bottom:0em;">Copy to: ${args.ccName}, ${args.ccEmail}</p>
        <p style="margin-top:3em;">
  Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
        </p>
        <!-- Note the anchor tag for the signature field is in white. -->
        <h3 style="margin-top:3em;">Agreed: <span style="color:white;">**signature_1**/</span></h3>
        </body>
    </html>
  `;
}
```

**`PHP`**

```php title="PHP"
public static function makeEnvelope(array $args, $clientService, $demoDocsPath, $docxFile, $pdfFile): EnvelopeDefinition
{
    # document 1 (html) has sign here anchor tag **signature_1**
    # document 2 (docx) has sign here anchor tag /sn1/
    # document 3 (pdf)  has sign here anchor tag /sn1/
    #
    # The envelope has two recipients.
    # recipient 1 - signer
    # recipient 2 - cc
    # The envelope will be sent first to the signer.
    # After it is signed, a copy is sent to the cc person.
    #
    # create the envelope definition
    $envelope_definition = new EnvelopeDefinition([
      'email_subject' => 'Please sign this document set'
    ]);
    $doc1_b64 = base64_encode($clientService->createDocumentForEnvelope($args));
    # read files 2 and 3 from a local directory
    # The reads could raise an exception if the file is not available!
    $content_bytes = file_get_contents($demoDocsPath . $docxFile);
    $doc2_b64 = base64_encode($content_bytes);
    $content_bytes = file_get_contents($demoDocsPath . $pdfFile);
    $doc3_b64 = base64_encode($content_bytes);

    # Create the document models
    $document1 = new Document([  # create the DocuSign document object
       'document_base64' => $doc1_b64,
       'name' => 'Order acknowledgement',  # can be different from actual file name
       'file_extension' => 'html',  # many different document types are accepted
       'document_id' => '1'  # a label used to reference the doc
    ]);
    $document2 = new Document([  # create the DocuSign document object
       'document_base64' => $doc2_b64,
       'name' => 'Battle Plan',  # can be different from actual file name
       'file_extension' => 'docx',  # many different document types are accepted
       'document_id' => '2'  # a label used to reference the doc
    ]);
    $document3 = new Document([  # create the DocuSign document object
       'document_base64' => $doc3_b64,
       'name' => 'Lorem Ipsum',  # can be different from actual file name
       'file_extension' => 'pdf',  # many different document types are accepted
       'document_id' => '3'  # a label used to reference the doc
    ]);
    # The order in the docs array determines the order in the envelope
    $envelope_definition->setDocuments([$document1, $document2, $document3]);

    # Create the signer recipient model
    $signer1 = new Signer([
       'email' => $args['signer_email'], 'name' => $args['signer_name'],
       'recipient_id' => "1", 'routing_order' => "1"]);
    # routingOrder (lower means earlier) determines the order of deliveries
    # to the recipients. Parallel routing order is supported by using the
    # same integer as the order for two or more recipients.

    # create a cc recipient to receive a copy of the documents
    $cc1 = new CarbonCopy([
       'email' => $args['cc_email'], 'name' => $args['cc_name'],
       'recipient_id' => "2", 'routing_order' => "2"]);

    return SMSDeliveryService::addSignersToTheDelivery($signer1, $cc1, $envelope_definition, $args);
}
```

**`PowerShell`**

```text title="PowerShell"
@{
    emailSubject = "Please sign this document set";
    documents    = @(
        @{
            documentBase64 = "$(Get-Content $doc1Base64)";
            name           = "Order acknowledgement";
            fileExtension  = "html";
            documentId     = "1";
        };
        @{
            documentBase64 = "$(Get-Content $doc2Base64)";
            name           = "Battle Plan";
            fileExtension  = "docx";
            documentId     = "2";
        };
        @{
            documentBase64 = "$(Get-Content $doc3Base64)";
            name           = "Lorem Ipsum";
            fileExtension  = "pdf";
            documentId     = "3";
        }; );
    recipients   = @{
        carbonCopies = @(
            @{
                email        = $variables.CC_EMAIL;
                name         = $variables.CC_NAME;
                recipientId  = "2";
                routingOrder = "2";
            };
        );
        signers      = @(
            @{
                email        = $variables.SIGNER_EMAIL;
                name         = $variables.SIGNER_NAME;
                recipientId  = "1";
                routingOrder = "1";
                tabs         = @{
                    signHereTabs = @(
                        @{
                            anchorString  = "**signature_1**";
                            anchorUnits   = "pixels";
                            anchorXOffset = "20";
                            anchorYOffset = "10";
                        };
                        @{
                            anchorString  = "/sn1/";
                            anchorUnits   = "pixels";
                            anchorXOffset = "20";
                            anchorYOffset = "10";
                        };
                    );
                };
            };
        );
    };
    status       = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
```

**`Python`**

```python title="Python"
def make_envelope(cls, args, doc_docx_path, doc_pdf_path):
    """
    Creates envelope
    Document 1: An HTML document.
    Document 2: A Word .docx document.
    Document 3: A PDF document.
    DocuSign will convert all of the documents to the PDF format.
    The recipients" field tags are placed using <b>anchor</b> strings.
    """

    # document 1 (html) has sign here anchor tag **signature_1**
    # document 2 (docx) has sign here anchor tag /sn1/
    # document 3 (pdf)  has sign here anchor tag /sn1/
    #
    # The envelope has two recipients.
    # recipient 1 - signer
    # recipient 2 - cc
    # The envelope will be sent first to the signer.
    # After it is signed, a copy is sent to the cc person.

    # create the envelope definition
    env = EnvelopeDefinition(
        email_subject="Please sign this document set"
    )
    doc1_b64 = base64.b64encode(bytes(cls.create_document1(args), "utf-8")).decode("ascii")
    # read files 2 and 3 from a local directory
    # The reads could raise an exception if the file is not available!
    with open(path.join(demo_docs_path, doc_docx_path), "rb") as file:
        doc2_docx_bytes = file.read()
    doc2_b64 = base64.b64encode(doc2_docx_bytes).decode("ascii")
    with open(path.join(demo_docs_path, doc_pdf_path), "rb") as file:
        doc3_pdf_bytes = file.read()
    doc3_b64 = base64.b64encode(doc3_pdf_bytes).decode("ascii")

    # Create the document models
    document1 = Document(  # create the DocuSign document object
        document_base64=doc1_b64,
        name="Order acknowledgement",  # can be different from actual file name
        file_extension="html",  # many different document types are accepted
        document_id="1"  # a label used to reference the doc
    )
    document2 = Document(  # create the DocuSign document object
        document_base64=doc2_b64,
        name="Battle Plan",  # can be different from actual file name
        file_extension="docx",  # many different document types are accepted
        document_id="2"  # a label used to reference the doc
    )
    document3 = Document(  # create the DocuSign document object
        document_base64=doc3_b64,
        name="Lorem Ipsum",  # can be different from actual file name
        file_extension="pdf",  # many different document types are accepted
        document_id="3"  # a label used to reference the doc
    )
    # The order in the docs array determines the order in the envelope
    env.documents = [document1, document2, document3]

    # Create the signer recipient model
    signer1 = Signer(
        email=args["signer_email"],
        name=args["signer_name"],
        recipient_id="1",
        routing_order="1"
    )
    # routingOrder (lower means earlier) determines the order of deliveries
    # to the recipients. Parallel routing order is supported by using the
    # same integer as the order for two or more recipients.

    # create a cc recipient to receive a copy of the documents
    cc1 = CarbonCopy(
        email=args["cc_email"],
        name=args["cc_name"],
        recipient_id="2",
        routing_order="2"
    )

    # Create signHere fields (also known as tabs) on the documents,
    # We"re using anchor (autoPlace) positioning
    #
    # The DocuSign platform searches throughout your envelope"s
    # documents for matching anchor strings. So the
    # signHere2 tab will be used in both document 2 and 3 since they
    # use the same anchor string for their "signer 1" tabs.
    sign_here1 = SignHere(
        anchor_string="**signature_1**",
        anchor_units="pixels",
        anchor_y_offset="10",
        anchor_x_offset="20"
    )

    sign_here2 = SignHere(
        anchor_string="/sn1/",
        anchor_units="pixels",
        anchor_y_offset="10",
        anchor_x_offset="20"
    )

    # Add the tabs model (including the sign_here tabs) to the signer
    # The Tabs object wants arrays of the different field/tab types
    signer1.tabs = Tabs(sign_here_tabs=[sign_here1, sign_here2])

    # Add the recipients to the envelope object
    recipients = Recipients(signers=[signer1], carbon_copies=[cc1])
    env.recipients = recipients

    # Request that the envelope be sent by setting |status| to "sent".
    # To request that the envelope be created as a draft, set to "created"
    env.status = args["status"]

    return env

@classmethod
def create_document1(cls, args):
    """ Creates document 1 -- an html document"""

    return f"""
    <!DOCTYPE html>
    <html>
        <head>
          <meta charset="UTF-8">
        </head>
        <body style="font-family:sans-serif;margin-left:2em;">
        <h1 style="font-family: "Trebuchet MS", Helvetica, sans-serif;
            color: darkblue;margin-bottom: 0;">World Wide Corp</h1>
        <h2 style="font-family: "Trebuchet MS", Helvetica, sans-serif;
          margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
          color: darkblue;">Order Processing Division</h2>
        <h4>Ordered by {args["signer_name"]}</h4>
        <p style="margin-top:0em; margin-bottom:0em;">Email: {args["signer_email"]}</p>
        <p style="margin-top:0em; margin-bottom:0em;">Copy to: {args["cc_name"]}, {args["cc_email"]}</p>
        <p style="margin-top:3em;">
            Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie.
            Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée.
            Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice.
            Donut jujubes oat cake jelly-o.
            Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
        </p>
        <!-- Note the anchor tag for the signature field is in white. -->
        <h3 style="margin-top:3em;">Agreed: <span style="color:white;">**signature_1**/</span></h3>
        </body>
    </html>
    """
```

**`Ruby`**

```ruby title="Ruby"
def make_envelope(envelope_args)
  # document 1 (HTML) has tag **signature_1**
  # document 2 (DOCX) has tag /sn1/
  # document 3 (PDF) has tag /sn1/
  #
  # The envelope has two recipients:
  # recipient 1 - signer
  # recipient 2 - cc
  # The envelope will be sent first to the signer.
  # After it is signed, a copy is sent to the cc person

  # Create the envelope definition
  envelope_definition = DocuSign_eSign::EnvelopeDefinition.new

  envelope_definition.email_subject = 'Please sign this document set'

  # Add the documents
  doc1_b64 = Base64.encode64(create_document1(envelope_args))
  # Read files 2 and 3 from a local directory
  # The reads could raise an exception if the file is not available!
  doc2_b64 = Base64.encode64(File.binread(envelope_args[:doc_docx]))
  doc3_b64 = Base64.encode64(File.binread(envelope_args[:doc_pdf]))

  # Create the document models
  document1 = DocuSign_eSign::Document.new(
    # Create the Docusign document object
    documentBase64: doc1_b64,
    name: 'Order acknowledgement', # Can be different from actual file name
    fileExtension: 'html', # Many different document types are accepted
    documentId: '1' # A label used to reference the doc
  )
  document2 = DocuSign_eSign::Document.new(
    # Create the Docusign document object
    documentBase64: doc2_b64,
    name: 'Battle Plan', # Can be different from actual file name
    fileExtension: 'docx', # Many different document types are accepted
    documentId: '2' # A label used to reference the do
  )
  document3 = DocuSign_eSign::Document.new(
    # Create the Docusign document object
    documentBase64: doc3_b64,
    name: 'Lorem Ipsum', # Can be different from actual file name
    fileExtension: 'pdf', # Many different document types are accepted
    documentId: '3' # A label used to reference the doc
  )

  # The order in the docs array determines the order in the envelope
  envelope_definition.documents = [document1, document2, document3]

  # Create the signer recipient model
  signer1 = DocuSign_eSign::Signer.new
  signer1.email = envelope_args[:signer_email]
  signer1.name = envelope_args[:signer_name]
  signer1.recipient_id = '1'
  signer1.routing_order = '1'
  ## routingOrder (lower means earlier) determines the order of deliveries
  # to the recipients. Parallel routing order is supported by using the
  # same integer as the order for two or more recipients

  # Create a cc recipient to receive a copy of the documents
  cc1 = DocuSign_eSign::CarbonCopy.new(
    email: envelope_args[:cc_email],
    name: envelope_args[:cc_name],
    routingOrder: '2',
    recipientId: '2'
  )
  # Create signHere fields (also known as tabs) on the documents
  # We're using anchor (autoPlace) positioning
  #
  # The Docusign platform searches throughout your envelope's documents for matching
  # anchor strings. So the sign_here_2 tab will be used in both document 2 and 3
  # since they use the same anchor string for their "signer 1" tabs.
  sign_here1 = DocuSign_eSign::SignHere.new(
    anchorString: '**signature_1**',
    anchorYOffset: '10',
    anchorUnits: 'pixels',
    anchorXOffset: '20'
  )

  sign_here2 = DocuSign_eSign::SignHere.new(
    anchorString: '/sn1/',
    anchorYOffset: '10',
    anchorUnits: 'pixels',
    anchorXOffset: '20'
  )
  # Add the tabs model (including the sign_here tabs) to the signer
  # The Tabs object takes arrays of the different field/tab types
  signer1_tabs = DocuSign_eSign::Tabs.new({
                                            signHereTabs: [sign_here1, sign_here2]
                                          })

  signer1.tabs = signer1_tabs

  # Add the recipients to the envelope object
  recipients = DocuSign_eSign::Recipients.new(
    signers: [signer1],
    carbonCopies: [cc1]
  )
  # Request that the envelope be sent by setting status to "sent".
  # To request that the envelope be created as a draft, set status to "created"
  envelope_definition.recipients = recipients
  envelope_definition.status = envelope_args[:status]
  envelope_definition
end

def create_document1(args)
  "
  <!DOCTYPE html>
  <html>
      <head>
        <meta charset=\"UTF-8\">
      </head>
      <body style=\"font-family:sans-serif;margin-left:2em;\">
      <h1 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;
color: darkblue;margin-bottom: 0;\">World Wide Corp</h1>
      <h2 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;
margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
color: darkblue;\">Order Processing Division</h2>
      <h4>Ordered by #{args[:signer_name]}</h4>
      <p style=\"margin-top:0em; margin-bottom:0em;\">Email: #{args[:signer_email]}</p>
      <p style=\"margin-top:0em; margin-bottom:0em;\">Copy to: #{args[:cc_name]}, #{args[:cc_email]}</p>
      <p style=\"margin-top:3em;\">
Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
      </p>
      <!-- Note the anchor tag for the signature field is in white. -->
      <h3 style=\"margin-top:3em;\">Agreed: <span style=\"color:white;\">**signature_1**/</span></h3>
      </body>
  </html>"
end
```

## Step 3. Create and send the envelope

Next, you use the definition of the envelope that you created in the `makeEnvelope` method in Step 2 to create a new envelope and send it, adding your access token and base path to the request header.

When the envelope is sent, the documents inside it will be delivered to the email address you specified for signing. The API returns the ID and status of the new envelope.

> **Note**
>
> View the source code for this how-to on GitHub: [Bash](https://github.com/docusign/code-examples-bash/blob/master/examples/eSignature/eg002SigningViaEmail.sh), [C#](https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Examples/SigningViaEmail.cs), [Java](https://github.com/docusign/code-examples-java/blob/master/src/main/java/com/docusign/controller/eSignature/services/SigningViaEmailService.java), [Node.js](https://github.com/docusign/code-examples-node/blob/master/lib/eSignature/examples/signingViaEmail.js), [PHP](https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/SigningViaEmailService.php), [PowerShell](https://github.com/docusign/code-examples-powershell/blob/master/examples/eSignature/eg002SigningViaEmail.ps1), [Python](https://github.com/docusign/code-examples-python/blob/master/app/eSignature/examples/eg002_signing_via_email.py), or [Ruby](https://github.com/docusign/code-examples-ruby/blob/main/app/services/e_sign/eg002_signing_via_email_service.rb).

**`Bash`**

```bash title="Bash"
curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
     --header "Content-Type: application/json" \
     --data-binary @${request_data} \
     --request POST ${base_path}/v2.1/accounts/${account_id}/envelopes \
     --output $response
```

**`C#`**

```csharp title="C#"
EnvelopeDefinition env = MakeEnvelope(signerEmail, signerName, ccEmail, ccName, docDocx, docPdf, envStatus);
var docuSignClient = new DocuSignClient(basePath);
docuSignClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken);

EnvelopesApi envelopesApi = new EnvelopesApi(docuSignClient);
var results = envelopesApi.CreateEnvelopeWithHttpInfo(accountId, env);
results.Headers.TryGetValue("X-RateLimit-Remaining", out string remaining);
results.Headers.TryGetValue("X-RateLimit-Reset", out string reset);

if (reset != null && remaining != null)
{
    DateTime resetDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(reset)).UtcDateTime;
    Console.WriteLine("API calls remaining: " + remaining);
    Console.WriteLine("Next Reset: " + resetDate);
}

return results.Data.EnvelopeId;
```

**`Java`**

```java title="Java"
	public static EnvelopeSummary signingViaEmail(
			EnvelopesApi envelopesApi,
			String accountId,
			EnvelopeDefinition envelope) throws ApiException {
		var createEnvelopeResponse = envelopesApi.createEnvelopeWithHttpInfo(accountId, envelope,
				envelopesApi.new CreateEnvelopeOptions());
		Map<String, List<String>> headers = createEnvelopeResponse.getHeaders();
		java.util.List<String> remaining = headers.get("X-RateLimit-Remaining");
		java.util.List<String> reset = headers.get("X-RateLimit-Reset");

		if (remaining != null & reset != null) {
			Instant resetInstant = Instant.ofEpochSecond(Long.parseLong(reset.get(0)));
			System.out.println("API calls remaining: " + remaining);
			System.out.println("Next Reset: " + resetInstant);
		}
		return createEnvelopeResponse.getData();
	}
```

**`Node.js`**

```javascript title="Node.js"
const sendEnvelope = async (args) => {
  // Data for this method
  // args.basePath
  // args.accessToken
  // args.accountId

  let dsApiClient = new docusign.ApiClient();
  dsApiClient.setBasePath(args.basePath);
  dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
  let envelopesApi = new docusign.EnvelopesApi(dsApiClient);
  let results = null;

  // Make the envelope request body
  let envelope = makeEnvelope(args.envelopeArgs);

  // Call the Envelopes::create API method
  // Exceptions will be caught by the calling function
  results = await envelopesApi.createEnvelope(args.accountId, {
      envelopeDefinition: envelope,
    }, (error, data, response) => {
      const headers = response?.headers;

      const remaining = headers?.['x-ratelimit-remaining'];
      const reset = headers?.['x-ratelimit-reset'];

      if (remaining && reset) {
        const resetInstant = new Date(Number(reset) * 1000); // seconds → ms

        console.log(`API calls remaining: ${remaining}`);
        console.log(`Next Reset: ${resetInstant.toISOString()}`);
      }
  });

  let envelopeId = results.data.envelopeId;

  console.log(`Envelope was created. EnvelopeId ${envelopeId}`);
  return { envelopeId: envelopeId };
};
```

**`PHP`**

```php title="PHP"
# Create the envelope request object
$envelope_definition = SigningViaEmailService::makeEnvelope(
    $args["envelope_args"],
    $clientService,
    $demoDocsPath,
    $docxFile,
    $pdfFile
);
$envelope_api = $clientService->getEnvelopeApi();

# Call Envelopes::create API method
# Exceptions will be caught by the calling function
try {
    $envelopeResponse = $envelope_api->createEnvelopeWithHttpInfo($args['account_id'], $envelope_definition);
    $headers = $envelopeResponse[2];
    $remaining = $headers['X-RateLimit-Remaining'] ?? null;
    $reset = $headers['X-RateLimit-Reset'] ?? null;

    if ($remaining !== null && $reset !== null) {
        $resetInstant = (new DateTime())->setTimestamp((int)$reset);
        error_log("API calls remaining: $remaining");
        error_log("Next Reset: " . $resetInstant->format(\DateTime::ATOM));
    }
} catch (ApiException $e) {
    // if you modify this code and are using the the JWT Conole App, uncomment
    // the following line to debug issues for easier visibility in the console
    // var_dump($e);

    $clientService->showErrorTemplate($e);
    exit;
}

return ['envelope_id' => $envelopeResponse[0]->getEnvelopeId()];
```

**`PowerShell`**

```text title="PowerShell"
Invoke-RestMethod `
    -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
    -Method 'POST' `
    -Headers @{
    'Authorization' = "Bearer $accessToken";
    'Content-Type'  = "application/json";
} `
    -InFile (Resolve-Path $requestData).Path `
    -OutFile $response
```

**`Python`**

```python title="Python"
envelope_args = args["envelope_args"]
# Create the envelope request object
envelope_definition = cls.make_envelope(envelope_args, doc_docx_path, doc_pdf_path)
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
# Call Envelopes::create API method
# Exceptions will be caught by the calling function
envelopes_api = EnvelopesApi(api_client)
(data, status, headers) = envelopes_api.create_envelope_with_http_info(account_id=args["account_id"], envelope_definition=envelope_definition)

remaining = headers.get("X-RateLimit-Remaining")
reset = headers.get("X-RateLimit-Reset")

if remaining is not None and reset is not None:
    reset_date = dt.fromtimestamp(int(reset), tz=timezone.utc)
    print(f"API calls remaining: {remaining}")
    print(f"Next Reset: {reset_date}")

envelope_id = data.envelope_id

return {"envelope_id": envelope_id}
```

**`Ruby`**

```ruby title="Ruby"
def worker
  # Create the envelope request object
  envelope_definition = make_envelope args[:envelope_args]
  # Call Envelopes::create API method
  # Exceptions will be caught by the calling function
  envelope_api = create_envelope_api(args)

  results, _status, headers = envelope_api.create_envelope_with_http_info args[:account_id], envelope_definition

  remaining = headers['X-RateLimit-Remaining']
  reset = headers['X-RateLimit-Reset']

  if remaining && reset
    reset_date = Time.at(reset.to_i).utc
    puts "API calls remaining: #{remaining}"
    puts "Next Reset: #{reset_date}"
  end

  envelope_id = results.envelope_id
  { 'envelope_id' => envelope_id }
end
```

## Expected response

If you run this code example from our Quickstart or launcher projects, you should see a JSON response similar to the code shown.

In addition, the signer receives an email containing a signing link that they can use to open and electronically sign a document using the Docusign mobile app or the Docusign website. After signing is complete, the recipient receives a carbon copy (CC) of the email that includes all of the completed and signed documents.

**`Sample response`**

```json title="Sample response"
{
  "envelopeId": "eead435f-xxxx-xxxx-xxxx-25b7d8523d2b",
  "uri": "/envelopes/eead435f-xxxx-xxxx-xxxx-25b7d8523d2b",
  "statusDateTime": "2020-08-18T23:36:26.8830000Z",
  "status": "sent"
}
```

## Next steps

* Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects:    [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).
* Find out more about [anchor tabs](/docs/esign-rest-api/esign101/concepts/tabs/auto-place).
* Learn [How to request a signature through your app](/docs/esign-rest-api/how-to/request-signature-in-app-embedded).
* See how to [Go-Live](/docs/esign-rest-api/go-live) with a completed app and find the base path for API calls in the production environment.