Pagination

Some of the main API resources are associated with a listing endpoint (list of Signature Requests, Users and Contacts) and each of them uses a cursor-based pagination.

Cursor-based Pagination

Cursor-based pagination returns a pointer (cursor) to a specific item in the dataset. When a cursor is given, the server will return the results found after this cursor.

The response to a list API request represents a single page of items sorted by items creation date (most recent first). When the query parameter ?after={next_cursor} is specified then items created before this cursor are returned, if no cursor is provided, the most recent items are returned.
Each page of results has a limit of 100 items.

Pros:

  • Most of the time, cursor-based pagination queries database more efficiently than offset-based pagination, which improves the response speed of the API.
  • Adding or deleting new records on previous pages does not result in duplicate or missing items.

Cons:

  • Unlike the offset-based pagination, cursor-based pagination does not allow you to jump to any page but only to the next or previous page.
  • It does not allow you to retrieve different pages in parallel, since you only get the next cursor from the previous result page.
  • You cannot know the total number of items available in the dataset until you have gone through all the results.

How to use the cursor-based pagination

In this example, we have a dataset with 101 Signature Requests. In order to retrieve all of them, we will have to perform two queries. One to get the first 100 Signature Requests, then a second to get the remaining Signature Requests.

1) First query without using a cursor as parameter:

GET /signature_requests

{
    "meta": {
        "next_cursor": "MTY3MjY2NTc2MC42NDc2NzQgYTgwYTNkMjYtNzA3Ny00ZWMyLWEzMTMtNjk1MDdlOGRlZjQ1"
    },
    "data": [
        {
            "approvers": [],
            "id": "ac50edf7-076e-4f1b-b680-0797e6a1135d",
            "source": "public_api",
            "status": "draft",
            "name": "The name of your Signature Request",
            "created_at": "2023-01-03T10:37:32+00:00",
            "email_custom_note": null,
            "ordered_signers": false,
            "timezone": "Europe/Paris",
            "reminder_settings": null,
            "expiration_date": "2023-07-03T21:59:00+00:00",
            "delivery_mode": "email",
            "documents": [
                {
                    "id": "c9e77f4e-60a6-4a0d-abc9-d8c210fa1521",
                    "nature": "signable_document"
                }
            ],
            "signers": [
                {
                    "id": "3cd1a547-b207-4c29-a3b6-f98bb9997415",
                    "status": "initiated"
                },
                {
                    "id": "bb79a1d1-dcc1-45e8-9418-e864bf332ae1",
                    "status": "initiated"
                },
                {
                    "id": "a7bcd14d-7871-4af9-95dc-fbcdefc00fd7",
                    "status": "initiated"
                }
            ],
            "external_id": null,
            "custom_experience_id": null,
            "sender": null
        },
      
				//...+ 99 more Signature Requests
    ]
}

2) Then we will fetch the next result page using the cursor returned by the last query:

GET /signature_requests?after=MTY3MjY2NTc2MC42NDc2NzQgYTgwYTNkMjYtNzA3Ny00ZWMyLWEzMTMtNjk1MDdlOGRlZjQ1

{
    "meta": {
        "next_cursor": null
    },
    "data": [
        {
            "approvers": [],
            "id": "aac08775-440e-4514-a14e-bf330f6dd74d",
            "source": "public_api",
            "status": "draft",
            "name": "The name of your Signature Request",
            "created_at": "2023-01-02T10:10:32+00:00",
            "email_custom_note": null,
            "ordered_signers": false,
            "timezone": "Europe/Paris",
            "reminder_settings": null,
            "expiration_date": "2023-07-02T21:59:00+00:00",
            "delivery_mode": "email",
            "documents": [
                {
                    "id": "04ee8759-4fce-4f1f-8e9e-6a4b0e7f2461",
                    "nature": "signable_document"
                }
            ],
            "signers": [
                {
                    "id": "4c3bf3ee-474e-4cb0-ba8f-897d5b330fde",
                    "status": "initiated"
                },
                {
                    "id": "44414f9f-f814-448f-8044-cb8e20f6c46b",
                    "status": "initiated"
                },
                {
                    "id": "f537b1ea-e4f1-4fc7-9347-dada5d9ff049",
                    "status": "initiated"
                }
            ],
            "external_id": null,
            "custom_experience_id": null,
            "sender": null
        }
    ]
}

The meta data next_cursor is now NULL, which means that there is no item left.