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

ParameterTypeDefaultDescription
cursorString(None)Opaque pagination cursor returned as metadata.nextCursor in a previous response. Omit on the first call to retrieve the first page.
limitInteger50Maximum 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.
includeTotalBooleanfalseWhen 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/json

Response 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:

EndpointArray keyOrder
GET /v1/accounts/{accountId}/devicesdevicesLast modified, newest first
GET /v1/accounts/{accountId}/sets/{setId}/devicesdevicesLast modified, newest first
GET /v1/accounts/{accountId}/shipmentsshipmentsLast modified, newest first
GET /v1/accounts/{accountId}/assetsassetsLast modified, newest first
GET /v1/accounts/{accountId}/setssetsPriority, 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}/itemsitemsLast modified, newest first
GET /v1/accounts/{accountId}/points-of-interestpointsOfInterestUnspecified
GET /v1/carrierscarriersName, ascending
GET /v1/accounts/{accountId}/data-delivery-rulesrulesLast 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 the cursor query 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 when includeTotal=true is 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_shipments
async 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;
}

Did this page help you?