Pagination
Sensos API endpoints that return collections (such as devices, shipments, assets, or points of interest) support cursor-based pagination to enable consistent, high-performance data retrieval across large result sets.
How It Works
Cursor-based pagination uses an opaque token (cursor) that marks a specific position in the result set. Rather than computing page offsets, each request fetches the next batch starting immediately after the cursor.
Treat the cursor as an opaque string: do not parse, build, or modify it. A cursor expires 2 days after it was issued; an invalid or expired cursor returns 400 Bad Request, in which case restart from the first page.
Most lists are ordered by last modification time, newest first (see the table below). A record that is modified while you are paging moves to the front of that order, so it can be skipped or returned twice. If you need a complete snapshot, de-duplicate on id.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | String | (None) | Opaque pagination cursor returned as metadata.nextCursor in a previous response. Omit on the first call to retrieve the first page. |
limit | Integer | 50 | Maximum number of records to return in a single page (allowed range: 1 to 100). Values outside the range are clamped, not rejected: 0 or less is treated as 50, more than 100 as 100. |
includeTotal | Boolean | false | When set to true, returns the total count of items matching the query in metadata.total. |
There is no sort parameter; each list has a fixed order.
Request Example
GET https://api.sensos.io/v1/accounts/{accountId}/shipments?limit=50&cursor={cursor}&includeTotal=true
Authorization: Bearer <YOUR_ACCESS_TOKEN>
Accept: application/jsonResponse Format
Paginated responses return a top-level metadata envelope alongside an array containing the resource records. The name of the array depends on the endpoint:
| Endpoint | Array key | Order |
|---|---|---|
GET /v1/accounts/{accountId}/devices | devices | Last modified, newest first |
GET /v1/accounts/{accountId}/sets/{setId}/devices | devices | Last modified, newest first |
GET /v1/accounts/{accountId}/shipments | shipments | Last modified, newest first |
GET /v1/accounts/{accountId}/assets | assets | Last modified, newest first |
GET /v1/accounts/{accountId}/sets | sets | Priority, ascending. Sets without a priority are appended to the last page, so the last page can contain more than limit records. |
GET /v1/accounts/{accountId}/items | items | Last modified, newest first |
GET /v1/accounts/{accountId}/points-of-interest | pointsOfInterest | Unspecified |
GET /v1/carriers | carriers | Name, ascending |
GET /v1/accounts/{accountId}/data-delivery-rules | rules | Last updated, newest first |
Example Response (Shipments)
{
"metadata": {
"total": 348,
"nextCursor": "NjVhMWQ2YjgtMmM0Ny00ZTFmLTk4YTMtMGY3YjVlMmMxZDQ5"
},
"shipments": [
{
"id": "357aebc5-692d-4b25-87d0-fc9ee7b3ada9",
"name": "Cold-Chain Pharma Batch #1048",
"status": "InTransit"
}
]
}Metadata Fields
metadata.nextCursor: An opaque string token to supply in thecursorquery parameter of your next request. It is an empty string ("") on the last page.metadata.total: The total count of records matching your query criteria. Returned only whenincludeTotal=trueis requested.
Pagination Loop Code Samples
import requests
def fetch_all_shipments(account_id: str, access_token: str):
url = f"https://api.sensos.io/v1/accounts/{account_id}/shipments"
headers = {
"Authorization": f"Bearer {access_token}",
"Accept": "application/json"
}
params = {"limit": 100}
all_shipments = []
while True:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
# Append current page records (the array key depends on the endpoint)
all_shipments.extend(data.get("shipments", []))
# nextCursor is "" on the last page
next_cursor = data.get("metadata", {}).get("nextCursor", "")
if not next_cursor:
break # Reached last page
params["cursor"] = next_cursor
return all_shipmentsasync function fetchAllShipments(accountId: string, accessToken: string) {
const allShipments = [];
let cursor = "";
do {
const url = new URL(`https://api.sensos.io/v1/accounts/${accountId}/shipments`);
url.searchParams.set("limit", "100");
if (cursor !== "") {
url.searchParams.set("cursor", cursor);
}
const res = await fetch(url.toString(), {
headers: {
"Authorization": `Bearer ${accessToken}`,
"Accept": "application/json"
}
});
if (!res.ok) {
throw new Error(`Pagination request failed: ${res.status}`);
}
const data = await res.json();
// The array key depends on the endpoint
allShipments.push(...(data.shipments ?? []));
// nextCursor is "" on the last page
cursor = data.metadata?.nextCursor ?? "";
} while (cursor !== "");
return allShipments;
}Updated 21 days ago
