Blog
Home/

Let’s Stop! Voiding Docusign envelopes with Go

Aaron Jackson-Wilde
Aaron Jackson-WildeProgrammer Writer
Summary3 min read

This code example shows you how to void an envelope using Go.

    • Retrieving your EnvelopeID
    • Voiding the envelope
    • Additional resources

    Table of contents

    Last time I wrote how to create an envelope using Go. This time, I’d like to destroy some envelopes instead, using the Docusign eSignature API. The process to void an envelope is rather simple and can be completed with an envelope ID and a void status message. Go is a robust, yet simple language that can run efficiently on limited hardware. I don’t know, man, it’s like Java and Python had a baby or something… 

    As a prerequisite, I’ll ask that you review the earlier mentioned blog post and retrieve the script made from before to generate an OAUTH token and an envelope. For the sake of brevity, I will not be reviewing how to generate your token, but I will briefly review sending an envelope so that you can retrieve (and void) your envelope using an envelope ID. I did mention destroying envelopes; however, I can’t KNOW for sure that all my readers can do that: purged documents have a configured retention period before they can be permanently removed from your account. Before that can happen, an envelope must be voided first.

    Retrieving your EnvelopeID

    With a valid OAuth token in hand, send your envelope. I want to show you how to interface with custom envelope data, so I’ll be making a small modification to the request body that generates the envelope:

    // Send an envelope
    func sendEnvelope(DSAccessToken string, DSAccountId string, envelopeDefinition string) (string, error) {
        client := &http.Client{}
        // Use http.NewRequest to set custom headers
        req, err := http.NewRequest("POST", "https://demo.docusign.net/restapi/v2.1/accounts/"+DSAccountId+"/envelopes", strings.NewReader(envelopeDefinition))
        req.Header.Set("Authorization", "Bearer "+DSAccessToken)
        if err != nil {
            fmt.Printf("Request Failed: %s", err)
            return "", err
        }
        // Since http.NewRequest is being used, client.Do is needed to execute the request
        res, err := client.Do(req)
        if err != nil {
            fmt.Printf("Request Failed: %s", err)
            return "", err
        }
     
        body, err := io.ReadAll(res.Body)
        if err != nil {
            fmt.Printf("Request Failed: %s", err)
            return "", err
        }
        // fmt.Printf("Body: %s\n", body)
        // Decode the response to JSON
        var envelope EnvelopeID
        jsonErr := json.Unmarshal(body, &envelope)
        if jsonErr != nil {
            fmt.Printf("Request Failed: %s", jsonErr)
            return "", jsonErr
        }
        return envelope.EnvelopeID, nil
    }
    
    

    The response JSON will contain an envelopeID. Keep this for later, as you will use it for voiding the very same envelope:

    {
      "envelopeId":"bc488991-xxxx-xxxx-xxxx-b09adc914e0a",
      "uri":"/envelopes/bc488991-xxxx-xxxx-xxxx-b09adc914e0a",
      "statusDateTime":"2023-10-28T05:48:53.3070000Z",
      "status":"sent"
    }
    
    

    Voiding the envelope

    Just as before, you’ll need to issue a PUT request on the Envelopes::Update endpoint using the retrieved envelopeID, setting the status property to void and providing a string description for the voidedReason. Note that the Envelopes:Update endpoint is also the same URL for the Envelopes:Create endpoint, except you will need to specify that this is a PUT operation (not POST) and you will need to now include the generated envelopeID as a parameter (URL path) value.

    // Voids an envelope
    func voidEnvelope(DSAccessToken string, DSAccountId string, EnvelopeID string)(string, error) {
        client := &http.Client{}
    
        voidBody := `{
            "status": "voided",
            "voidedReason": "The reason for voiding the envelope"
          }`
        // Use http.NewRequest in order to set custom headers
        req, err := http.NewRequest("PUT", "https://demo.docusign.net/restapi/v2.1/accounts/"+DSAccountId+"/envelopes/"+EnvelopeID, strings.NewReader(voidBody))
        req.Header.Set("Authorization", "Bearer "+DSAccessToken)
        if err != nil {
            fmt.Printf("Request Failed: %s", err)
            return "", err
        }
        // Since http.NewRequest is being used, client.Do is needed to execute the request
        res, err := client.Do(req)
        if err != nil {
            fmt.Printf("Request Failed: %s", err)
            return "", err
        }
        fmt.Print("Void Envelope Response: " + res.Status + "\n")
        return res.Status, err
    }
    
    

    Additional resources

    Aaron Jackson-Wilde
    Aaron Jackson-WildeProgrammer Writer

    Aaron Jackson-Wilde has been with Docusign since 2019 and specializes in API-related developer content. Aaron contributes to the Quickstart launchers, How-To articles, and SDK documentation, and helps troubleshoot occasional issues on GitHub or StackOverflow.

    More posts from this author

    Related posts

    • Developer Spotlight

      Developer Spotlight is Coming to Docusign Community!

      Matthew Lusher
      Matthew Lusher
    • Breaking the Language Barrier: Why Large Language Models Need Open Text Formats

      Dan Selman
      Dan Selman
    • Understanding Levenshtein Distance: Applications to AI-Generated Text

      Vincent Pan
      Vincent Pan

    Developer Spotlight is Coming to Docusign Community!

    Matthew Lusher
    Matthew Lusher

    Understanding Levenshtein Distance: Applications to AI-Generated Text

    Vincent Pan
    Vincent Pan

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

    Explore Docusign IAMTry eSignature for Free
    Person smiling while presenting