Blog
Home/

Common API Tasks🐈: Adding a witness to your envelope

Inbar Gazit
Inbar GazitSr. Manager, Developer Content
•
Summary•3 min read

See how to use the eSignature REST API to add a witness signer to your envelope.

    • Code snippets
    • Additional resources

    Table of contents

    Common API Tasks: Adding a witness to an envelope

    Welcome to another edition of the CAT🐈 (Common API Tasks) blog. This blog series is about giving you all you need to complete small, specific, SDK-supported tasks using one of our APIs. You can find all articles in this series on the Docusign developer blog. 

    Today I’d like to show you how you can use yet another feature of Docusign eSignature: signing with a witness. This feature was also recently discussed in a blog post by one of our developer support engineers. However, it was new last year and didn’t yet make it into our SDKs at the time, so today I’m going to show you how to use this feature with our six SDK-supported languages (C#, Java, Node.js, PHP, Python, and Ruby).

    Before we get to the code, let’s quickly recap what this is all about. In cases where we want a third party to confirm that they witnessed someone else signing a document, we can add that party as a special witness recipient of the envelope. We may or may not have all the information about this third party at the time the envelope is sent. That’s okay. The signer will see a pop-up message like this, enabling them to modify the name and email address of the witness as well as send them a message.

    Popup: filling in witness information

    After the signer finishes signing, the witness will get the request to sign and confirm that they witnessed the original signer signing the document. The witness has to enter their occupation and address in addition to signing the document.

    Form for witness to fill in their info

    A witness is just like any other recipient, but it must relate to a signer that exists in the envelope. That's what the witnessFor property is used for. The witness object has to have a different recipientId than the signer object it matches, but the witnessFor value should match the recipientId value of that signer object. Also note that the name and email address for the witness are just a suggestion for the signer. The signer can modify them when they sign the envelope.

    If routing order is specified, then the witness must be assigned the same value for routingOrder as the signer they are witnessing. You can specify any tabs you want for the witness.

    Regarding embedding, you can embed the witness and/or the signer view for a witnessed signer. In the code snippet below I chose to embed only the signer; the witness will use remote signing. 

    Code snippets

    The code snippets below are incomplete, and you have to use additional code to create an envelope, add documents to it, and update anything else you may need. What I’m showing here is simply how a Witness object relates to an existing Signer object and adding a SignHere tab object for the witness to sign.

    C#

    Signer signer1 = new Signer
    {
        Email = "sue@domain.com",
        Name = "Sue Signer",
        ClientUserId = "1001",
        RoutingOrder = "1",
        RecipientId = "1"
    };
    
    Witness witness1 = new Witness
    {
        Email = "will@domain.com",
        Name = "Will Witness",
        RoutingOrder = "1",
        WitnessFor = "1",		 // Must match the signer’s recipientId
        RecipientId = "2",
    };
    
    SignHere signHere = new SignHere
    {
        DocumentId = "1",
        PageNumber = "1",
        XPosition = "500",
        YPosition = "500"
    };
    
    witness1.Tabs = new Tabs { SignHereTabs = new List<signhere> { signHere } };
    
    Recipients recipients = new Recipients
    {
        Signers = new List<signer> { signer1 },
        Witnesses = new List<witness> { witness1}    
    };</witness></signer></signhere>
    

    Java

    Signer signer1 = new Signer();
    signer1.setEmail("sue@domain.com");
    signer1.setName("Sue Signer");
    signer1.setRoutingOrder("1");
    signer1.setClientUserId("1001");
    signer1.setRecipientId("1");
    
    Witness witness1 = new Witness();
    witness1.setEmail("will@domain.com");
    witness1.setName("Will Witness");
    witness1.setRoutingOrder("1");
    witness1.setWitnessFor("1");  	// Must match the signer’s recipientId
    witness1.setRecipientId("2");
    
    SignHere signHere = new SignHere();
    signHere.setDocumentId("1");
    signHere.setPageNumber("1");
    signHere.setXPosition("500");
    signHere.setYPosition("500");
    
    witness1.setTabs(new Tabs());
    java.util.List<signhere> signHereTabs = new java.util.List<signhere>()
    signHereTabs.add(signHere);
    witness1.getTabs.setSignHereTabs(signHereTabs);
    
    Recipients recipients = new Recipients();
    java.util.List<signer> signers = new java.util.List<signer>()
    signers.add(signer);
    java.util.List<witness> witnesses = new java.util.List<witness>()
    witnesses.add(witness);
    recipients.setSigners(signers);
    recipients.setWitnesses(witnesses);
    </witness></witness></signer></signer></signhere></signhere>
    

    Node.js

    let signer1 = docusign.Signer.constructFromObject({
      email: 'sue@domain.com',
      name: 'Sue Signer',
      clientUserId: '1001',
      routingOrder: '1',
      recipientId: '1'
    });
    let witness1 = docusign.Witness.constructFromObject({
      email: 'will@domain.com',
      name: 'Will Witness',
      routingOrder: '1',
      witnessFor: '1', 		// Must match the signer’s recipientId
      recipientId: '2'
    });
    let signHere = docusign.SignHere.constructFromObject({
     yPosition: '500',
     xPosition: '500',
     documentId: '1',
     pageNumber: '1'
    });
    let witness1Tabs = docusign.Tabs.constructFromObject({
    signHereTabs: [signHere1]});
    witness1.tabs = witness1Tabs;
    let recipients = docusign.Recipients.constructFromObject({
    signers: [signer1],
    witnesses: [witness1]});
    
    

    PHP

    $signer1 = new Signer([ 
      'email' => 'sue@domain.com',
      'name' => 'Sue Signer',
      'client_user_id' => '1001',
      'routing_order' => ‘1’,
      'recipient_id' => '1'
    ]);
    $witness1 = new Witness([ 
      'email' => 'will@domain.com',
      'name' => 'Will Witness',
      'routing_order' => '1',
      'witness_for' => '1',		# Must match the signer’s recipient_id
      'recipient_id' => '2'
    ]);
    $sign_here = new SignHere([
      'y_position' => '500', 'x_position' => '500',
      'document_id' => '1', 'page_number' => '1'
    ]);
    $witness1->settabs(new Tabs(['sign_here_tabs' => [$sign_here]]));
    $recipients = new Recipients(['signers' => [$signer1], 'witnesses' => [witness1]]);
    
    

    Python

    signer1 = Signer(
      email='sue@domain.com',
      name='Sue Signer',
      client_user_id='1001',
      routing_order='1',
      recipient_id='1'
    
    )
    witness1 = Signer(
      email='will@domain.com',
      name='Will Witness',
      routing_order='1',
      witness_for='1', 		# Must match the signer’s recipient_id
      recipient_id='2'
    )
    sign_here = SignHere(
      x_position='500',
      y_position='500',
      document_id = '1',
      page_number = '1'
    )
    witness1.tabs = Tabs(sign_here_tabs=[sign_here])
    recipients=Recipients(signers=[signer], witnesses=[witness1])
    
    

    Ruby

    signer1 = DocuSign_eSign::Signer.new ({
      email: 'sue@domain.com', 
      name: 'Sue Signer',
      routingOrder: '1',
      clientUserId: '1001', 
      recipientId: '1'
    })
    witness1 = DocuSign_eSign::Witness.new ({
      email: 'will@domain.com', 
      name: 'Will Witness',
      routingOrder: '1',
      witnessFor: '1',		# Must match the signer’s recipient_id
      recipientId: '2'
    })
    sign_here = DocuSign_eSign::SignHere.new
    sign_here.x_position = '500'
    sign_here.y_posiotion = '500'
    sign_here.document_id = '1'
    sign_here.page_number = '1'
    tabs = DocuSign_eSign::Tabs.new
    tabs.sign_here_tabs = [sign_here]
    witness1.tabs = tabs
    recipients = DocuSign_eSign::Recipients.new
    recipients.signers = [signer1]
    recipients.witnesses = [witness1]
    
    

    And there you have it! I hope you found it useful. If you have any questions, comments, or suggestions for topics for future Common API Tasks posts, feel free to email me. Until next time...

    Additional resources

    Inbar Gazit
    Inbar GazitSr. Manager, Developer Content

    Inbar Gazit has been with Docusign since 2013 in various engineering roles. Since 2019 he has focused on developer content. Inbar works on code examples including the launchers, available on GitHub in eight languages, and helps build sample apps showcasing the various Docusign APIs. He is also active on StackOverflow, answering your questions. Inbar can be reached at inbar.gazit@docusign.com.

    More posts from this author

    Related posts

    • Developer Spotlight

      Developer Spotlight is Coming to Docusign Community!

      Matthew Lusher
      Matthew Lusher
    • Breaking the Language Barrier: Why Large Language Models Need Open Text Formats

      Dan Selman
      Dan Selman
    • Understanding Levenshtein Distance: Applications to AI-Generated Text

      Vincent Pan
      Vincent Pan

    Developer Spotlight is Coming to Docusign Community!

    Matthew Lusher
    Matthew Lusher

    Understanding Levenshtein Distance: Applications to AI-Generated Text

    Vincent Pan
    Vincent Pan

    Discover what's new with Docusign IAM or start with eSignature for free

    Explore Docusign IAMTry eSignature for Free
    Person smiling while presenting