> 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 SMS or WhatsApp delivery

> This topic demonstrates how to send a signature request via an SMS message. Recipients receive an SMS notification with a signing link that they can use to open and electronically sign a document using the Docusign mobile app or the Docusign website.

eSignature REST API 2.1 only

This topic demonstrates how to send a signature request via an [SMS or WhatsApp message](/docs/esign-rest-api/esign101/concepts/sms-delivery). Recipients receive a notification from SMS or WhatsApp with a signing link that they can use to open and electronically sign a document using the Docusign mobile app or the Docusign website.

> **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.                                                                                                    |
| \{CC_COUNTRY_CODE}     | The country code corresponding to the CC_PHONE_NUMBER.                                                                                                                                                                                                                                                                                                                                                                    |
| \{CC_PHONE_NUMBER}     | The phone number of the carbon copy recipient to whom the SMS or WhatsApp notification will be sent.                                                                                                                                                                                                                                                                                                                      |
| \{CC_RECIPIENT_NAME}   | A string value for the name of the carbon copy recipient.                                                                                                                                                                                                                                                                                                                                                                 |
| \{COUNTRY_CODE}        | The country code corresponding to the PHONE_NUMBER.                                                                                                                                                                                                                                                                                                                                                                       |
| \{DELIVERY_METHOD}     | The delivery method specified for a given recipient. One of: `Email`, `fax`, `SMS`, `WhatsApp`, or `offline` The SMS and WhatsApp delivery methods are limited to signer, carbonCopy, and certifiedDelivery recipients.                                                                                                                                                                                                   |
| 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 |
| \{PHONE_NUMBER}        | The phone number of the signer to whom the SMS or WhatsApp notification will be sent.                                                                                                                                                                                                                                                                                                                                     |
| \{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

To request a signature, you need to create a new envelope definition. The accompanying code shows how to create an individual envelope by defining a method named `makeEnvelope` that creates the envelope definition. The `makeEnvelope` method:

* Creates and attaches multiple documents to the envelope.
* Sets signer and CC recipient data.
* Creates a routing order for the documents.
* Creates and assigns signable fields to specific signers within the documents.To send an SMS or WhatsApp notification, you need to edit the signer's `phnoneNumber` field to include values for `number` and `countryCode`. You also have to set the `deliveryMethod` field to either "`SMS"` or `"WhatsApp"`. You should make these changes for each recipient you want to notify via SMS or WhatsApp. The accompanying code also demonstrates how to notify a carbon copy recipient via SMS or WhatsApp by editing the same fields in the `carbonCopy` object.

**`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":
        [
            {
            "phoneNumber":
                {
                    "countryCode": "'"${CC_PHONE_COUNTRY}"'",
                    "number":"'"${CC_PHONE_NUMBER}"'"
                },
            "name": "'"${CC_NAME}"'",
            "recipientId": "2",
            "routingOrder": "2",
            "deliveryMethod": "'"${DELIVERY_METHOD}"'",
            }
        ],
        "signers":
        [
            {
            "phoneNumber":
                {
                    "countryCode": "'"${SIGNER_PHONE_COUNTRY}"'",
                    "number":"'"${SIGNER_PHONE_NUMBER}"'"
                },
                "name": "'"${SIGNER_NAME}"'",
                "recipientId": "1",
                "routingOrder": "1",
                "deliveryMethod": "'"${DELIVERY_METHOD}"'",
                "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#"
private static EnvelopeDefinition MakeEnvelope(string signerName, string signerCountryCode, string signerPhoneNumber, string ccName, string ccCountryCode, string ccPhoneNumber, string docDocx, string docPdf, string envStatus, string deliveryMethod)
{
    // Data for this method
    // signerName
    // signerCountryCode
    // signerPhoneNumber
    // ccName
    // ccCountryCode
    // ccPhoneNumber
    // docDocx
    // docPdf
    // envStatus -- the envelope status ('created' or 'sent')

    // 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.
    // read files from a local directory
    // The reads could raise an exception if the file is not available!
    string doc2DocxBytes = Convert.ToBase64String(System.IO.File.ReadAllBytes(docDocx));
    string doc3PdfBytes = Convert.ToBase64String(System.IO.File.ReadAllBytes(docPdf));

    // create the envelope definition
    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(signerPhoneNumber, signerName, ccPhoneNumber, 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
    {
        Name = signerName,
        RecipientId = "1",
        RoutingOrder = "1",
        DeliveryMethod = deliveryMethod,
        PhoneNumber = new RecipientPhoneNumber
        {
            CountryCode = signerCountryCode,
            Number = signerPhoneNumber,
        },
    };

    // 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
    {
        Name = ccName,
        RecipientId = "2",
        RoutingOrder = "2",
        DeliveryMethod = deliveryMethod,
        PhoneNumber = new RecipientPhoneNumber
        {
            CountryCode = ccCountryCode,
            Number = ccPhoneNumber,
        },
    };

    // 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;
}

private static byte[] Document1(string signerPhone, string signerName, string ccPhone, string ccName)
{
    // Data for this method
    // signerEmail
    // signerPhone
    // ccPhone
    // ccName
    return Encoding.UTF8.GetBytes(
    " <!DOCTYPE html>\n" +
        "    <html>\n" +
        "        <head>\n" +
        "          <meta charset=\"UTF-8\">\n" +
        "        </head>\n" +
        "        <body style=\"font-family:sans-serif;margin-left:2em;\">\n" +
        "        <h1 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;\n" +
        "            color: darkblue;margin-bottom: 0;\">World Wide Corp</h1>\n" +
        "        <h2 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;\n" +
        "          margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;\n" +
        "          color: darkblue;\">Order Processing Division</h2>\n" +
        "        <h4>Ordered by " + signerName + "</h4>\n" +
        "        <p style=\"margin-top:0em; margin-bottom:0em;\">Phone Number: " + signerPhone + "</p>\n" +
        "        <p style=\"margin-top:0em; margin-bottom:0em;\">Copy to: " + ccName + ", " + ccPhone + "</p>\n" +
        "        <p style=\"margin-top:3em;\">\n" +
        "  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.\n" +
        "        </p>\n" +
        "        <!-- Note the anchor tag for the signature field is in white. -->\n" +
        "        <h3 style=\"margin-top:3em;\">Agreed: <span style=\"color:white;\">**signature_1**/</span></h3>\n" +
        "        </body>\n" +
        "    </html>");
}
```

**`Java`**

```java title="Java"
// 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.
public static EnvelopeDefinition makeEnvelope(
        String countryCode,
        String signersPhoneNumber,
        String signerName,
        String deliveryMethod,
        String ccCountryCode,
        String carbonCopyPhoneNumber,
        String ccName,
        String status) 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("/sn1/", ANCHOR_OFFSET_Y, ANCHOR_OFFSET_X));

    // Create a signer recipient to sign the document, identified by name
    // and phone number. 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.

    RecipientPhoneNumber phoneNumber = new RecipientPhoneNumber();
    phoneNumber.setCountryCode(countryCode);
    phoneNumber.setNumber(signersPhoneNumber);

    Signer signer = new Signer();
    signer.setName(signerName);
    signer.setPhoneNumber(phoneNumber);
    signer.setRecipientId("1");
    signer.setRoutingOrder("1");
    signer.setTabs(signerTabs);
    signer.setDeliveryMethod(deliveryMethod);

    // create a cc recipient to receive a copy of the documents, identified by name
    // and phone number
    RecipientPhoneNumber ccPhoneNumber = new RecipientPhoneNumber();
    ccPhoneNumber.setCountryCode(ccCountryCode);
    ccPhoneNumber.setNumber(carbonCopyPhoneNumber);

    CarbonCopy cc = new CarbonCopy();
    cc.setName(ccName);
    cc.setPhoneNumber(ccPhoneNumber);
    cc.setRecipientId("2");
    cc.setRoutingOrder("2");
    cc.setDeliveryMethod(deliveryMethod);

    // The order in the docs array determines the order in the envelope
    EnvelopeDefinition envelope = new EnvelopeDefinition();
    envelope.setEmailSubject("Please sign this document set");
    envelope.setDocuments(Arrays.asList(
            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.signerName
  // args.phoneNumber
  // args.countryCode
  // args.ccName
  // args.ccPhoneNumber
  // args.ccCountryCode
  // 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 RecipientPhoneNumber object for the signer's phone number
  let signerPhoneNumber = docusign.RecipientPhoneNumber.constructFromObject({
    countryCode: args.countryCode,
    number: args.phoneNumber,
  });

  // Create a signer recipient to sign the document, identified by name and phone number
  // We're setting the parameters via the object constructor
  let signer1 = docusign.Signer.constructFromObject({
    name: args.signerName,
    phoneNumber: signerPhoneNumber,
    deliveryMethod: args.deliveryMethod,
    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 RecipientPhoneNumber object for the signer's phone number
  let ccPhoneNumber = docusign.RecipientPhoneNumber.constructFromObject({
    countryCode: args.ccCountryCode,
    number: args.ccPhoneNumber,
  });

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

  // 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.signerName
  // 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;">Phone number: ${args.phoneNumber}</p>
        <p style="margin-top:0em; margin-bottom:0em;">Copy to: ${args.ccName}, ${args.ccPhoneNumber}</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,
    $docDocx,
    $docPDF
): EnvelopeDefinition {
    $envelope_definition = CreateAnEnvelopeFunctionService::makeEnvelope(
        $args,
        $clientService,
        $demoDocsPath,
        $docDocx,
        $docPDF
    );

    $signerPhone = new RecipientPhoneNumber([
        'country_code' => $args['signer_country_code'],
        'number' => $args['signer_phone_number']
    ]);

    # Create the signer recipient model
    $signer1 = new Signer([
        'name' => $args['signer_name'], 'phone_number' => $signerPhone,
        'recipient_id' => "1", 'routing_order' => "1",
        'delivery_method' => $args['deliveryMethod']
        ]);
    # 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.

    $CCsignerPhone = new RecipientPhoneNumber([
        'country_code' => $args['cc_country_code'],
        'number' => $args['cc_phone_number']
    ]);

    # Create a CC recipient to receive a copy of the documents
    $CC = new CarbonCopy([
        'name' => $args['cc_name'], 'phone_number' => $CCsignerPhone,
        'recipient_id' => "2", 'routing_order' => "2",
        'delivery_method' => $args['deliveryMethod']
        ]);

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

public static function addSignersToTheDelivery($signer1, $CC, $envelope_definition, $args)
{
    # 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 = new SignHere([
                                   'anchor_string' => '**signature_1**', 'anchor_units' => 'pixels',
                                   'anchor_y_offset' => '10', 'anchor_x_offset' => '20']);
    $sign_here2 = new 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->setTabs(new Tabs([
                                   'sign_here_tabs' => [$sign_here1, $sign_here2]]));

    # Add the recipients to the envelope object
    $recipients = new Recipients([
                                     'signers' => [$signer1], 'carbon_copies' => [$CC]]);
    $envelope_definition->setRecipients($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"
    $envelope_definition->setStatus($args["status"]);

    return $envelope_definition;
```

**`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 = @(
            @{
                phoneNumber = @{
                    countryCode =  $MSGCCCountryPrefix;
                    number = $MSGNumberCC;
                }
                name         = $variables.CC_NAME;
                recipientId  = "2";
                routingOrder = "2";
                deliveryMethod = $selected;
            };
        );

        signers      = @(
            @{
                phoneNumber = @{
                    countryCode =  $MSGCountryPrefix;
                    number = $MSGNumber;

                }
                name         = $variables.SIGNER_NAME;
                recipientId  = "1";
                routingOrder = "1";
                deliveryMethod = $selected;
                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"
@classmethod
def make_envelope(cls, args):
    """
    Creates envelope:
    document 1 (HTML) has signHere anchor tag: **signature_1**
    document 2 (DOCX) has signHere anchor tag: /sn1/
    document 3 (PDF)  has signHere anchor tag: /sn1/
    DocuSign will convert all of the documents to the PDF format.
    The recipient’s field tags are placed using anchor strings.
    The envelope has two recipients:
    recipient 1: signer
    recipient 2: cc
    The envelope will be sent first to the signer via SMS.
    After it is signed, a copy is sent to the cc recipient via SMS.
    """
    # 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 folder
    # The reads could raise an exception if the file is not available!
    with open(path.join(demo_docs_path, DS_CONFIG["doc_docx"]), "rb") as file:
        doc2_docx_bytes = file.read()
    doc2_b64 = base64.b64encode(doc2_docx_bytes).decode("ascii")
    with open(path.join(demo_docs_path, DS_CONFIG["doc_pdf"]), "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]

    signerPhoneNumber = RecipientPhoneNumber(
        country_code=args["country_code"],
        number=args["phone_number"]
    )

    # Create the signer recipient model
    signer1 = Signer(
        name=args["signer_name"],
        recipient_id="1",
        routing_order="1",
        delivery_method=args["delivery_method"],
        phone_number=signerPhoneNumber
    )

    # Create a RecipientPhoneNumber and add it to the additional SMS notification
    ccPhoneNumber = RecipientPhoneNumber(
        country_code=args["cc_country_code"],
        number=args["cc_phone_number"]
    )

    # Create a cc recipient to receive a copy of the documents
    cc1 = CarbonCopy(
        name=args["cc_name"],
        recipient_id="2",
        routing_order="2",
        delivery_method=args["delivery_method"],
        phone_number=ccPhoneNumber
    )

    # 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 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 SignHere 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;">Phone Number: {args["phone_number"]}</p>
        <p style="margin-top:0em; margin-bottom:0em;">Copy to: {args["cc_name"]}</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 via SMS
  # After it is signed, a copy is sent to the cc person via SMS

  # 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!
  doc_docx = Rails.application.config.doc_docx
  doc2_b64 = Base64.encode64(File.binread(File.join('data', doc_docx)))
  doc_pdf = Rails.application.config.doc_pdf
  doc3_b64 = Base64.encode64(File.binread(File.join('data', 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]

  signer_phone_number = DocuSign_eSign::RecipientPhoneNumber.new
  signer_phone_number.country_code = envelope_args[:country_code]
  signer_phone_number.number = envelope_args[:phone_number]

  # Create the signer recipient model
  signer1 = DocuSign_eSign::Signer.new
  signer1.phone_number = signer_phone_number
  signer1.name = envelope_args[:signer_name]
  signer1.recipient_id = '1'
  signer1.routing_order = '1'
  signer1.delivery_method = envelope_args[:delivery_method]

  ## 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

  cc_phone_number = DocuSign_eSign::RecipientPhoneNumber.new
  cc_phone_number.country_code = envelope_args[:cc_country_code]
  cc_phone_number.number = envelope_args[:cc_phone_number]

  # Create a cc recipient to receive a copy of the documents
  cc1 = DocuSign_eSign::CarbonCopy.new
  cc1.name = envelope_args[:cc_name]
  cc1.routing_order = '2'
  cc1.recipient_id = '2'
  cc1.phone_number = cc_phone_number
  cc1.delivery_method = envelope_args[:delivery_method]

  # 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;\">Phone number: #{args[:phone_number]}</p>
      <p style=\"margin-top:0em; margin-bottom:0em;\">Copy to: #{args[:cc_name]}, #{args[:cc_phone_number]}</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

With the envelope definition and the attributes defined for the signer, document, and custom fields, you can now use the [Envelopes:create](/docs/esign-rest-api/reference/envelopes/envelopes/create) API method to create an envelope
and send it, adding your access token and base path to the request header.

> **Note**
>
> View the source code for this how-to on GitHub: [Bash](https://github.com/docusign/code-examples-bash/blob/master/examples/eSignature/eg037SigningViaSMS.sh), [C#](https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Examples/SMSDelivery.cs), [Java](https://github.com/docusign/code-examples-java/blob/master/src/main/java/com/docusign/controller/eSignature/services/SMSDeliveryService.java), [Node.js](https://github.com/docusign/code-examples-node/blob/master/lib/eSignature/examples/smsDelivery.js), [PHP](https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/SMSDeliveryService.php), [PowerShell](https://github.com/docusign/code-examples-powershell/blob/master/examples/eSignature/eg037SMSDelivery.ps1), [Python](https://github.com/docusign/code-examples-python/blob/master/app/eSignature/examples/eg037_sms_delivery.py), or [Ruby](https://github.com/docusign/code-examples-ruby/blob/master/app/services/e_sign/eg037_sms_delivery_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#"
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);
}
```

**`Java`**

```java title="Java"
public static EnvelopeSummary smsDelivery(
        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"
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);

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

**`PHP`**

```php title="PHP"
$envelopeResponse = $envelope_api->createEnvelopeWithHttpInfo($args['account_id'], $envelope_definition);

$remaining = $envelopeResponse[2]['X-RateLimit-Remaining'] ?? null;
$reset =  $envelopeResponse[2]['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));
}
```

**`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

Write-Output "Response: $(Get-Content -Raw $response)"
```

**`Python`**

```python title="Python"
envelope_args = args["envelope_args"]
# Create the envelope request object
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
envelope_definition = cls.make_envelope(envelope_args)
# Call Envelopes::create API method
# Exceptions will be caught by the calling function
envelopes_api = EnvelopesApi(api_client)
(results, 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 = results.envelope_id

return {"envelope_id": envelope_id}
```

**`Ruby`**

```ruby title="Ruby"
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
```

## 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 SMS or WhatsApp message 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": "e319acf5-xxxx-xxxx-xxxx-8bd6eae9abb7",
  "uri": "/envelopes/e319acf5-xxxx-xxxx-xxxx-8bd6eae9abb7",
  "statusDateTime": "2023-04-06T19:38:30.6530000Z",
  "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).
* Learn more about [SMS delivery or WhatsApp](/docs/esign-rest-api/esign101/concepts/sms-delivery).
* Find out [How to request a signature by email](/docs/esign-rest-api/how-to/request-signature-email-remote).
* 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.