Basics
When a signature request is created using the API, the workflow followed by signers can be highly customized, including:
- the branding, the content and the type of emails sent to signers
- the signature page on which the signers are redirected
- the branding of the Signature attestation document
The minimal/simplest signature workflow is the following:
- An email asking to sign the document is sent to each signer by the Woleet platform. This email includes a link redirecting the signer to a signature page.
- The signer reads the email, clicks on the link and is redirected to a signature page.
- The signature page eventually signs the document by delegating the signature to the Woleet backend (the signer authentication is done using a secret identifier included in the redirection link)
The default signature workflow sends more emails (see below for a full description) but all additional emails can be disabled or customized.
Note that although emails are always sent by the Woleet platform, the email and the name of the sender can also be customized.
The default email asking to sign the document redirects signers to a default signature page hosted by the Woleet platform. However, the redirection can be easily modified to redirect to a custom signature page. Since implementing a custom signature page is straightforward (it can be as simple as one POST call) it is easy to implement a fully customized signature workflow.
List of email types
Here is the list of all email types sent by the Woleet platform when using the default signature workflow:
Type | Purpose | Comment | Identifier |
---|---|---|---|
Signature request to signer | Sent to the signer when the signature request is activated (ie. its state is IN_PROGRESS) | Mandatory: cannot be disabled Must provide a link to a signature page including the secret identifier of the signer | signatureRequestSigneeEmail |
Signature reminder to signer | Send to the signer 3 days after the signature request if the signer has not signed yet | signatureReminderSigneeEmail | |
Signature canceled to signer | Sent to the signer when the signature request is canceled. (ie. its state is CANCELED) | signatureCanceledSigneeEmail | |
Signature closed to signer | Sent to the signer when the signature request is closed. (ie. its stated is CLOSED). | signatureClosedSigneeEmail | |
Signature confirmation to signer | Sent to the signer right after he signs the document | Can provide a link to the "Signature verification" page | signatureConfirmedSigneeEmail |
Signature confirmation to requester | Sent to the requester right after each signature | Not sent if the requester is also the signer (same email) Can provide a link to the "Signature verification" page | signatureConfirmedRequesterEmail |
Signature feedback to requester | Sent to the requester if a signee reports some feedback about the signature request | Mandatory: cannot be disabled | signatureFeedbackRequesterEmail |
Signature proof to signer | Sent to the signer when his signature proof is ready | The signature proof is provided as an attachement | signatureProofConfirmedSigneeEmail |
Signature attestation | Sent to the requester and the signers when the signature request is completed or closed and the proof of signature of its audit trail by Woleet is ready | The "Signature attestation" PDF document is provided as an attachement | signatureAttestationEmail |
Templating engine
Each type of email has a default template. The Woleet platform uses Velocity Engine 2.3 as template engine.
Default templates are made of HTML content using Velocity Template Language annotations and can be overwritten by custom templates.
Custom templates can also use Velocity Template Language annotations.
Customize the workflow
The default signature workflow can be customized using the vars
property of the signature request. This property can be used to store a set of variables as key/value pairs. These variables can be used to:
- disable some email types
- provide custom templates for some email types
- brand the Signature attestation document
- define or overwrite variables used by templates
Templates have access to a set of predefined variables depending on the type of email (eg. requesterName
) plus to all variables defined at signature request level using the vars
property. Variables defined at signature request level overwrite predefined ones, and can themselves be overwritten by variables defined at signer level.
Disable some email types
To disable a given email type, set a {email type identifier}Disabled
boolean variable to true
:
{
...
"vars": {
"signatureProofConfirmedSigneeEmailDisabled": true,
"signatureConfirmedSigneeEmailDisabled": true
}
}
Note that all email types but signatureRequestSigneeEmail
and signatureFeedbackRequesterEmail
can be deactivated.
Provide custom templates for some email types
To provide a custom template for a given email type, store the template of the content of the email in the {email type identifier}ContentTemplate
string variable, and the template of the subject of the email in the {email type identifier}SubjectTemplate
string variable:
{
...
"vars": {
"signatureRequestSigneeEmailSubjectTemplate": "Please sign '$fileName'"
"signatureRequestSigneeEmailContentTemplate": "Hi, Please sign '$fileName' at <a href=\"https://sign.acme.com/?signatureRequestURL=$tools.urlEncode($signatureRequestURL)\">Sign</a>"
}
}
Customize the Signature attestation document
At the very end of the signature workflow (ie. when the signature request is CLOSED or COMPLETED) the Signature attestation document (a PDF file) is by default sent by email to all signees.
The template used to generate this document cannot be customized yet, but uses variables allowing to "brand" the document by overwriting their default value:
Name | Purpose |
---|---|
brandColor1 | Main brand color of the service |
brandColor2 | Alternate brand color of the service |
textColor1 | Main text color of the service |
textColor2 | Alternate text color of the service |
serviceName | Name of the service |
serviceEmail | Email of the service |
serviceURL | URL of the service |
serviceLogoURL | URL of the logo of the service |
serviceIllustrationURL | URL of the illustration of the service |
serviceContactEmail | Contact email of the service |
serviceDocumentationURL | URL of the documentation of the service |
serviceAddress | Postal address of the service |
Define or overwrite variables used by templates
Some variable are predefined and can be used in various templates.
To overwrite a predefined variable, simply define a variable with the same name at signature request level:
{
...
"vars": {
"serviceName": "ACME Sign",
"requesterName": "ACME Corp."
}
}
List of predefined variables
Here is the list of all predefined variables that can be used in email templates:
Name | Purpose | Comment |
---|---|---|
lang | Language to use in the email (as an ISO639-1 string). | Computed from the signature request's lang properties: currently, since only en or fr are supported by default templates, it is always fallbacks to one of these values, except if overwritten in vars . |
requesterName | Name of the signature requester. | Defaults to "{first name} {last name}" of the account creating the signature request. |
requesterEmail | Email of the signature requester. | Defaults to the email of the account creating the signature request. |
signeeName | Name of the signer (eg. John Doe) | Defaults to the commonName property of the signer. |
signeeEmail | Email of the signer | |
isRequester | true if the signer is also the requester of the signature. | |
signatureRequestURL | URL of the signature request, including the secret identifier of the signer as a request parameter. | Intended to be provided to the signature page, allowing it to authenticate as the signer to retrieve and/or sign the signature request. Defaults to https://api.woleet.io/v1/signatureRequest/{signatureRequestId}?signeeId={signeeId} . |
signeeId | Secret identifier of the signer (required to authenticated as the signer to retrieve and/or sign the signature request). | |
requiresOTP | true if an SMS OTP is required for the signer to sign. | If true the signature page needs to request the platform to send an OTP to the signer, and needs to provide this OTP to sign. |
signingURL | URL of the default signature page (without the signatureRequestURL parameter). | As an example, the default signatureRequestSigneeEmail template builds a Sign button redirecting to $signingURL?signatureRequestURL=$tools.urlEncode($signatureRequestURL) |
signatureRequestId | Identifier of the signature request. | |
signatureRequestName | Name of the signature request. | |
signatureRequestSharingURL | URL of the signature request's sharing page. | This page can be used by anybody having the URL to: - follow the state of the signature request - verify all signatures - download the signature proofs - download the Signature attestation PDF document (if available). |
documentName | Name of the document to sign. | Equals to fileName if set, or equals to signatureRequestName |
fileName | Name of the file to sign. | If set in the signature request. |
fileURL | URL of the data to sign (if set). | If set in the signature request. |
serviceName | Name of the service managing the signature request. This name is used as sender name for all emails and OTPs. | Defaults to "Woleet". |
serviceEmail | Email of the service managing the signature request. This email is used as sender email for all emails. | Defaults to "[email protected]". |
serviceURL | URL of the service managing the signature request. | Defaults to "app.wolelet.io". |
serviceLogoURL | URL of the logo of the service managing the signature request. | Defaults to Woleet's logo. |
serviceContactEmail | Contact email of the service managing the signature request. | Defaults to Woleet's contact email. |
serviceDocumentationURL | URL of the documentation of the service managing the signature request. | Defaults to Woleet's documentation. |
Utilities
You can use the tools.urlEncode
macro to URL encode any URL parameter:
<a href="$signingURL?signatureRequestURL=$tools.urlEncode($signatureRequestURL)">
#if($lang == "en")
Sign
#elseif($lang == "fr")
Signer
#end
</a>
Examples
Here is a sample curl
call creating a customized signature request:
- it disables all optional emails
- it provides a custom template for email sent to signers
- the custom template provides the name and a link to the file to sign to the signer, so that he can download it
- it redirects the signer to a custom signature page using a
srURL
argument to retrieve the signature request URL - it overwrites the name of the requester to "ACME Corp. legal dept."
- it uses "ACME Corp." and "[email protected]" as the sender name and email for all emails sent
curl -u {login}:{password} -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
"name": "ACME Corp. Terms and Conditions",
"vars": {
"serviceName": "ACME Corp.",
"serviceEmail": "[email protected]",
"requesterName": "ACME Corp. legal dept.",
"signatureConfirmedSigneeEmailDisabled": true,
"signatureConfirmedRequesterEmailDisabled": true,
"signatureProofConfirmedSigneeEmailDisabled": true,
"signatureAttestationEmailDisabled": true,
"signatureRequestSigneeEmailSubjectTemplate": "Please sign $fileName",
"signatureRequestSigneeEmailContentTemplate": "Hi $signeeName,<br>$requesterName invites you to sign <a href=\"$fileURL\">$fileName</a><br><a href=\"https://sign.acme.com/?srURL=$tools.urlEncode($signatureRequestURL)\">Sign</a>"
},
"hashToSign": "c8db8eaef2524d4c823d7b014214fda86f6480cc6d145f4c908cc01de37fb102",
"fileName": "ACME Corp. TCU",
"fileURL": "https://acme.com/privacy.html",
"authorizedSignees": [ { "commonName": "John Doe", "email": "[email protected]"} ]
}' 'https://api.woleet.io/v1/signatureRequest'
Customize the signature page
To customize the signature page, you need to host a new signature page on your own, and redirect signers to this page by overwriting the signingURL
variable, or by providing a custom template for the Signature request to signer email.
Here is a sample minimal HTML/Javascript code implementing a custom signature page:
<html>
<head>
<script>
// Get signature request URL parameter
var srURL = new URL(window.location.href).searchParams.get("srURL");
console.log("signature request URL: ", srURL);
// Get the signer secret identifier
var signeeId = new URL(srURL).searchParams.get("signeeId");
console.log("signer secret identifier: ", signeeId);
// Sign the signature request on behalf of the signer
function sign() {
// Build the delegate URL from the signature request URL
var delegateURL = new URL(srURL);
delegateURL = delegateURL.origin + delegateURL.pathname + "/delegate";
console.log("delegate URL: ", delegateURL);
// Call the delegate URL
var http = new XMLHttpRequest();
http.open('POST', delegateURL, true);
http.setRequestHeader('Content-type', 'application/json');
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
console.log("done");
}
}
http.send(JSON.stringify({ signeeId: signeeId }));
}
</script>
</head>
<body>
<button onclick="sign()">Sign</button>
</body>
</html>