linkPagination
All top-level API resources have support for bulk fetches via "list" API methods.
For instance you can list users, list licenses,
and list machines. These list API methods
share a common format, taking an optional page query parameter.
Our API utilizes a cursor-based pagination strategy (also known as "keyset" pagination)
via the page[size] and page[cursor] parameters. The cursor is the ID of the last
record you received, and the API will return the next set of records after that ID
(exclusive). To fetch the first page, omit the page[cursor] parameter or pass an
empty value.
To paginate through an entire result set:
- Make an initial request to a resource list with the
page[size]parameter set to your desired page size and thepage[cursor]parameter set to an empty value. - Check the response's
linksobject. If alinks.nextURI is present, more results may be available on the next page. If thelinks.nextproperty isnull, you've reached the end of the result set. - Follow the
links.nextURI, or use the ID of the last record in the currentdataarray as thepage[cursor]for your next request. - Repeat step 2 and 3 until
links.nextisnull, or until thedataarray is empty, both of which indicate you've reached the end of the requested result set.
All results are returned in reverse chronological order.
We also support an offset-based strategy via the page[number] parameter, but
offset-based pagination can become slow on large datasets, and worse, correctness
issues can arise when paginating across many pages, e.g. records created or deleted
between requests can cause duplicate or even missing results. As such, we've
deprecated the offset-based pagination strategy in favor of the cursor-based
strategy, outlined above.
linkQuery parameters
linkpage
object<string, integer | string>Object containing page
sizeand pagecursor, or pagesizeand pagenumber.linkpage[cursor]
stringThe page cursor. Must be the UUID of a resource, representing the starting point of the page (exclusive), or an empty string.
For most cases, navigating pages will start with an empty cursor, then the ID of the last record in your current result set should be used as the cursor for the next request. You can also follow thelinks.nextURI provided in each response./v1/accounts/<account>/licenses?page[cursor]=linkpage[number]
integerdeprecatedThis param has been deprecated and its use is no longer recommended.The page number. Must be a number between 1 and 100.
Offset-based pagination has been deprecated and has been limited to a maximum of 100 pages. Please use cursor-based pagination.
Example request
const fetch = require("node-fetch")const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/users?page[size]=25&page[cursor]=4a3eb389-5742-49f2-92f8-29347196a265", {method: "GET",headers: {"Accept": "application/vnd.api+json","Authorization": "Bearer <token>"}})const { data, links, errors } = await response.json()import requestsimport jsonres = requests.get("https://api.keygen.sh/v1/accounts/<account>/users?page[size]=25&page[cursor]=4a3eb389-5742-49f2-92f8-29347196a265",headers={"Accept": "application/vnd.api+json","Authorization": "Bearer <token>"}).json()import SwiftyJSONimport AlamofireAlamofire.request("https://api.keygen.sh/v1/accounts/<account>/users?page[size]=25&page[cursor]=4a3eb389-5742-49f2-92f8-29347196a265",headers: ["Accept": "application/vnd.api+json","Authorization": "Bearer <token>"]).responseJSON { response inlet json = JSON(data: response.data!)}using RestSharp;var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");var request = new RestRequest("users", Method.GET);request.AddHeader("Accept", "application/vnd.api+json");request.AddHeader("Authorization", "Bearer <token>");request.AddParameter("page[size]", 25);request.AddParameter("page[cursor]", "4a3eb389-5742-49f2-92f8-29347196a265");var response = client.Execute(request);import com.mashape.unirest.http.exceptions.*import com.mashape.unirest.http.*val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/users").header("Authorization", "Bearer <token>").header("Accept", "application/vnd.api+json").queryString("page[size]", 25).queryString("page[cursor]", "4a3eb389-5742-49f2-92f8-29347196a265").asJson()import com.mashape.unirest.http.exceptions.*;import com.mashape.unirest.http.*;HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/users").header("Authorization", "Bearer <token>").header("Accept", "application/vnd.api+json").queryString("page[size]", 25).queryString("page[cursor]", "4a3eb389-5742-49f2-92f8-29347196a265").asJson();#include <iostream>#include <string>#include <cpprest/http_client.h>#include <cpprest/filestream.h>using namespace std;using namespace web;using namespace web::http;using namespace web::http::client;using namespace utility;http_client client("https://api.keygen.sh/v1/accounts/<account>");http_request req;req.headers().add("Authorization", "Bearer <token>");req.headers().add("Accept", "application/json");uri_builder uri("/users");uri.append_query("page[size]", 25);uri.append_query("page[cursor]", "4a3eb389-5742-49f2-92f8-29347196a265");req.set_request_uri(uri.to_uri());req.set_method(methods::GET);client.request(req).then([](http_response res) {auto data = res.extract_json().get();}).wait();curl 'https://api.keygen.sh/v1/accounts/<account>/users?page[size]=25&page[cursor]=4a3eb389-5742-49f2-92f8-29347196a265' -g \-H 'Accept: application/vnd.api+json' \-H 'Authorization: Bearer <token>'
Example response
{ "data": [ { "id": "6ed498fe-5f5f-49af-82ee-cb7400cc4522", "type": "users", "links": { "self": "/v1/accounts/<account>/users/6ed498fe-5f5f-49af-82ee-cb7400cc4522" }, "attributes": { "fullName": "Marty McFly", "firstName": "Marty", "lastName": "McFly", "status": "ACTIVE", "role": "user", "metadata": {}, "created": "2017-01-02T19:48:50.077Z", "updated": "2017-01-02T19:48:50.077Z" }, "relationships": { "account": { "links": { "related": "/v1/accounts/<account>" }, "data": { "type": "accounts", "id": "<account>" } }, "products": { "links": { "related": "/v1/accounts/<account>/users/a5a154d2-f026-40fa-bc8d-a7e3ca415298/products" } }, "licenses": { "links": { "related": "/v1/accounts/<account>/users/a5a154d2-f026-40fa-bc8d-a7e3ca415298/licenses" } }, "machines": { "links": { "related": "/v1/accounts/<account>/users/a5a154d2-f026-40fa-bc8d-a7e3ca415298/machines" } }, "tokens": { "links": { "related": "/v1/accounts/<account>/users/a5a154d2-f026-40fa-bc8d-a7e3ca415298/tokens" } } } }, … ], "links": { "self": "/v1/accounts/<account>/users?page[size]=25&page[cursor]=4a3eb389-5742-49f2-92f8-29347196a265", "next": "/v1/accounts/<account>/users?page[size]=25&page[cursor]=6ed498fe-5f5f-49af-82ee-cb7400cc4522", }}