From the Trenches: API pagination

When fetching and filtering data retrieved in an API call, it is important to consider the volume and subsets of data you include in your results. Pagination is a technique used in various software domains to divide similarly structured data into smaller and more manageable chunks, or “pages”. This can often provide better performance for the end user, better performance for the application, and more relevant and usable results. In this post I will talk about pagination with Docusign’s REST APIs and SDKs.

When to use pagination with Docusign’s REST APIs

Most commonly, you’ll use API pagination with GET request methods and other requests that return a large list of results. In the eSignature API, you’ll often see these labeled as “list” methods. These methods use query parameters of count and start_position to define the pages. The response to these calls will return a startPosition, endPosition, resultSetSize, totalSetSize, previousUri, and nextUri attribute. The nextUri is the same request URL you used in the GET request, but contains the startPosition for your next page of results. You can use this URI directly or increment the startPosition yourself to get the next page of data.

Depending on the API and endpoint you are using, though, there may be different rules and limits for paging. For example, in January 2024, we changed the rules on the listStatusChanges API method. Specifically, we changed the limit to 1,000 results per call and changed how the from_date parameter behaves. If no from_date parameter is passed in the request, the request will only retrieve results going back two years. In order to fetch envelopes older than two years, you should pass the specific date range using from_date and to_date parameters.

Let's now look at some examples of methods where pagination is commonly needed.

eSignature REST API (v2.1)

Envelopes: listStatusChanges

Description: Search for envelopes that have been sent from your account

Page limit: 1000

Other required parameters: from_date or envelope_ids or transaction_ids

GET /restapi/v2.1/accounts/{accountId}/envelopes?from_date=2024-04-01&start_position=0&count=500

Users: list

Description: Retrieves a list of users for the specified account

Page limit: 100

GET /restapi/v2.1/accounts/{accountId}/users?start_position=0&count=50

Templates: list

Description: Retrieves the list of templates for the specified account

Page limit: 2000

GET /restapi/v2.1/accounts/{accountId}/templates?start_position=0&count=100

Groups: list

Description: Gets information about User Groups

Page limit: 100

GET /restapi/v2.1/accounts/{accountId}/groups?start_position=0&count=20

What about the rest of my results?

These above examples will return you one page of results for every one API request, so you will need to make follow up requests to get the rest of your results. You can easily do this by calling the nextUri parameter that comes in the response, or you can increment the startPosition yourself by setting it equal to the endPosition + 1.

Let's look at a code example that uses a while loop to get all data at once. This example uses the listStatusChanges method from our C# SDK to loop through all envelopes sent in the last 30 days. It will have a page count of 100 and will start at startPosition 0. We will also create a List to store all of the envelopes that were returned:

EnvelopesApi envelopesApi = new EnvelopesApi(docuSignClient);

int count = 100;
int startPosition = 0;
int daysAgo = -30;
bool moreResults = true;

// Pass in the paging parameters and any other query parameters
ListStatusChangesOptions options = new ListStatusChangesOptions();
options.fromDate = DateTime.Now.AddDays(daysAgo).ToString("yyyy-MM-dd");
options.count = count.ToString();
options.startPosition = startPosition.ToString();

// Initialize an empty list to store our retrieved envelopes
List<Envelope> envelopeList = new List<Envelope>();

// Fetches envelopes until the start position exceeds total number of envelopes
while (moreResults)
    EnvelopesInformation results = envelopesApi.ListStatusChanges(acct.AccountId, options);
    // Loop through the envelopes and add to the envelope list
    foreach (var env in results.Envelopes)

    startPosition = Int32.Parse(results.EndPosition) + 1;
    options.startPosition = startPosition.ToString();
    moreResults = startPosition < Int32.Parse(results.TotalSetSize);

Keep in mind that an API request will be made every time a new page of results needs to be retrieved. Be mindful of this and poll responsibly. If you are working with a large volume of data, we recommend using additional query parameters to limit the number of results when possible.


If you have any questions about a specific endpoint or method, please contact the Docusign Developer Support group.

Additional resources

Steve DiCicco
Steve DiCicco
Developer Support Engineer