DocuSign REST API - Send envelopes as a different user - docusignapi

I am setting up a web app that uses DocuSign to send an eSignature request to various different clients. Each request to a different client needs to have a different displayed sender name and email address, and not just the main name on the DocuSign account. The completed e-signed form also needs to be emailed to these client-specific email addresses as well.
I have created a new second login within my DocuSign account as a test, and am able to get it to display this login's name/email, but only when I generate an entirely new temporary demo API key from that account and use that in the application.
I am able to change the reply email by altering the EnvelopeDefinition.EmailSettings.ReplyEmailAddressOverride field, but the envelope email sent to signers still displays the main account name/email, and signed docs are emailed to the main email.
How can I change the name and email address sent to the signer and the email address signed docs are received by?
string signerName = "John Doe";
string signerEmail = "johndoe#fake.com";
string accessToken = "{The DocuSign API KEY}";
string accountId = "{The DocuSign Account Number}";
Document document = new Document
{
DocumentBase64 = Convert.ToBase64String(ReadContent(docName)),
Name = "Please Sign This Form",
FileExtension = "docx",
DocumentId = "1"
};
Document[] documents = new Document[] { document };
Signer signer = new Signer
{
Email = signerEmail,
Name = signerName,
RecipientId = "1",
RoutingOrder = "1"
};
Tabs tabs = new Tabs();
SignHere signHereTab = new SignHere
{
DocumentId = "1",
PageNumber = "1",
AnchorString = "Patient Signature or Mark",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "-18",
Width = "160"
};
List<SignHere> signatureTabs = new List<SignHere>();
signatureTabs.Add(signHereTab);
tabs.SignHereTabs = signatureTabs;
FullName nameTab = new FullName
{
DocumentId = "1",
PageNumber = "1",
TabLabel = "Full Name",
Value = signerName,
AnchorUnits = "pixels",
AnchorString = "Name:",
AnchorXOffset = "133",
AnchorYOffset = "5"
};
List<FullName> nameTabs = new List<FullName>();
nameTabs.Add(nameTab);
tabs.FullNameTabs = nameTabs;
signer.Tabs = tabs;
Recipients recipients = new Recipients
{
Signers = new List<Signer> { signer }
};
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition
{
EmailSubject = "Please Sign Form",
Documents = new List<Document>(documents),
Recipients = recipients,
Status = "sent"
};
//Override the reply email address
envelopeDefinition.EmailSettings = new EmailSettings();
envelopeDefinition.EmailSettings.ReplyEmailAddressOverride = "client-specific-email#fake.com";
envelopeDefinition.EmailSettings.ReplyEmailNameOverride = "Test Account";
ApiClient apiClient = new ApiClient(basePath);
apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient.Configuration);
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);

If your app wants to send as various different people (users) on your DocuSign account, the right answer is to impersonate them using the OAuth JWT flow. See the JWT examples, the eg-01 code examples, on github.com/docusign.
For each user impersonated, your app will need their user guid from DocuSign. It is available from the Users section of the administration tool.
The old legacy authentication header technique is not supported for new apps.

Since you are using the Token Generator on Developer Center https://developers.docusign.com/oauth-token-generator, your choice for now is to login to that website with the other user you wish to use and that token would be for that other user.
Long term I would suggest you look into using JWT Auth. That has the option of specifiying the userId and you can switch users. You also have to use real auth if you want to move your app out of the developer sandbox and into production anyway.

Related

Remove/Correct Identity Verification from a signer from DocuSign SDK

I create an envelope and I want to implement the Correct functionality same as the DocuSign portal from API.
On creation I setup the authentication type to a signer and working perfectly.
Signer signer = new Signer
{
Email = email,
Name = name,
RecipientId = recipientId
};
//On Create
RecipientSMSAuthentication smsAuth = new RecipientSMSAuthentication();
smsAuth.SenderProvidedNumbers = new List<string>();
foreach (var telephone in telephoneNumbers)
{
smsAuth.SenderProvidedNumbers.Add(telephone);
}
signer.IdCheckConfigurationName = "SMS Auth $";
signer.SmsAuthentication = smsAuth;
When I try to correct this signer and remove or change (etc phone) this authentication type is not working
//On Update
signer.IdCheckConfigurationName = "";
signer.SmsAuthentication = null;
I use the UpdateAsync api call
Recipients Recipients = new Recipients();
List<Signer> Signers = new List<Signer>();
Signers.Add(signer);
Recipients.Signers = Signers;
await envelopesApi.UpdateAsync(accountId, envelopeId, new Envelope() { Recipients = Recipients }, new EnvelopesApi.UpdateOptions() { resendEnvelope = "true" });
A couple of things.
First, you're using the old method for SMS verification in this code. A new method which is going to give you more flexibility was introduced recently. It looks like this:
RecipientIdentityVerification workflow = new RecipientIdentityVerification()
{
WorkflowId = workflowId,
InputOptions = new List<RecipientIdentityInputOption> {
new RecipientIdentityInputOption
{
Name = "phone_number_list",
ValueType = "PhoneNumberList",
PhoneNumberList = new List<RecipientIdentityPhoneNumber>
{
new RecipientIdentityPhoneNumber
{
Number = phoneNumber,
CountryCode = countryAreaCode,
}
}
}
}
};
Signer signer1 = new Signer()
{
Name = signerName,
Email = signerEmail,
RoutingOrder = "1",
Status = "Created",
DeliveryMethod = "Email",
RecipientId = "1", //represents your {RECIPIENT_ID},
Tabs = signer1Tabs,
IdentityVerification = workflow,
};
Note that your account may not have the new auth method enabled, you can either create a new developer account or contact support to enable it for you,.
Second, updating recipients of an existing envelopes has some limits. It can only be done if the envelope is in a "Draft" status ("created") and not after it was sent ("sent"). You may need to use the Correct action in that case.

Assign to someone else is enabled in Docusign, but not appearing as an option for recipients

We've enabled "Assign to someone else" in preferences.
Envelopes created via the UI offer recipients the ablity to assign to someone else.
We explicitly set AllowReassign = "true" on envelopes created via the API.
Envelopes created via the API do NOT offer this option.
NOTE: We are NOT using the emails generated by docusign: we are sending our own emails then using the API CreateRecipientView call based on a unique token.
If I use "correct" to edit a sent envelope and add a new recipient, this DOES generate a docusign email, and this new recipient DOES have the option to "assign to someone else" on clicking the link.
What is preventing the "assign to someone else" functionality from working? Might it be our use of CreateRecipientView? Is there a bug? Failing that, what other things can I check?
EDIT - as suggested exmaple code of how we create the envelope
var envDefinition = new EnvelopeDefinition { EmailSubject = emailSubject) };
envDefinition.Documents = new List<Document>();
//Add the email text
envDefinition.EmailSubject = HttpUtility.HtmlDecode(Title);
envDefinition.EmailBlurb = HttpUtility.HtmlDecode(Message);
//Add the documents
envDefinition.Documents = PopulateDocuments(documentList, Envelope);
EventNotification evenNotification = new EventNotification
{
LoggingEnabled = "true",
RequireAcknowledgment = "true",
UseSoapInterface = "false",
IncludeCertificateWithSoap = "false",
SignMessageWithX509Cert = "false",
IncludeDocuments = "true",
IncludeEnvelopeVoidReason = "true",
IncludeTimeZone = "true",
IncludeSenderAccountAsCustomField = "true",
IncludeDocumentFields = "true",
IncludeHMAC = "true",
IncludeCertificateOfCompletion = "false",
};
evenNotification.Url = docusignBaseUrl;
var envelopeEvents = new List<EnvelopeEvent>();
// In this case we only add a single envelope event, we can add multiple events based on requirement
envelopeEvents.Add(new EnvelopeEvent { EnvelopeEventStatusCode = EnvelopeEventStatusCompleted, IncludeDocuments = "true" });
envelopeEvents.Add(new EnvelopeEvent { EnvelopeEventStatusCode = EnvelopeEventStatusVoided, IncludeDocuments = "false" });
envelopeEvents.Add(new EnvelopeEvent { EnvelopeEventStatusCode = EnvelopeEventStatuDeclined, IncludeDocuments = "false" });
evenNotification.EnvelopeEvents = envelopeEvents;
List<RecipientEvent> rEvents = new List<RecipientEvent>();
rEvents.Add(new RecipientEvent { RecipientEventStatusCode = RecipientEventStatusDeclined, IncludeDocuments = "false" });
rEvents.Add(new RecipientEvent { RecipientEventStatusCode = RecipientEventStatusCompleted, IncludeDocuments = "false" });
evenNotification.RecipientEvents = rEvents;
envDefinition.EventNotification = evenNotification;
//Add the recipients
envDefinition.Recipients = PopulateRecipients(Envelope);
//envDefinition.RecipientsLock = "true"; //cannot add new receipients at docusign
envDefinition.AllowReassign = "true";
envDefinition.Status = "created";
//submit the envelope
envelopesApi = new EnvelopesApi(apiClient);
envelopeSummary = envelopesApi.CreateEnvelope(_docuSignAccountId, envDefinition);
and the recipients (Signers)
Signer signer = new Signer();
signer.Name = Recipient.GetRecipientName(recipient.TheRecipient);
signer.Email = Recipient.GetRecipientEmail(recipient.TheRecipient);
signer.RecipientId = recipient.Id.ToString();
signer.TemplateLocked = "true"; //cannot be edited as docusign
signer.TemplateRequired = "true"; //cannot be removed at docusign
signer.EmailNotification = new RecipientEmailNotification()
{
SupportedLanguage = GetLanguage(recipient),
EmailSubject = string.Format(WebDisplayHelper.GetText(typeof(DocuSignFileHandler), DocuSignFileHandlerResources.EmailSubject),
HttpUtility.HtmlDecode(Envelope.Title),
HttpUtility.HtmlDecode(Envelope.Reference)),
EmailBody = HttpUtility.HtmlDecode(Envelope.Blurb)
};
signer.RoutingOrder = recipient.RoutingOrder.ToString();
This code works in general - in addition to enabling "Allow recipients to change signing responsibility" in Settings, the only code change is that we've commented out the code which locks recipients, and added the explicit call
envDefinition.AllowReassign = "true";
Ideally we would retain the lock so that new recipients cannot be added, while allowing specified receipients to reassign the signature to someone else
The Signer Reassign feature does disappear under certain circumstances. If you're sending the email notifications on your own and utilizing recipientViewTokens, that means that you're most likely using captive recipients. What makes a captive recipient captive is the existence of a clientUserId, which enables recipientViewTokens and stops the initial email notifications from going out.
One of the other things it does is that the envelope is bound to a generic DocuSign account, not to any particular users personal DS account. Because the DS account / user seat is required for signer reassign the option is removed.
Feel free to open up a ticket on the support portal to discuss in realtime, myself or someone from my team can meet with you to go over the issue.
Regards,
Matt

DocuSign API - Email Notification Settings

I'm successfully sending envelopes via the DocuSign eSignature API and have a question about the emails that are sent as part of the signing process. When a request is sent I'm receiving the following emails (using the Sandbox environment):
email to each recipient from dse_demo#docusign.net with a reply to of my name/email address
email to me when each recipient clicks the link to view the agreement to sign (e.g. "John Smith viewed Acme Co Customer Agreement")
email to me (and each recipient) when agreement has been completed.
I'm trying to understand what options are available for each of these as far as:
enabling/disabling each of these emails
changing the email address used for each of these (and if this can be done via the API)
Appreciate any insights into whether and how I can make any changes to these.
The completion emails can be enabled/disabled in the settings for your DocuSign account. This can be found in: Settings > Signing Settings > Envelope Delivery. You can also enable/disable the "envelope viewed" notification emails and completion emails for both the sender and signer in: Settings > Email Preferences.
Which language are you integrating the API with? In C# you can change the email when adding the envelope recipient in the envelope definition e.g.
private static EnvelopeDefinition MakeEnvelope(string recipientEmail)
{
recipientEmail = "recipientEmail#email.com"
byte[] buffer = System.IO.File.ReadAllBytes("filePath");
Document doc1 = new Document();
string b64 = Convert.ToBase64String(buffer);
doc1.DocumentBase64 = b64;
doc1.Name = "Document Name";
doc1.FileExtension = "pdf";
doc1.DocumentId = "1";
env.Documents = new List<Document> { doc1 };
Text textTab = new Text
{
DocumentId = "1",
PageNumber = "1",
XPosition = "168",
YPosition = "513",
Height = "17",
Width = "369",
Value = "envelopeTabText",
Locked = "true"
};
SignHere signer1signhere = new SignHere
{
DocumentId = "1",
PageNumber = "1",
XPosition = "128",
YPosition = "775"
};
**Signer signer1 = new Signer
{
Email = recipientEmail,
Name = "customerName",
RecipientId = "1",
RoutingOrder = "1"
};**
Tabs signer1Tabs = new Tabs
{
TextTabs = new List<Text> { textTab },
SignHereTabs = new List<SignHere> { signer1signhere }
};
signer1.Tabs = signer1Tabs;
Recipients recipients = new Recipients
{
Signers = new List<Signer> { signer1 }
};
env.Recipients = recipients;
env.Status = "sent";
return env;
}

How can we send draft envelope to other recipient of envelope?

I am using Authorizatio Code Grant for authorization and wanted to send envelope as draft to other envelope recipient(editor). But in this case it is going to draft of whoever is logging and sending envelope request. I can send that envelope to other recipient's draft simply using "Transfer Owenership" from sender's draft but wanted to automate this while sending envelope request.
Here is the envelope request I am sending:
try
{
// create the envelope definition
EnvelopeDefinition env = new EnvelopeDefinition();
env.EmailSubject = $"Please Sign - { DateTime.Now.ToString() }";
//Get document extension
var fileContentByteArray = System.IO.File.ReadAllBytes("D:\\ESign1.docx");
Document documentToSign = new Document
{
DocumentBase64 = Convert.ToBase64String(fileContentByteArray),
Name = "ESign1.docx",
FileExtension = "docx",
DocumentId = "1"
};
env.Documents = new List<Document> { documentToSign };
var signatureHandler = new Editor
{
Email = "abc#test.com",
RecipientId = "1",
RoutingOrder = "1",
};
List<Signer> signers = new List<Signer>();
signers.Add(new Signer { Email = "xyz#test.com", Name = "xyz", RecipientId = "3", RoutingOrder = "3" });
signers.Add(new Signer { Email = "abc#test.com", Name = "abc", RecipientId = "2", RoutingOrder = "2" });
// Add the recipients to the envelope object
Recipients recipients = new Recipients
{
Editors = new List<Editor> { signatureHandler },
Signers = signers
};
//Attache all recipients to envelope
env.Recipients = recipients;
//Webhook to listen envelope status
EventNotification eventNotification = new EventNotification
{
IncludeDocuments = "true",
IncludeDocumentFields = "true",
IncludeTimeZone = "true",
Url = "https://webhook-endpoint",
LoggingEnabled = "true",
EnvelopeEvents = new List<EnvelopeEvent>
{
new EnvelopeEvent{ EnvelopeEventStatusCode = "completed", IncludeDocuments = "true" }
}
};
env.EventNotification = eventNotification;
env.Status = "created";
var config = new Configuration(baseUrl);
config.AddDefaultHeader("Authorization", "Bearer " + access_token);
var apiClient = new ApiClient(baseUrl)
{
Configuration = config
};
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeSummary result = envelopesApi.CreateEnvelopeAsync(account_id, env).Result;
}
catch (Exception ex)
{
}
What you need to do is set the envelope to 'sent' status instead of 'created'(env.Status="sent"). This will start the workflow and allow the recipient specified to edit the envelope as you're looking for. It's important to note that this will then continue along in the workflow after that recipient has finished their action on the envelope.
If you're looking for collaboration on an envelope and it's going to be going back and forth a bit before you actually want it signed, you might want to check out DocuSigns markup feature.

Docusign API - Self Signing

We have a requirement where we need to make a couple of PDF forms available using a HTML link to users for signing, but the signer should be a self-signer. In other words, once the signer completes signing using Docusign, they should be able to download the signed documents. However, we as the sender if the HTML link don't want to receive these saved documents as they have Personally Identifiable Information. The signer will upload these documents separately into our application at a later point.
I searched, but couldn't find a way to generate a HTML link for a self-signer. I was able to create a prototype that works for a regular signer, but not for a self-signer.
Any help would be much appreciated. Here's my code right snippet now:
// specify the document we want signed
string SignTest1File = #"C:\Users\skosuri.AA\Desktop\of0306.pdf";
string SignTest2File = #"C:\Users\skosuri.AA\Desktop\epa-credit-release-authorization.pdf";
// Enter recipient (signer) name and email address
string recipientName = "Chris";
string recipientEmail = "xxx.xxx#epa.gov";
// instantiate api client with appropriate environment (for production change to www.docusign.net/restapi)
string basePath = "https://demo.docusign.net/restapi";
// instantiate a new api client
ApiClient apiClient = new ApiClient(basePath);
// set client in global config so we don't need to pass it to each API object
Configuration.Default.ApiClient = apiClient;
string authHeader = "{\"Username\":\"" + Username + "\", \"Password\":\"" + Password + "\", \"IntegratorKey\":\"" + IntegratorKey + "\"}";
Configuration.Default.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
// we will retrieve this from the login() results
string accountId = null;
// the authentication api uses the apiClient (and X-DocuSign-Authentication header) that are set in Configuration object
AuthenticationApi authApi = new AuthenticationApi();
LoginInformation loginInfo = authApi.Login();
// user might be a member of multiple accounts
accountId = loginInfo.LoginAccounts[0].AccountId;
Console.WriteLine("LoginInformation: {0}", loginInfo.ToJson());
// Read a file from disk to use as a document
byte[] fileBytes = File.ReadAllBytes(SignTest1File);
byte[] fileBytes2 = File.ReadAllBytes(SignTest2File);
EnvelopeDefinition envDef = new EnvelopeDefinition();
envDef.EmailSubject = "Please complete and sign these documents";
// Add a document to the envelope
Document doc = new Document();
doc.DocumentBase64 = System.Convert.ToBase64String(fileBytes);
doc.Name = "of0306.pdf";
doc.DocumentId = "1";
doc.TransformPdfFields = "true";
envDef.Documents = new List<Document>();
envDef.Documents.Add(doc);
// Add a second document to the envelope
Document doc2 = new Document();
doc2.DocumentBase64 = System.Convert.ToBase64String(fileBytes2);
doc2.Name = "epa-credit-release-authorization.pdf";
doc2.DocumentId = "2";
doc2.TransformPdfFields = "true";
envDef.Documents.Add(doc2);
// Add a recipient to sign the documeent
Signer signer = new Signer();
signer.Name = recipientName;
signer.Email = recipientEmail;
signer.RecipientId = "1";
signer.DefaultRecipient = "true";
// must set |clientUserId| to embed the recipient
signer.ClientUserId = "1234";
// Create a |SignHere| tab on the document for the recipient to sign
signer.Tabs = new Tabs();
signer.Tabs.SignHereTabs = new List<SignHere>();
signer.Tabs.DateSignedTabs = new List<DateSigned>();
signer.Tabs.FullNameTabs = new List<FullName>();
SignHere signHere = new SignHere();
signHere.AnchorString = "Applicant's Signature:";
signHere.AnchorXOffset = "1.5";
signHere.AnchorYOffset = "0";
signHere.AnchorIgnoreIfNotPresent = "false";
signHere.AnchorUnits = "inches";
signHere.DocumentId = "1";
signHere.RecipientId = "1";
signer.Tabs.SignHereTabs.Add(signHere);
DateSigned ds = new DateSigned();
ds.PageNumber = "3";
ds.XPosition = "380";
ds.YPosition = "550";
ds.DocumentId = "1";
ds.RecipientId = "1";
ds.TabLabel = "Date Signed";
signer.Tabs.DateSignedTabs.Add(ds);
// Create a |SignHere| tab on the second document for the recipient to sign
SignHere signHere2 = new SignHere();
signHere2.PageNumber = "1";
signHere2.XPosition = "80";
signHere2.YPosition = "375";
signHere2.DocumentId = "2";
signHere2.RecipientId = "1";
signer.Tabs.SignHereTabs.Add(signHere2);
FullName fn = new FullName();
fn.PageNumber = "1";
fn.XPosition = "80";
fn.YPosition = "300";
fn.DocumentId = "2";
fn.RecipientId = "1";
signer.Tabs.FullNameTabs.Add(fn);
DateSigned ds2 = new DateSigned();
ds2.PageNumber = "1";
ds2.XPosition = "80";
ds2.YPosition = "475";
ds2.DocumentId = "2";
ds2.RecipientId = "1";
signer.Tabs.DateSignedTabs.Add(ds2);
envDef.Recipients = new Recipients();
envDef.Recipients.Signers = new List<Signer>();
envDef.Recipients.Signers.Add(signer);
// set envelope status to "sent" to immediately send the signature request
envDef.Status = "sent";
// Use the EnvelopesApi to create and send the signature request
EnvelopesApi envelopesApi = new EnvelopesApi();
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(accountId, envDef);
Console.WriteLine("EnvelopeSummary:\n{0}", JsonConvert.SerializeObject(envelopeSummary));
RecipientViewRequest viewOptions = new RecipientViewRequest()
{
ReturnUrl = "https://www.epa.gov",
ClientUserId = "1234", // must match clientUserId set in step #2!
AuthenticationMethod = "email",
UserName = recipientName,
Email = recipientEmail
};
// create the recipient view (aka signing URL)
ViewUrl recipientView = envelopesApi.CreateRecipientView(accountId, envelopeSummary.EnvelopeId, viewOptions);
// print the JSON response
Console.WriteLine("ViewUrl:\n{0}", JsonConvert.SerializeObject(recipientView));
// Start the embedded signing session!
System.Diagnostics.Process.Start(recipientView.Url);
I don't quite understand your question.
Your app can use a "system user" (an email account such as "noreply#company.com") as the sender and present an embedded signing request to the "self-signer."
That way the "self-signer" can fill in the information and sign.
The signed document will only be visible (via DocuSign) to the system user. You can also set up a purge policy.
But it is not a friendly user experience to ask that the
signer will upload these documents separately into our application at a later point.
Instead, I suggest that you check out the concealValueOnDocument parameter of the text (data) tab.
Docs:
When set to true, the field appears normally while the recipient is adding or modifying the information in the field, but the data is not visible (the characters are hidden by asterisks) to any other signer or the sender.
When an envelope is completed the information is available to the sender through the Form Data link in the DocuSign Console.
This setting applies only to text boxes and does not affect list boxes, radio buttons, or check boxes.
Using this setting enables the signer to see the PII when they sign, but the information is not visible to subsequent signers or viewers of the information.
The PII data is still available via the API so your integration can process it as necessary.

Resources