Endpoints that support returning lots of data, usually but not always GETing a List of Resources, support dual-cursor pagination.
If the endpoint supports pagination, it will return a ”pagination”
root key in the response:
"pagination": {
"page_count": <number of total pages>,
"item_count": <number of items in this response>,
"total_count": <total number of items in all pages>,
"cursor": {
"next_cursor": <cursor parameter for next page>,
"previous_cursor": <cursor parameter for previous page>,
"has_next": <true if next_cursor>,
"has_previous": <true if previous cursor>
}
}
This should be present in every response from paginated APIs, even if the user has not asked for pagination or if all of the data fits into one response. For example, if I list all insights
via GET https://api.cloudzero.com/v2/insights
and I don’t have any, I would still get a response like:
{
"pagination": {
"page_count": 0,
"item_count": 0,
"total_count": 0,
"cursor": {
"next_cursor": null,
"previous_cursor": null,
"has_next": false,
"has_previous": false
}
},
"insights": []
}
A client controls the number of items per page via the limit
parameter.
GET https://api.cloudzero.com/v2/insights?limit=5
might return
{
"pagination": {
"page_count": 3,
"item_count": 5,
"total_count": 15,
"cursor": {
"next_cursor": "H4sIAL1Fs2EC/yWKQQqAMAwEv1Jy9uqlnynBpFiMRJooiPh3o952ZvYC0+5l4RNyAkHzsm+EzgRD+pt24v5WtOmVcyMunU3liFdOFcU4vLS1efAYW2s1/uB+ANRxjWxiAAAA",
"previous_cursor": null,
"has_next": true,
"has_previous": false
}
},
"insights": [...]
}
The next_cursor
and previous_cursor
returned are opaque strings that can be used to grab the next and previous pages of data respectively. A client does so simply by passing the urlencoded value of next_cursor
or previous_cursor
via the cursor
parameter:
URL Encoding Cursors
Remember to url encode the cursor before sending it up as a query parameter!
We do it this way to accommodate both Web Browser and Programmatic access.
GET https://api.cloudzero.com/v2/insights?cursor=H4sIAL1Fs2EC%2FyWKQQqAMAwEv1Jy9uqlnynBpFiMRJooiPh3o952ZvYC0%2B5l4RNyAkHzsm%2BEzgRD%2Bpt24v5WtOmVcyMunU3liFdOFcU4vLS1efAYW2s1%2FuB%2BANRxjWxiAAAA
might return
{
"pagination": {
"page_count": 3,
"item_count": 5,
"total_count": 15,
"cursor": {
"next_cursor": "H4sIAAFGs2EC/yWKQQqAMAwEv1Jy9qAHL/1MCTbFYiSSVEHEv5vibWdmHzDRlja6IQZgtJbOI2OjDEP4m2gm7RVt6XKtmZKSCV/+iqEgG7nnutfmPPuWUow6TOP7ASTguj9jAAAA",
"previous_cursor": "H4sIAAFGs2EC/yWKQQqAMAwEv1Jy9uDFi58pwaRYjESaKIj4d1O87czsA6bN88Y3zAkEzfN5EDoTDOlv2ohbr2hLl2slzo1N5YrXnAqKcXipe/XgKbaWYtxhfD+RhfoRYgAAAA==",
"has_next": true,
"has_previous": true
}
},
"insights": [...]
}