Common API Tasksđ: Adding a witness to your envelope
See how to use the eSignature REST API to add a witness signer to your envelope.
Table of contents
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.
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.
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 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.
Related posts