Docusign - How To - How to request a signature by SMS and WhatsAPP

How to request a signature by SMS and WhatsAPP

This topic demonstrates how to send a signature request via an SMS or WhatsApp message. 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.

Required data

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

DATA ELEMENT DESCRIPTION
{API_ACCOUNT_ID} A GUIDGUID, opens in new window 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 KeysApps and Keys, opens in new window 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:///restapi, Where 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 signer where the SMS or WhatsApp notification will be sent.
{CC_RECIPIENT_NAME} A string value for the name of the cc 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 offlineThe 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, opens in new window
PDF file, opens in new window
A third document in HTML is constructed dynamically by the sample code
{PHONE_NUMBER} The phone number of the signer where 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 OAuth grant types: Authorization Code Grant, Implicit Grant, and JSON Web Token (JWT) Grant. Choose the OAuth grant type appropriate for your scenario.

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.

  1. 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>
  """

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 API method to create an envelope and send it, adding your access token and base path to the request header.

  1. 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 = envelopes_api.create_envelope(account_id=args["account_id"], envelope_definition=envelope_definition)

envelope_id = results.envelope_id

return {"envelope_id": envelope_id}

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

{
  "envelopeId": "e319acf5-xxxx-xxxx-xxxx-8bd6eae9abb7",
  "uri": "/envelopes/e319acf5-xxxx-xxxx-xxxx-8bd6eae9abb7",
  "statusDateTime": "2023-04-06T19:38:30.6530000Z",
  "status": "sent"
}