From the Trenches: Working with authoritative copies using Docusign APIs
Learn how to set authoritative copy flags in both the eSignature REST and SOAP APIs to manage their creation and vaulting.
An authoritative copy is the single, distinct, absolute original version of a document that is unique, identifiable, and unalterable without detection. Note that since all electronic files are “copies” and don’t intrinsically have a uniqueness property, authoritative copy requires the application of management and control processes. Within Docusign, you can specify whether all or just specific documents in an envelope are covered by the authoritative copy controls. Whether a document is considered an authoritative copy depends on the values of three properties in the envelope
and document
objects. The overall process, referred to as envelope vaulting, is a series of actions that lead to control of an authoritative document being transferred away from an eSignature provider to an outside party.
This system is ideal for when contract documents themselves have a tangible value. For example, a loan document or other form of chattel paper may require the owner to maintain an authoritative copy control or transfer when selling their interest in the loan to another party.
What are the primary differences in Authoritative Copy between the eSignature REST vs. SOAP APIs?
Within the Docusign platform, our Authoritative Copy APIs work on a combination of two platforms, depending on the Authoritative operations in use. Both the eSignature SOAP and REST APIs support specifying authoritative copy controls on envelope documents. However, only the SOAP API provides operations necessary for exporting Authoritative Copy-controlled documents out of Docusign control.
The primary operations and attributes per API are:
eSignature SOAP API:
Authoritative Copy in SOAP requires two features to be enabled for your account. The first is called Auto Authoritative Copy. This feature is meant to automatically enable envelopes for Authoritative Copy by flagging all outgoing envelopes and associated documents as authoritative. The second, Can Export Authoritative Copies, is an individual user permission to allow export of authoritative documents.
eSignature REST API v2.1
To enable Authoritative Copy at the envelope level, set the authoritativeCopy
flag to true
and flag individual documents for Authoritative Copy.
Parameters | Description |
---|---|
Envelope: | Enables or disables the feature. If this value is |
Envelope: | The default value assigned to a document once Authoritative Copy has been enabled at the envelope level. |
Document: | Used to flag individual documents for Authoritative Copy. |
In this chart, you can see how the Authoritative Copy system should behave when combining these parameters.
Envelope creation:
The following JSON body is an example of how to construct an envelope flagged for Authoritative Copy. Note that the authoritativeCopy
and authoritativeCopyDefault
flags are all at the top level of the JSON payload. The third flag, authoritativeCopy
, which enables you to target specific documents within an envelope for export, is handled at the individual document level. Please note that the Authoritative Copy system will not engage until the envelope has entered a completed
status.
{
"authoritativeCopy":"true",
"authoritativeCopyDefault":"true",
"documents": [
{
"authoritativeCopy":"true",
"documentBase64": "JVBER...jMxMzA2MgolJUVPRg==",
"documentId": "1",
"fileExtension": "pdf",
"name": "BaseDocument.pdf",
"order": "1"
},
{
"authoritativeCopy":"true",
"documentBase64": "JVBER...jMxMzA2MgolJUVPRg==",
"documentId": "2",
"fileExtension": "pdf",
"name": "BaseDocument2.pdf",
"order": "2"
}
],
"emailBlurb": "AuthoritativeCopy Test",
"emailSubject": "AuthoritativeCopy Test",
"recipients": {
"signers": [
{
"email": "user@example.com",
"name": "Matt K",
"recipientId": 1,
"routingOrder": "1",
"tabs": {
"signHereTabs": [
{
"pageNumber": "1",
"recipientId": "1",
"documentId":"1",
"tabLabel": "Example Tab",
"xPosition": 0,
"yPosition": 0
}
]
}
}
]
},
"status": "sent"
}
Now that you have the envelope created, let’s take a moment to discuss options for managing these envelopes. You may want to check the current Authoritative Copy status, or update an individual document you did, or did not, intend to flag as authoritative. Docusign’s eSignature REST API does have options to check and update unlocked envelope documents while they are currently in flight.
Checking authoritative copy status on the fly
The individual document flags are the only method presently available to verify documents have been flagged for Authoritative Copy. Note that in the general envelope details and metadata, this parameter is not included.
Action:
GET ../v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents
{
"envelopeId": "20f96145-xxxx-xxxx-xxxx-c9b42fa9774d",
"envelopeDocuments": [
{
"documentId": "1",
"documentIdGuid": "d2267a23-xxxx-xxxx-xxxx-64bc4d594a70",
"name": "BaseDocument.pdf",
"type": "content",
"uri": "/envelopes/20f96145-xxxx-xxxx-xxxx-c9b42fa9774d/documents/1",
"order": "1",
"pages": " ",
"availableDocumentTypes": "",
"display": "inline",
"includeInDownload": "true",
"signerMustAcknowledge": "no_interaction",
"templateRequired": "false",
"authoritativeCopy": "false"
},
{
"documentId": "2",
"documentIdGuid": "f6bf6d5c-xxxx-xxxx-xxxx-b11c72e6402d",
"name": "BaseDocument2.pdf",
"type": "content",
"uri": "/envelopes/20f96145-xxxx-xxxx-xxxx-c9b42fa9774d/documents/2",
"order": "2",
"pages": " ",
"availableDocumentTypes": "",
"display": "inline",
"includeInDownload": "true",
"signerMustAcknowledge": "no_interaction",
"templateRequired": "false",
"authoritativeCopy": "true"
}
]
}
You can see in this example that one of the documents has been flagged for export, but not both. In theory, let’s say that I did not intend to flag it this way and I actually wanted both documents to be vaulted. Now what can I do?
If the envelope has already been locked or completed, unfortunately there isn’t much that you can do. However, the authoritativeCopy
flag can still be toggled as long as the envelope is in either a created
or sent
status. All other statuses will return an error message.
Update Authoritative Copy status on the fly
Action:
PUT //accountId/envelopes/{envelopeId}/documents
{
"documents": [
{
"name": "DocName.pdf",
"order": 1,
"display": "inline",
"documentId": "1",
"authoritativeCopy": true
}
]
}
Response:
{
"envelopeId": "{ENVELOPEID}",
"envelopeDocuments": [
{
"documentId": "1",
"documentIdGuid": "203c9db5-xxxx-xxxx-xxxx-868de3db3d9f",
"name": "DocName.pdf",
"uri": "/envelopes/{ENVELOPEID}/documents/1",
"order": "1",
"templateRequired": "false",
"authoritativeCopy": "true"
}
]
}
Exporting an authoritative copy
How you export an authoritative copy depends on whether you’re using the eOriginal connector or an API call.
If using the eOriginal connector
The eOriginal connector is a premium connector that facilitates the authoritative copy export process and allows for envelopes to be flagged individually. The eOriginal Connector is an all-or-nothing export, similar to our older SOAP models, and operates in the following way:
Add an envelope custom field called “Vault with eOriginal” to your envelope.
The field must be a list field with values “Yes;No”
When an envelope is processed through Docusign Connect, the eOriginal Connector checks for the existence of this field. If the value is set to “no”, no vaulting is attempted. If set to “yes”, the envelope is automatically vaulted.
For more information on this Connector and setup, see the Support article How to set up eOriginal vaulting as optional on envelopes.
If using the Docusign APIs
All authoritative copy exports done without the eOriginal Connector use a combination of the same three API calls. Please note that all authoritative export calls must be authenticated and placed through our eSignature SOAP API. Presently there is no direct export option available in the REST APIs.
Below you can see an outline of the required headers, call body, and endpoint to use.
Required parameters | Description |
---|---|
| The Application Password for the authenticated user. An Application Password can be generated by visiting the user’s profile with DocuSign.com and navigating to the Privacy and Security section. |
| The email address of the user you’re authenticating as. |
| GUID value of the integration key your system is using to authenticate. |
| Security tokens require the created and expired timestamp in ZULU. |
Action:
POST https://{baseUrl}.docusign.net/api/3.0/api.asmx OR https://{baseUrl}.docusign.net/api/3.0/dsapi.asmx
Note: Your integration may already be using one of our SOAP endpoints. Docusign offers two primary SOAP endpoints that handle (mostly) the same SOAP actions: api.asmx and dsapi.asmx.
There are two primary differences between the api.asmx and dsapi.asmx endpoints: api.asmx uses the WSS UserName token supplied within the API call definitions, the dsapi.asmx endpoint uses the X-Docusign-Authentication header. For availability of information, I’ll supply both below.
Be sure to also note the transactionId
and PDFBytes
returned, as they will be required for the next step.
Headers:
Key | Value |
---|---|
A |
|
|
|
|
|
|
|
Example body:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
<u:Timestamp u:Id="_0">
<u:Created>2024-01-17T16:36:53Z</u:Created>
<u:Expires>2024-01-17T18:36:53Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-7ee6ff31-bc85-41fb-8eac-1a64972c8cbc-54">
<o:Username>[{INTEGRATORKEY}]{EMAIL}</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">{APPLICATION PASSWORD}</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<ExportAuthoritativeCopy xmlns="http://www.docusign.net/API/3.0">
<EnvelopeId>{ENVELOPEID}</EnvelopeId>
</ExportAuthoritativeCopy>
</s:Body>
</s:Envelope>
Successful response:
<?xml version="1.0" encoding="utf-8"?>
… …
<soap:Body>
<ExportAuthoritativeCopyResponse xmlns="http://www.docusign.net/API/3.0">
<ExportAuthoritativeCopyResult>
<EnvelopeId>{ENVELOPEID}</EnvelopeId>
<TransactionId>70825e90-xxxx-xxxx-xxxx-5fe0bb6456e5</TransactionId>
<Count>2</Count>
<DocumentPDF>
<Name>BaseDocument.pdf</Name> <PDFBytes>xFEimX0iyJM9VytxCBzild681r6...C9YvyaGJhdDw8JiBw==</PDFBytes>
</DocumentPDF>
<DocumentPDF>
<Name>Summary</Name>
<PDFBytes>thq/jN0b9wxl+vxnL2gU3cWldfv...XsX4MROGzY1FeLF3/xR</PDFBytes>
</DocumentPDF>
</ExportAuthoritativeCopyResult>
</ExportAuthoritativeCopyResponse>
</soap:Body>
Now that you have your transaction IDs, you can move on to the next step, which is to compute a checksum of the returned documents. Note that the returned documents are in an archive format and are initially encrypted. The Authoritative Copy process calls to assemble the PDFBytes
are sent back into a byte array and used to create a checksum. Once you have this, you send the TransactionId
and Checksum back to Docusign to acknowledge the authoritative copy export.
Computing the checksum
The portion related to checksum computation can be tricky. I’ll outline the process and take you through it step by step. Note that the checksum uses standard SHA1 cryptography to hash the contents of the previous API response.
Taking from the response in from the previous step, you should now have your
PDFbytes
, which are Base64-encoded, and atransactionId
.Take both
PDFbyte
strings, convert them into a byte array, then append them in order.For example, here we have a document and a Certificate of Completion. If the converted values for the document are ‘abc’ and the converted values for the Certificate of Completion are ‘def’, the string that you apply your hash to is going to be ‘abcdef.’
Once you have the hash, you convert it back into a Base64 string and add it to your API call. An example of the final hash would be: VSxEWfUxnng+hi6CZpeZkSUEmT4=.
Thanks and credit to my colleague, Renan Araujo, for supplying a Node script for accomplishing this quite easily.
var CryptoJS = require("crypto-js");
var document1 = "<documentpdfbytes>";
var coc = "<certificatepdfbytes>";
// CryptoJS
var parseB64 = CryptoJS.enc.Base64.parse(document1);
parseB64.concat(CryptoJS.enc.Base64.parse(coc));
var shaB64 = CryptoJS.SHA1(parseB64);
console.log("->", shaB64.toString(CryptoJS.enc.Base64));
</certificatepdfbytes></documentpdfbytes>
Headers:
Key | Value |
---|---|
Accept |
|
|
|
|
|
|
|
Example body:
<?xml version="1.0" encoding="utf-8"?><envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><header><security s:mustunderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><timestamp u:id="_0"><created>2024-01-17T16:36:53Z</created><expires>2024-01-17T18:36:53Z</expires></timestamp><usernametoken u:id="uuid-7ee6ff31-bc85-41fb-8eac-1a64972c8cbc-54"><username>[{INTEGRATORKEY}]{EMAIL}</username><password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">{APPLICATION PASSWORD}</password></usernametoken></security></header><body><acknowledgeauthoritativecopyexport xmlns="http://www.docusign.net/API/3.0"><envelopeid>01026f8b-5573-xxxx-xxxx-4ec1c87bddf5</envelopeid><transactionid>f24ebb1f-603b-xxxx-xxxx-ac6d6491294f</transactionid><checksumhash>VSxEWfUxnng+hi6CZpeZkSUEmT4=</checksumhash></acknowledgeauthoritativecopyexport></body>
</envelope>
Successful response:
<?xml version="1.0" encoding="utf-8"?>
… …
<body><acknowledgeauthoritativecopyexportresponse xmlns="http://www.docusign.net/API/3.0"><acknowledgeauthoritativecopyexportresult><authoritativecopyexportsuccess>true</authoritativecopyexportsuccess><envelopeid>01026f8b-5573-xxxx-xxxx-4ec1c87bddf5</envelopeid><exportkey>faa3ad7d7d744ee0
<exportkey><acknowledgeauthoritativecopyexportresult></acknowledgeauthoritativecopyexportresult></exportkey></exportkey></acknowledgeauthoritativecopyexportresult></acknowledgeauthoritativecopyexportresponse></body>
… …
Decrypt the document archive
Finally, you have your ExportKey
. The last step is to decrypt the document archive. Docusign encrypts the document archive using a Rijndael encryption method based on a private key with the parameters listed below. You can decrypt the archive using a dedicated Rijndael or AES-128 library, making sure your decryption call has:
Mode as CBC
Padding as PKCS7
Key size as 128 bits
Block size as 128 bits (this size is fixed for the AES method)
// Node.js
var exportKey = "13ff00ec18fcaad1"; //
<p>Rijndael has a number of dependencies in various languages to help you decrypt these documents. For considerations of space, I cannot show examples in multiple languages in this guide. Now that you have everything decrypted, you should have access to your exported copy. </p>
<p><strong>Notes:</strong></p>
<ol><li>During this process, you may encounter watermarks. One will be present in the Demo environment by default, another one will be related to authoritative copy status. Depending on the status of the document, you may see “Authoritative”, or “Copy” watermarked on the envelope. This is to be expected. As for the demo watermark, it will be removed automatically when you move your account into your production environment. </li>
<li>The individual user permission, ‘Can Export Authoritative Documents,’ for exporting authoritative copies still needs to be enabled at the <em>user</em> level. </li>
<li>The account level permission, ‘Auto Export Authoritative Copy,’ is meant to automatically flag envelopes and envelope documents for Authoritative Copy by default.</li>
<li>After acknowledging the Authoritative copy, if the transaction ID, envelope ID, and checksum all agree with the actual envelope and documents, a decryption key is sent back. At this point, <em>the envelope can no longer be exported from the Docusign platform:</em> any attempts to download it will result in an envelope with a “Copy” watermark displayed. Be sure to include robust error handling during the process that logs decryption information until it’s successfully processed. If a document reaches this state, Docusign Support <em>cannot</em> help you recover the document, as we no longer are the Authoritative source for the agreement.</li>
</ol><h2>Additional resources</h2>
<ul><li><a href="https://developers.docusign.com/">Docusign Developer Center</a></li>
<li><a href="https://twitter.com/docusignapi">@DocuSignAPI on X</a></li>
<li><a href="https://www.linkedin.com/showcase/docusign-for-developers/">Docusign for Developers on LinkedIn</a></li>
<li><a href="https://www.youtube.com/playlist?list=PLXpRTgmbu4opxdx2IThm4pDYS8tIKEb0w">Docusign for Developers on YouTube</a></li>
<li><a href="https://developers.docusign.com/#newsletter-signup">Docusign Developer Newsletter</a></li>
</ul>
Rijndael has a number of dependencies in various languages to help you decrypt these documents. For considerations of space, I cannot show examples in multiple languages in this guide. Now that you have everything decrypted, you should have access to your exported copy.
Notes:
During this process, you may encounter watermarks. One will be present in the Demo environment by default, another one will be related to authoritative copy status. Depending on the status of the document, you may see “Authoritative”, or “Copy” watermarked on the envelope. This is to be expected. As for the demo watermark, it will be removed automatically when you move your account into your production environment.
The individual user permission, ‘Can Export Authoritative Documents,’ for exporting authoritative copies still needs to be enabled at the user level.
The account level permission, ‘Auto Export Authoritative Copy,’ is meant to automatically flag envelopes and envelope documents for Authoritative Copy by default.
After acknowledging the Authoritative copy, if the transaction ID, envelope ID, and checksum all agree with the actual envelope and documents, a decryption key is sent back. At this point, the envelope can no longer be exported from the DocuSign platform: any attempts to download it will result in an envelope with a “Copy” watermark displayed. Be sure to include robust error handling during the process that logs decryption information until it’s successfully processed. If a document reaches this state, DocuSign Support cannot help you recover the document, as we no longer are the Authoritative source for the agreement.
FAQ
Q: When acknowledging an authoritative copy, I receive an error indicating the file size specified does not match exported file size. What can cause this?
A: When acknowledging an authoritative copy, the general cause for this will be a misstep in creating your hash string. Please run through the process again. If you’re having trouble, feel free to reach out to Customer Support. I or someone from my team would be happy to assist you.
Q: All of my envelope documents are being flagged for Authoritative Copy and I can see this registered in my getDocument
responses; However, the export action is indicating that my envelope is *not* flagged for Authoritative Copy.
A: Docusign REST APIs for Authoritative Copy allow you to flag individual documents. However, the top, envelope-level authoritativeCopy
flag must be set to true
in order for the system to engage. If a null
or other value is supplied aside from true
, your envelope will register as non-authoritative when attempting to export it.
Docusign accounts have an all-or-nothing account level switch that must be toggled by Customer Support. This feature is called “Auto-Authoritative Copy.” This results in all envelopes sent by the account being flagged as Authoritative.
Q: I’m seeing some inconsistencies with my envelope's Authoritative Copy status. Some appear to be honoring individual authoritativeCopy flags, but envelopes not set to be authoritative are being marked as authoritative anyway.
A: This likely has to do with either the position of your parameters in the createEnvelope
request, or your account may have been flagged for auto-Authoritative Copy.
Accounts configured for auto-authoritative copy will automatically flag all of your envelope documents for export. If you’re not supplying envelope-specific flags to override this, the auto-authoritative copy feature will flag them for export anway.
When engaging the Authoritative Copy system within Docusign, the envelope authoritativeCopy
flag is at the top level and enables the system. The authoritativeCopyDefault
flag sets the default flag for a document and is placed alongside authoritativeCopy
. The third flag is also authoritativeCopy
; this flag is included in document definitions alongside the documentName
and Base64
/ HTMLSource
objects.
Structural example:
{
"authoritativeCopy":"true",
"authoritativeCopyDefault":"true",
"documents": [
{
"authoritativeCopy":"true",
"documentBase64": "JVBERi0...PRg==",
"documentId": "1",
"fileExtension": "pdf",
"name": "BaseDocument.pdf",
"order": "1"
}
],
Q: I received an error message stating that my document is non-authoritative. I’ve checked the document details using the getDocument
method in this article and both are reading as authoritative: true
.
A: For the document to be exported, the envelope needs to both be in a completed
status and the top-level authoritativeCopy
flag for enabling Authoritative Copy for the document must be present. If it is not present, you will receive an error message stating that the document is non-authoritative.
Q: I’m receiving an error message for specific Docusign users when trying to export authoritative copies stating they don’t have permission.
A: Each user in a Docusign account has an individual permission profile applied to them. One of these user-level flags is to allow the export of authoritative copies. Ideally, you would want a specific group of users to have access to export your envelope; this is done through Docusign permission sets. If you run into any issues, please reach out to Customer Support so we can verify that all of the necessary flags and permissions are in place.
Q: Is there a way to export envelope documents flagged for Authoritative Copy via the Docusign REST APIs?
A: No, the only present option available within Docusign is to use the eSignature SOAP API.
Q: I’m attempting to export a document flagged for Authoritative Copy but am receiving an error indicating the timestamp is invalid.
A: This is likely due to the timestamps provided in your security token. In the response we send back there will be three elements: a FaultString
, Timestamp
and a Creation
event for the return message.
FaultString:
“Message Expired --->WSE066: Timestamp is expired. This indicates a stale message but may also be caused by lack of synchronization between sender and receiver clocks. Make sure the clocks are synchronized or use the timeToleranceInSeconds element in the microsoft.web.services3 configuration section to adjust tolerance for lack of clock synchronization”
Timestamp:
<wsu:Timestamp wsu:Id="Timestamp-544c2f52-1fe6-4f21-8617-261ec623a3ff">
<wsu:Created>
2024-01-17T19:12:30Z
</wsu:Created>
<wsu:Expires>
2024-01-17T19:17:30Z
</wsu:Expires>
</wsu:Timestamp>
These timestamps are the present timestamps in UTC. You can check the timestamp you’re providing in your SOAP request vs. the one returned to Docusign. This shows you the difference between a functional and non-functional timestamp, enabling you to determine what kind of offset you’re going to need so the timestamps line up.
For example, if my creation request has a Timestamp of
<wsu:Created>
2024-01-17T18:12:30Z
</wsu:Created>
<wsu:Expires>
2024-01-17T18:17:30Z
</wsu:Expires>
And the return message has a Timestamp of
<wsu:Created>
2024-01-17T19:12:30Z
</wsu:Created>
<wsu:Expires>
2024-01-17T19:17:30Z
</wsu:Expires>
I can see that the one I’m providing is one hour off. Once I correct this or add an hourly offset, the call processes as expected.
Additional resources
Matt King is a senior member of the Developer Support team and has been with Docusign for about 5 years. He specializes in assisting customers with our various APIs, SDKs, and code examples.
Related posts