Blog
Home/

Common API Tasks🐈: Locking and unlocking envelopes

Author Inbar Gazit
Inbar GazitSr. Manager, Developer Content
Summary3 min read

This blog series is focused on simple API tasks, yet useful pieces of functionality that can be accomplished using one of the Docusign APIs.

    • C#
    • Java
    • Node.js
    • PHP
    • Python
    • Ruby

    Table of contents

    Welcome to another post of the Common API Tasks blog series for developers! This blog series is focused on simple, yet useful pieces of functionality that can be accomplished using one of the Docusign APIs. In past posts I helped you with things like how to void an envelope or how to retrieve tab data. In my last post, I showed you how you can add more users to a Docusign account using the eSignature REST API. In this issue I’ll be showing you a very useful technique to make your applications more robust by locking and unlocking envelopes as needed.

    As developers who use various systems of source control, I’m sure you’re familiar with the concept of merge conflicts: two (or more) developers making changes to the same file and ending up with the wrong version that someone has to go and resolve.

    Similarly, in Docusign, when you have more than one user (or sometimes the same user using two instances of your application) accessing the system and trying to make changes to the same envelope, you may run into trouble.

    To help developers with this problem, the eSignature REST API provides a mechanism to lock envelopes such that only a particular user of a particular integration can modify them. While the envelope is locked, any other requests to modify it are denied and result in an error. Note that opening an envelope for signing is considered modifying it, even if you don’t actually sign it. That is because the Docusign system records each interaction with the envelope and changes the certificate of completion, which is part of the envelope.

    In this blog post, I’ll cover how to lock an envelope, how to check if an envelope is locked and how to unlock the envelope. The code snippets that I show do the following:

    1. Check if envelope is locked or not

    2. If it is unlocked, lock it

    3. If it is locked, unlock it

    When you lock an envelope, you have to provide some information, including which app is locking the envelope and the duration of the lock. You may also provide a password. That is useful if you are locking a template and want to make sure that it is not changed.

    Your application gets back a lockToken, which must later be used to unlock the envelope using an HttpHeader. You cannot unlock an envelope without this lockToken (the lock will expire when the LockDurationInSeconds has passed). 

    OK, so let’s get down to some code...

    C#

    // You will need to obtain an accessToken using your chosen authentication flow 
    var config = new Configuration(new ApiClient(basePath));
    config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
    var envelopesApi = new EnvelopesApi(config);
    try
    {
       LockInformation lockInfo = envelopesApi.GetLock(accountId, envelopeId);
       // check if this app locked it
        if (lockInfo.LockedByApp == "C.A.T. App")
       {
           // add a header with the LockToken to ensure this app has the right to unlock 
            string LockHeader = $"{{\"lockToken\":\"{lockInfo.LockToken}\"}}";
            envelopesApi.Configuration.AddDefaultHeader("X-Docusign-Edit", LockHeader);
            envelopesApi.DeleteLock(accountId, envelopeId);
       }
    }
    catch (ApiException exp)
    {
       // GetLock would throw an ApiException with error 404 if the envelope is unlocked
        if (exp.ErrorCode == 404)
       {
            var lockRequest = new LockRequest
           { 
                LockedByApp = "C.A.T. App",
                LockDurationInSeconds = "300",
                LockType = "edit"
           };
           envelopesApi.CreateLock(accountId, envelopeId, lockRequest);
       }
    }
    

    Java

    // You will need to obtain an accessToken using your chosen authentication flow 
    Configuration config = new Configuration(new ApiClient(basePath));
    config.addDefaultHeader("Authorization", "Bearer " + accessToken);
    EnvelopesApi envelopesApi = new EnvelopesApi(config);
    try
    {
       LockInformation lockInfo = envelopesApi.getLock(accountId, envelopeId);
       // check if this app locked it
        if (lockInfo.getLockedByApp() == "C.A.T. App")
       {
            // add a header with the LockToken to ensure this app has the right to unlock 
            String LockHeader = String.Format("{{\"lockToken\":\"%s\"}}",   
            lockInformation.getLockToken());
            envelopesApi.getConfiguration().addDefaultHeader("X-Docusign-Edit", LockHeader);
            envelopesApi.deleteLock(accountId, envelopeId);
       }
    }
    catch (ApiException exp)
    {
       // GetLock would throw an ApiException with error 404 if the envelope is unlocked
        if (exp.getCode() == 404)
       {
            LockRequest lockRequest = new LockRequest();
            lockRequest.setLockedByApp("C.A.T. App");
            lockRequest.setLockDurationInSeconds("300");
            lockRequest.setLockType("edit");
            envelopesApi.createLock(accountId, envelopeId, lockRequest);
       }
    }
    

    Node.js

    // You will need to obtain an accessToken using your chosen authentication flow 
    let dsApiClient = new docusign.ApiClient();
    dsApiClient.setBasePath(basePath);
    dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + accessToken);
    let envelopesApi = new docusign.EnvelopesApi(dsApiClient);
    try
    {
        let lockInfo = envelopesApi.getLock(accountId, envelopeId);
       // check if this app locked it
        if (lockInfo.lockedByApp === 'C.A.T. App')
       {
           // add a header with the LockToken to ensure this app has the right to unlock 
           let lockHeader = '{{"lockToken":"${lockInfo.lockToken}"}}';
           envelopesApi.configuration.addDefaultHeader('X-Docusign-Edit', lockHeader);
           envelopesApi.deleteLock(accountId, envelopeId);
       }
    }
    catch (exp)
    {
       // GetLock would throw an ApiException with error 404 if the envelope is unlocked
       if (exp.status == 404)
       {
           let lockRequest = new docusign.LockRequest.constructFromObject({
           LockedByApp : 'C.A.T. App',
           lockDurationInSeconds : '300',
           lockType : 'edit' });
           envelopesApi.createLock(accountId, envelopeId, lockRequest);
       }
    }
    

    PHP

    # You will need to obtain an $access_token using your chosen authentication flow 
    $api_client = new \Docusign\eSign\client\ApiClient($base_path);
    $config = new \Docusign\eSign\Model\Configuration($api_client);
    $config->addDefaultHeader('Authorization', 'Bearer ' + $access_token);
    $envelopes_api = new \Docusign\Api\EnvelopesApi($config);
    try
    {
       $lock_info = $envelopes_api->getLock($account_id, $envelope_id);
       # check if this app locked it
       if ($lock_info->getLockedByApp() == 'C.A.T. App')
       {
           # add a header with the LockToken to ensure this app has the right to unlock 
           $lock_header = sprintf('{{"lockToken":"%s"}}', $lock_info->getLockToken());
           $envelopes_api->configuration->addDefaultHeader('X-Docusign-Edit', $lock_header);
           $envelopes_api->deleteLock(accountId, envelopeId);
       }
    }
    catch (ApiException $exp)
    {
       # GetLock would throw an ApiException with error 404 if the envelope is unlocked
       if ($exp->getCode() == 404)
       {
           $lock_request = new \Docusign\eSign\Model\lockRequest();
           $lock_request->setLockedByApp('C.A.T. App');
           $lock_request->setlockDurationInSeconds('300');
           $lock_request->setlockType('edit');
           $envelopes_api->createLock($account_id, $envelope_id, $lock_request);
       }
    }
    

    Python

    # You will need to obtain an access_token using your chosen authentication flow 
    api_client = ApiClient()
    api_client.set_default_header('Authorization', 'Bearer ' + access_token)
    envelopes_api = EnvelopesApi(config)
    try:
       lock_info = envelopes_api.get_lock(account_id, envelope_id)
       # check if this app locked it
       if lockInfo.locked_by_app == 'C.A.T. App':
           # add a header with the LockToken to ensure this app has the right to unlock 
           lock_header = '{{"lockToken":"{0}"}}'.format(lock_info.lock_token)
           envelopes_api.configuration.set_default_header('X-Docusign-Edit', lock_header)
           envelopes_api.delete_lock(account_id, envelope_id)
    except ApiException as exp:
       # GetLock would throw an ApiException with error 404 if the envelope is unlocked
        if exp.status == 404:
            lock_request = LockRequest()
            lock_request.locked_by_app = 'C.A.T. App'
            lock_request.lock_duration_in_seconds = '300'
            lock_request.lock_type = 'edit'
            envelopes_api.create_lock(account_id, envelope_id, lock_request)
    

    Ruby

    # You will need to obtain an access_token using your chosen authentication flow 
    config = DocuSign_eSign::Configuration.new
    config.host = base_path
    api_client = DocuSign_eSign::ApiClient.new config
    api_client.DefaultHeader['Authorization'] = 'Bearer ' + access_token
    envelopes_api = DocuSign_eSign::EnvelopesApi.new api_client
    begin
       lock_info = envelopes_api.get_lock(account_id, envelope_id)
       # check if this app locked it
       if lockInfo.locked_by_app == 'C.A.T. App'
           # add a header with the LockToken to ensure this app has the right to unlock 
           lock_header = '{{"lockToken":"%s"}}' % lock_info.lock_token
           envelopes_api.Configuration..DefaultHeader['X-Docusign-Edit'] = lock_header
           envelopes_api.delete_lock(account_id, envelope_id)
       end
    rescue DocuSign_eSign::ApiError => exp
       # GetLock would throw an ApiException with error 404 if the envelope is unlocked
       if exp.status == 404
           lock_request = DocuSign_eSign::LockRequest.new
           lock_request.locked_by_app = 'C.A.T. App'
           lock_request.lock_duration_in_seconds = '300'
           lock_request.lock_type = 'edit'
           envelopes_api.create_lock(account_id, envelope_id, lock_request)
       end
    end
    

     I hope you found this useful. As usual, 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

    Author Inbar Gazit
    Inbar GazitSr. Manager, Developer Content

    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.

    More posts from this author

    Related posts

    • Common API Tasks🐈: List all your Maestro workflows using the Maestro API
      Common API Tasks

      Common API Tasks🐈: List all your Maestro workflows using the Maestro API

      Author Inbar Gazit
      Inbar Gazit
    • Common API Tasks🐈: Find a web form by name

      Common API Tasks🐈: Find a web form by name

      Author Inbar Gazit
      Inbar Gazit
    Common API Tasks🐈: Find a web form by name

    Common API Tasks🐈: Find a web form by name

    Author Inbar Gazit
    Inbar Gazit

    Discover what's new with Docusign IAM or start with eSignature for free

    Explore Docusign IAMTry eSignature for Free
    Person smiling while presenting