Skip to main content
Blog
Home/

Common API Tasks🐈: Adding a witness to your envelope

Author Inbar Gazit
Inbar GazitSr. Manager, Developer Content and Advocacy
Summary3 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

    Author Inbar Gazit
    Inbar GazitSr. Manager, Developer Content and Advocacy

    Inbar Gazit has been with Docusign since 2013 in various engineering roles. Since 2019 he has focused on developer content and advocacy. 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 Docusign Community and StackOverflow, answering your questions. Inbar can be reached at inbar.gazit@docusign.com.

    More posts from this author

    Related posts

    • Developers

      Configuring Salesforce for scalable and secure Docusign integrations

      Author Achille Jean Axel Nisengwe
      Achille Jean Axel Nisengwe
      Configuring Salesforce for scalable and secure Docusign integrations
    • 2025 Developer Release 1: Build faster, agree smarter

      Author Amina Atlaf
      Amina Atlaf
      2025 Developer Release 1: Build faster, agree smarter
    • Start embedding your Docusign workflows with the Embedded Sending Sample App

      Author Karissa Jacobsen
      Karissa Jacobsen
      Start embedding your Docusign workflows with the Embedded Sending Sample App

    Configuring Salesforce for scalable and secure Docusign integrations

    Author Achille Jean Axel Nisengwe
    Achille Jean Axel Nisengwe
    Configuring Salesforce for scalable and secure Docusign integrations

    2025 Developer Release 1: Build faster, agree smarter

    Author Amina Atlaf
    Amina Atlaf
    2025 Developer Release 1: Build faster, agree smarter

    Start embedding your Docusign workflows with the Embedded Sending Sample App

    Author Karissa Jacobsen
    Karissa Jacobsen
    Start embedding your Docusign workflows with the Embedded Sending Sample App

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

    Explore Docusign IAMTry eSignature for Free
    Person smiling while presenting