> You are reading the Docusign Developer Documentation. For clean Markdown of any page, append .md to the page URL.
>
> Documentation indexes by section:
> - APIs and SDKs: https://docusign.docs.buildwithfern.com/docs/llms.txt
> - Platform 101: https://docusign.docs.buildwithfern.com/platform/llms.txt
> - Extension Apps: https://docusign.docs.buildwithfern.com/extension-apps/llms.txt
> - Docusign CLI: https://docusign.docs.buildwithfern.com/docusign-cli/llms.txt
>
> Authentication (OAuth, JWT Grant, M2M): https://docusign.docs.buildwithfern.com/platform/auth
> Webhooks and Connect: https://docusign.docs.buildwithfern.com/platform/webhooks
>
> OpenAPI specifications: https://docusign.docs.buildwithfern.com/openapi.json
> MCP server: https://docusign.docs.buildwithfern.com/_mcp/server

# How to list envelope status changes

> Demonstrates how to get a set of status history data for all of your envelopes

This topic demonstrates how to get a set of status history data for all of your envelopes updated within a specified range of dates.

## Required data

Running the code in this how-to requires this data:

| Data element      | Description                                                                                                                                                                                                                                                                                                            |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \{API_ACCOUNT_ID} | A [GUID](http://guid.one/) value that identifies your account. This value is automatically generated by Docusign for any account you create. Copy the value from the **API Account ID** field on the [Apps and Keys](https://admindemo.docusign.com/authenticate?goTo=appsAndKeys) page.                               |
| \{BASE_PATH}      | A string value that forms the root of the URL required to make API calls. The base path value in the example code is set to target the developer environment at https\://\<domain>/restapi Where \<domain> is demo.docusign.net for the developer environment and is the result of the GetUserInfo call in production. |
| \{FROM_DATE}      | A filter for the query in the format YYYY-MM-DD. Only envelopes whose status has changed beginning with the date specified by `from_date` will be returned.                                                                                                                                                            |

## Step 1. Obtain your OAuth token

To make the API call shown in this how-to, you need a valid OAuth access token. Docusign supports access tokens for three different recommended OAuth grant types: Public Authorization Code Grant, Confidential Authorization Code Grant, and JSON Web Token (JWT) Grant. Choose the OAuth grant type appropriate for your scenario.

> **Note**
>
> See [Confidential Authorization Code Grant](/platform/auth/authcode#confidential-authorization-code-grant) for guidance on your options to get an Confidential Authorization Code Grant  OAuth token.

![Three icons that represent the three methods a user can use to obtain an OAuth token: JSON Web Token (JWT), Public Authorization Code Grant (ACG), and Confidential Authorization Code grant](/_fern-files/_img/64f473773042ee439449a096bf7673292b1585b86a4ccc55f82ba0dda41f61a1.webp)

## Step 2. List envelope status

Call the `envelopes.listStatusChanges` method to get a list of envelopes and their statuses during a specified range of time. To get the list, you must specify either a from date or provide a list of envelope IDs or transaction IDs in the request. Otherwise, an error will be returned. This example uses the from date to get an array of envelopes created within the last 30 days. Use the following steps to make this method call and obtain the list of envelopes and statuses:

1. Instantiate the Docusign API client.
2. Set the following default request header to add your access token.
   `"Authorization" : "Bearer {ACCESS_TOKEN}"`
3. Initialize the Envelopes API.
4. Create a filter that specifies the set of envelope statuses that you want to return. Your request must include one or more of the following filter parameters: `from_date`, `envelope_ids`, or `transaction_ids`. Each of these parameters can accept a comma-delimited list.

   The example documented here uses the `from_date` filter, which returns all envelope status changes made since the specified date. Docusign recommends using ISO 8601 format dates with an explicit time zone offset.

   **Note:** The `status` and `from_to_status` options are very useful for search filtering. The former enables filtering by way of a comma-delimited list of statuses, whereas the latter will enable you to filter by a specific status for a given `from_date` and `to_date` time range. You can learn about more optional query filtering parameters by consulting [Envelopes:listStatusChanges](/docs/esign-rest-api/reference/envelopes/envelopes/liststatuschanges) in the API Reference.
5. After calling the `envelopes.listStatusChanges` method to obtain the envelope status data, you will receive both data on the status of each document within the envelope (`sent` vs `draft`, for instance) and status change dates as well as resource locators such as the documents combined URI, the attachments URI, and the recipients URI.

View the source code for this example on GitHub: [Bash](https://github.com/docusign/code-examples-bash/blob/master/examples/eSignature/eg003ListEnvelopes.sh), [C#](https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Examples/ListAccountEnvelopes.cs), [Java](https://github.com/docusign/code-examples-java/blob/master/src/main/java/com/docusign/controller/eSignature/examples/EG003ControllerListEnvelopes.java), [Node.js](https://github.com/docusign/code-examples-node/blob/master/lib/eSignature/examples/listEnvelopes.js), [PHP](https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/ListEnvelopesService.php), [PowerShell](https://github.com/docusign/code-examples-powershell/blob/master/examples/eSignature/eg003ListEnvelopes.ps1), [Python](https://github.com/docusign/code-examples-python/blob/master/app/eSignature/examples/eg003_list_envelopes.py), or [Ruby](https://github.com/docusign/code-examples-ruby/blob/main/app/services/e_sign/eg003_list_envelopes_service.rb).

**`Bash`**

```bash title="Bash"
# Calculate the from_date query parameter and use the ISO 8601 format.
# Example:
# from_date=2018-09-30T07:43:12+03:00
# For a Mac, 10 days in the past:
if date -v -10d &> /dev/null ; then
    # Mac
    from_date=`date -v -10d '+%Y-%m-%dT%H:%M:%S%z'`
else
    # Not a Mac
    from_date=`date --date='-10 days' '+%Y-%m-%dT%H:%M:%S%z'`
fi

curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
     --header "Content-Type: application/json" \
     --get \
     --data-urlencode "from_date=${from_date}" \
     --request GET ${base_path}/v2.1/accounts/${account_id}/envelopes
```

**`C#`**

```csharp title="C#"
var docuSignClient = new DocuSignClient(basePath);
docuSignClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(docuSignClient);

ListStatusChangesOptions options = new ListStatusChangesOptions();
options.fromDate = DateTime.Now.AddDays(-30).ToString("yyyy-MM-dd");

// Call the API method:
var results = envelopesApi.ListStatusChangesWithHttpInfo(accountId, options);
results.Headers.TryGetValue("X-RateLimit-Remaining", out string remaining);
results.Headers.TryGetValue("X-RateLimit-Reset", out string reset);

if (reset != null && remaining != null)
{
    DateTime resetDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(reset)).UtcDateTime;
    Console.WriteLine("API calls remaining: " + remaining);
    Console.WriteLine("Next Reset: " + resetDate);
}
```

**`Java`**

```java title="Java"
EnvelopesApi envelopesApi = createEnvelopesApi(session.getBasePath(), user.getAccessToken());
EnvelopesInformation envelopesInformation = ListEnvelopesServices.listEnvelopes(
        envelopesApi,
        session.getAccountId());
```

**`Node.js`**

```javascript title="Node.js"
let dsApiClient = new docusign.ApiClient();
dsApiClient.setBasePath(args.basePath);
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
let envelopesApi = new docusign.EnvelopesApi(dsApiClient);
  let results = null;
results = await envelopesApi.listStatusChanges(args.accountId, options, (error, data, response) => {
    const headers = response?.headers;

    const remaining = headers?.['x-ratelimit-remaining'];
    const reset = headers?.['x-ratelimit-reset'];

    if (remaining && reset) {
      const resetInstant = new Date(Number(reset) * 1000);

      console.log(`API calls remaining: ${remaining}`);
      console.log(`Next Reset: ${resetInstant.toISOString()}`);
    }
});
```

**`PHP`**

```php title="PHP"
$envelope_api = $clientService->getEnvelopeApi();
$from_date = date("c", (time() - (30 * 24 * 60 * 60)));
$options = new ListStatusChangesOptions();
$options->setFromDate($from_date);
try {
    $statusChanges = $envelope_api->listStatusChangesWithHttpInfo($args['account_id'], $options);

    $remaining = $statusChanges[2]['X-RateLimit-Remaining'] ?? null;
    $reset = $statusChanges[2]['X-RateLimit-Reset'] ?? null;

    if ($remaining !== null && $reset !== null) {
        $resetInstant = (new DateTime())->setTimestamp((int)$reset);
        error_log("API calls remaining: $remaining");
        error_log("Next Reset: " . $resetInstant->format(\DateTime::ATOM));
    }
} catch (ApiException $e) {
    $clientService->showErrorTemplate($e);
    exit;
}
```

**`PowerShell`**

```text title="PowerShell"
# Obtain your accountId from demo.docusign.net -- the account id is shown in
# the drop down on the upper right corner of the screen by your picture or
# the default picture.
$accountID = Get-Content .\config\API_ACCOUNT_ID

Write-Output "Sending the list envelope status request to Docusign..."
Write-Output "Results:"

# Get date in the ISO 8601 format
$fromDate = ((Get-Date).AddDays(-10d)).ToString("yyyy-MM-ddTHH:mm:ssK")

$(Invoke-RestMethod `
    -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
    -Method 'GET' `
    -Headers @{
    'Authorization' = "Bearer $accessToken";
    'Content-Type'  = "application/json";
  } `
    -Body @{ "from_date" = ${fromDate} }).envelopes
```

**`Python`**

```python title="Python"
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])

envelope_api = EnvelopesApi(api_client)

# The Envelopes::listStatusChanges method has many options
# See https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/liststatuschanges/

# The list status changes call requires at least a from_date OR
# a set of envelopeIds. Here we filter using a from_date.
# Here we set the from_date to filter envelopes for the last month
# Use ISO 8601 date format
# 1. Call the envelope status change method to list the envelopes
from_date = (dt.utcnow() - timedelta(days=30)).strftime('%Y-%m-%d')
(data, status, headers) = envelope_api.list_status_changes_with_http_info(account_id=args["account_id"], from_date=from_date)

remaining = headers.get("X-RateLimit-Remaining")
reset = headers.get("X-RateLimit-Reset")

if remaining is not None and reset is not None:
    reset_date = dt.fromtimestamp(int(reset), tz=timezone.utc)
    print(f"API calls remaining: {remaining}")
    print(f"Next Reset: {reset_date}")
```

**`Ruby`**

```ruby title="Ruby"
envelope_api = create_envelope_api(args)
options = DocuSign_eSign::ListStatusChangesOptions.new
options.from_date = (Date.today - 30).strftime('%Y-%m-%d')
# Exceptions will be caught by the calling function
results, _status, headers = envelope_api.list_status_changes_with_http_info args[:account_id], options

remaining = headers['X-RateLimit-Remaining']
reset = headers['X-RateLimit-Reset']

if remaining && reset
  reset_date = Time.at(reset.to_i).utc
  puts "API calls remaining: #{remaining}"
  puts "Next Reset: #{reset_date}"
end
```

## Expected response

If you run this code example from our Quickstart or launcher projects, you should see a JSON response similar to the code shown.

**`Sample response`**

```json title="Sample response"
{
  "resultSetSize": "4",
  "startPosition": "0",
  "endPosition": "3",
  "totalSetSize": "4",
  "nextUri": "",
  "previousUri": "",
  "envelopes":
  [
    {
      "status": "sent",
      "documentsUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/documents",
      "recipientsUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/recipients",
      "attachmentsUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/attachments",
      "envelopeUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e",
      "emailSubject": "Please sign this document",
      "envelopeId": "d9457cd7-xxxx-xxxx-xxxx-b5847d53092e",
      "signingLocation": "online",
      "customFieldsUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/custom_fields",
      "notificationUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/notification",
      "allowMarkup": "false",
      "createdDateTime": "2020-08-19T00:37:17.6570000Z",
      "lastModifiedDateTime": "2020-08-19T00:37:17.6570000Z",
      "sentDateTime": "2020-08-19T00:37:18.3600000Z",
      "statusChangedDateTime": "2020-08-19T00:37:18.3600000Z",
      "documentsCombinedUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/documents/combined",
      "certificateUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/documents/certificate",
      "templatesUri": "/envelopes/d9457cd7-xxxx-xxxx-xxxx-b5847d53092e/templates",
      "expireEnabled": "true",
      "expireAfter": "120",
      "sender":
      {
        "userName": "Admin One",
        "userId": "c1c4ca80-xxxx-xxxx-xxxx-32a3a9b13925",
        "accountId": "a56df5fc-xxxx-xxxx-xxxx-f64dc8ab421e",
        "email": "admin1@anyemail.com"
      },
      "purgeState": "unpurged",
      "envelopeIdStamping": "true",
      "autoNavigation": "true",
      "isSignatureProviderEnvelope": "false",
      "anySigner": null,
      "envelopeLocation": "not_specified"
    }
  ]
}
```

## Next steps

* Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects:    [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).
* See context around [envelopes](/docs/esign-rest-api/esign101/concepts/envelopes).
* See [Envelopes:listStatusChanges](/docs/esign-rest-api/reference/envelopes/envelopes/liststatuschanges) for the full list of envelope status values.
* See the MyAPICalls sample app scenario [Envelope Search with Resend](https://myapicalls.sampleapps.docusign.com/scenario/10), which walks you through a sequence of API calls that search for envelopes and resend an envelope returned in the results.
* See how to [Go-Live](/docs/esign-rest-api/go-live) with a completed app and find the base path for API calls in the production environment.