Common API Tasks🐈: Adding a witness to your envelope

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.


Signer signer1 = new Signer
    Email = "",
    Name = "Sue Signer",
    ClientUserId = "1001",
    RoutingOrder = "1",
    RecipientId = "1"

Witness witness1 = new Witness
    Email = "",
    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}    


Signer signer1 = new Signer();
signer1.setName("Sue Signer");

Witness witness1 = new Witness();
witness1.setName("Will Witness");
witness1.setWitnessFor("1");  	// Must match the signer’s recipientId

SignHere signHere = new SignHere();

witness1.setTabs(new Tabs());
java.util.List<SignHere> signHereTabs = new java.util.List<SignHere>()

Recipients recipients = new Recipients();
java.util.List<Signer> signers = new java.util.List<Signer>()
java.util.List<Witness> witnesses = new java.util.List<Witness>()


let signer1 = docusign.Signer.constructFromObject({
  email: '',
  name: 'Sue Signer',
  clientUserId: '1001',
  routingOrder: '1',
  recipientId: '1'
let witness1 = docusign.Witness.constructFromObject({
  email: '',
  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]});


$signer1 = new Signer([ 
  'email' => '',
  'name' => 'Sue Signer',
  'client_user_id' => '1001',
  'routing_order' => ‘1’,
  'recipient_id' => '1'
$witness1 = new Witness([ 
  'email' => '',
  '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]]);


signer1 = Signer(
  name='Sue Signer',

witness1 = Signer(
  name='Will Witness',
  witness_for='1', 		# Must match the signer’s recipient_id
sign_here = SignHere(
  document_id = '1',
  page_number = '1'
witness1.tabs = Tabs(sign_here_tabs=[sign_here])
recipients=Recipients(signers=[signer], witnesses=[witness1])


signer1 = ({
  email: '', 
  name: 'Sue Signer',
  routingOrder: '1',
  clientUserId: '1001', 
  recipientId: '1'
witness1 = ({
  email: '', 
  name: 'Will Witness',
  routingOrder: '1',
  witnessFor: '1',		# Must match the signer’s recipient_id
  recipientId: '2'
sign_here =
sign_here.x_position = '500'
sign_here.y_posiotion = '500'
sign_here.document_id = '1'
sign_here.page_number = '1'
tabs =
tabs.sign_here_tabs = [sign_here]
witness1.tabs = tabs
recipients =
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 Gazit
Sr. Manager, Developer Content