📄 Pagination

The Dutchie Point of Sale API uses different pagination strategies depending on the endpoint. Most endpoints return complete datasets, while specific endpoints offer pagination for large collections.

🎯 Pagination Overview

Default Behavior

Most API endpoints return all available data in a single response. This approach is optimized for typical business operations where complete datasets are needed for synchronization.

When Pagination is Used

Pagination is available for endpoints that may return very large datasets, such as:

📊 Pagination Methods

Endpoint Pagination Type Parameters Notes
GET /customer/customers None - Returns all customers
GET /customer/customers-paginated Page-based PageNumber, PageSize Large customer datasets
GET /products None - Returns all products
GET /reporting/register-transactions None Date range Filtered by date range

🔢 Page-Based Pagination

Used by endpoints like /customer/customers-paginated for straightforward page navigation.

Request Parameters

Example Request:

GET /customer/customers-paginated?PageNumber=1&PageSize=50

Example Response:

[
  {
    "customerID": 12345,
    "firstName": "John",
    "lastName": "Doe"
    // ... more customer data
  },
  {
    "customerID": 12346,
    "firstName": "Jane",
    "lastName": "Smith"
    // ... more customer data
  }
  // ... more customers (up to PageSize)
]
💡 Note: The customers-paginated endpoint returns a direct array. You need to check the array length against your PageSize to determine if there are more pages.

Navigation Pattern

🔗 Cursor-Based Pagination

Used by select endpoints for efficient traversal of large, time-ordered datasets.

Request Parameters

Example First Request:

GET /example-endpoint?maxPageSize=100

Example Response:

{
  "items": [
    {
      "lspId": 123,
      "locId": 456,
      "customerId": 789,
      "transactionType": "Earned",
      "transactionDateUtc": "2024-01-15T10:30:00Z",
      "points": 25.0,
      "adjustmentReason": null,
      "comment": "Purchase points",
      "registerTransactionId": 98765
    }
    // ... more transactions
  ],
  "pageSize": 100,
  "haveMoreData": true,
  "nextPageKey": "offset:100"
}

Example Next Request:

GET /example-endpoint?pageKey=offset:100&maxPageSize=100
💡 Cursor Benefits: Cursor-based pagination handles real-time data changes better than page-based pagination, ensuring you don't miss records or see duplicates.

⚡ Best Practices

Choose the Right Approach

Error Handling

Performance Optimization

⚠️ Rate Limits: Remember that paginated requests count against your rate limits. Monitor your usage when processing large datasets.

🔄 Working with Non-Paginated Endpoints

Most Dutchie API endpoints return complete datasets optimized for business operations:

Typical Response Patterns

Date Range Filtering

Many endpoints use date ranges instead of pagination to manage response size:

GET /reporting/register-transactions?fromLastModifiedDateUTC=2024-01-01T00:00:00Z&toLastModifiedDateUTC=2024-01-31T23:59:59Z
🎯 Recommendation: Start with non-paginated endpoints for simplicity, then switch to paginated versions if you encounter performance issues with large datasets.

🔧 Implementation Examples

Page-Based Loop (JavaScript)

async function getAllCustomers() {
  let allCustomers = [];
  let currentPage = 1;
  let hasMoreData = true;
  const pageSize = 100;
  
  while (hasMoreData) {
    const response = await fetch(
      `/customer/customers-paginated?PageNumber=${currentPage}&PageSize=${pageSize}`
    );
    const customers = await response.json();
    
    allCustomers.push(...customers);
    
    // If we got fewer than pageSize results, we're done
    hasMoreData = customers.length === pageSize;
    currentPage++;
  }
  
  return allCustomers;
}

Cursor-Based Loop (JavaScript)

async function getAllLoyaltyTransactions() {
  let allTransactions = [];
  let nextPageKey = null;
  
  do {
    const url = nextPageKey 
      ? `/example-endpoint?pageKey=${nextPageKey}&maxPageSize=100`
      : '/example-endpoint?maxPageSize=100';
    
    const response = await fetch(url);
    const data = await response.json();
    
    allTransactions.push(...data.items);
    nextPageKey = data.haveMoreData ? data.nextPageKey : null;
  } while (nextPageKey);
  
  return allTransactions;
}