
From the Trenches: How to use the Docusign CLM API to upload, download and version documents
Learn how the CLM API enables you to automate document updates and handoffs between stakeholders and maintain a single source of truth in Docusign CLM.

Consider a scenario in which your sales team needs the most recent master service agreement (MSA) template in Word for redlining, the legal department requires a PDF version for archiving, marketing needs to update a cover page image with a PNG file, and all of this needs to be done without leaving a CRM or other core business applications.
Docusign CLM’s Content API exposes endpoints you can use to automate these handoffs and maintain a single source of truth in Docusign CLM. The Content API allows you to upload, download, and version (check out/check in) document files from a Docusign CLM account.
Let’s look at the key API methods that make this possible, along with the HTTP headers and parameters you can use to customize the examples for your workflow.
CLM Content API endpoints
All document upload, download, and versioning operations live in the Docusign CLM Content API. The Content API’s base endpoint domain differs from the Object and Task API base domains, so be sure to confirm your account-specific endpoints in CLM under Admin › System Domains.
For CLM accounts that have migrated to Azure, the base URL has changed. Please refer to our support page for the latest Azure migration schedule and details.
Pre-migration
Upload:
https://apiupload{datacenter}.springcm.comDownload:
https://apidownload{datacenter}.springcm.com

Post-migration (Azure)
Upload and download:
Production:
https://api.{site}.{region}.clm.docusign.net/contentDeveloper:
https://api.{site}.{region}.clm.demo.docusign.net/content

You can see here that the post-migration URL is the same for both download and upload. For the examples in this article, we will use the post-migration Azure base URL.
Upload documents
For uploading documents, use the Content:Upload method. Start by deciding whether you’re sending a single file or multiple files, as the parameter requirements differ slightly. File size and content type can also matter if performance is a concern. For example, Base64 is usually fine for smaller payloads, but multipart/form-data or raw binary will be faster and more performant for larger uploads.
Here are some examples of how to configure your API requests for the Content:Upload method:
Single-part upload (Base64)
Request URL
POST: https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/folders/{folder_id}/documents?name=sample.docx
Request headers
Authorization: Bearer {access_token}
Content-Transfer-Encoding: base64
Request body (raw, text/plain)
<BASE64_FILE_STRING>
Single-part upload (binary)
Request URL
POST: https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/folders/{folder_id}/documents?name=sample.docx
Request headers
Authorization: Bearer {access_token}
Content-Type: application/octet-stream
Request body (binary)
--data-binary '@/path/to/sample.docx'
Multipart upload (one or many files)
Request URL
POST: https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/folders/{folder_id}/documents
Request headers
Authorization: Bearer {access_token}
Content-Type: multipart/form-data; boundary=------MyBoundary
Leave the Content-Type header empty if using Postman, as Postman will set it automatically at the time of the request.
Request body (form-data)
------MyBoundary
Content-Disposition: form-data; name="file"; filename="sample.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
<binary content of sample.docx>
------MyBoundary
Content-Disposition: form-data; name="file"; filename="example.pdf"
Content-Type: application/pdf
<binary content of example.pdf>
------MyBoundary--This Python code shows how to make a multipart/form-data request using Python’s Requests library. Python will automatically set the Content-Type header to multipart/form-data when using the files parameter in the request method:
import requests
url = f"https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/folders/{folder_id}/documents"
payload = {}
files=[
('documents',('DOCXSample.docx',open('./assets/DOCXSample.docx','rb'),'application/vnd.openxmlformats-officedocument.wordprocessingml.document')),
('documents',('PDFSample.pdf',open('./assets/PDFSample.pdf','rb'),'application/pdf'))
]
headers = {
'Authorization': 'bearer eyJ0eXAiOi...',
'Content-Disposition': 'form-data; name="file"; filename="filename"'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)A successful upload will result in an HTTP 201 Created response with the new document object (or an array for multipart).
We recommend previewing your uploaded documents to ensure that they render correctly in the CLM user interface. This is especially important for Word documents due to CLM’s conversion of DOCX files to PDF. You can use the PreviewUrl property from the API response to easily preview the document in your browser. If your document does not render in the preview and you see a We can't show a preview of this document message, this usually means that your request headers or body are misconfigured or the content type you are using is not supported.
Download documents
To download documents, use the Content:Get method, which is a GET request to a document by its document ID.
Request URL
GET: https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/documents/{document_id}
You can easily get this URL by referencing the DownloadDocumentHref property that is part of the document’s API object or the upload response.
You can control the format of the downloaded file by providing an Accept request header. The Accept header allows you to specify the format for your downloaded document Options include using the document’s native format, converting it to PDF, extracting the text through optical character recognition (OCR), and downloading the document as a PNG image. Here is a quick reference for these formats and the Accept header you should use:
Accept value | Result |
|---|---|
(none) or | Original file format |
| Server-generated PDF (if available) |
| OCR text |
| PNG image (first page only) |
Here is a Python example that shows how to download documents in PDF format:
import requests
account_id = "00000000-0000-0000-0000-7ecf158441c0"
document_id = "00000000-0000-0000-0000-0ea5bf7f1f2b"
url = f"https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/documents/{document_id}"
payload = {}
headers = {
'Authorization': 'bearer eyJ0eXAiOi...',
'Accept': 'application/pdf'
}
response = requests.request("GET", url, headers=headers, data=payload)Version documents
The last function of the Content API we will cover is document versioning, which involves checking out documents to prevent concurrent edits, making any updates needed to the checked-out document, and then checking the new document back in to save the new version in the version history.
Check out
To start, let’s lock or check out the document we want to update. To do this, you call the Documents:PostLock method. This method is part of the Object API and is a POST request to the document ID with an empty call body. Here are the details:
Request URL
POST: https://api.{site}.{region}.clm.docusign.net/v2/{account_id}/documents/{document_id}/lock
Request body (empty JSON object)
{}
A successful lock request will result in a 200 OK response, and the response body will look similar to the following:
{
"IsLocked": true,
"LockDate": "2025-10-31T17:17:59.193Z",
"Type": "CheckedOut",
"LockOwner": {
...
},
"CheckInHref": "https://api.s1.us.clm.docusign.net/content/v2/{account_id}/documents/{document_id}"
}The response properties include confirmation that the document is locked, data about the lock owner, and a CheckInHref, which can be used when we need to check the document back in. Locking the envelope in this manner will check out the document and prevent edits in the CLM UI and from other users; however, the lock owner can still upload new document versions to the CheckInHref without unlocking it first.
Upload new document version
That brings us to the next step, which is uploading the new document version. Using what we learned in the Upload documents section above, we can upload a new document version with the same single-document request headers, such as binary and Base64; however, this time we will use the Content:Post method instead of the Content:Upload method. Here are the details:
Request URL
POST: https://api.{site}.{region}.clm.docusign.net/content/v2/{account_id}/documents/{document_id}
Request headers
Authorization: Bearer {access_token}
Content-Type: application/octet-stream
Content-Disposition: binary; name="file"; filename="sample.docx"
Request body (binary)
--data-binary '@/path/to/sample.docx'
We are using the CheckInHref for the request URL, which differs from the upload document URL in that it does not contain the parent folder ID. We are uploading the new document directly to the document ID. A successful POST request to upload a new document version will result in a 201 Created response that will include "LockStatus": "CheckedOut" if the document is still checked out.
Check in
Once we are done with any edits and have uploaded the final version of the document, we can finally check the document back in by deleting the lock. To do this, we will call the Documents:DeleteLock method:
Request URL
DELETE: https://api.{site}.{region}.clm.docusign.net/v2/{account_id}/documents/{id}/lock
A successful lock deletion will result in a 200 OK response with a response body similar to the following:
{
"IsLocked": false,
"Type": "NotCheckedOut",
"CheckInHref": "https://api.s1.us.clm.docusign.net/content/v2/{account_id}/documents/{documentId}"
}Review version history
Now that we have some version history, we can make a GET request to Documents:GetVersions to get a list of all the document versions associated with the primary document ID. Each version of the document is given its own unique document ID that you can use to preview or download specific document versions. Here is a sample Documents:GetVersions response with some data redacted for brevity:
{
"Items": [
{
"Name": "Sample Document for Testing.docx",
"CreatedDate": "2025-11-04T15:10:25.78Z",
"UpdatedDate": "2025-11-21T17:24:33.06Z",
"Version": "3.0",
"PreviewUrl": ".....",
"DownloadDocumentHref": ".....",
"Uid": "e1d1cd1c-0000-0000-0000-995fe20249c7"
},
{
"Name": "Sample Document for Testing.pdf",
"CreatedDate": "2025-11-04T15:10:25.78Z",
"UpdatedDate": "2025-11-21T17:09:58.68Z",
"Version": "2.0",
"PreviewUrl": ".....",
"DownloadDocumentHref": ".....",
"Uid": "3f9eb7f0-0000-0000-0000-995fe20249c7"
},
{
"Name": "Sample Document for Testing.docx",
"CreatedDate": "2025-11-04T15:10:25.78Z",
"UpdatedDate": "2025-11-04T15:10:25.78Z",
"Version": "1.0",
"PreviewUrl": ".....",
"DownloadDocumentHref": ".....",
"Uid": "550d14e3-0000-0000-0000-995fe20249c7"
}
]
}Conclusion
With just a handful of API calls using the methods above, you can automate the handoffs and updates of your CLM documents. This includes uploading new files, retrieving documents in a specific format, and maintaining version control through check-out and check-in locks.
In addition to document management, the Docusign CLM API offers many other powerful methods and endpoints that you can use to interact with your CLM data, so head over to our Developer Center to learn more.
Additional resources
Learn how to authenticate with the CLM API.
See the Content API reference for details about the endpoints.
Review the CLM API rules and resource limits.
Steve DiCicco is an experienced support engineer who has been with Docusign since 2022. You can reach Steve on LinkedIn.
Related posts
Docusign IAM is the agreement platform your business needs



