> For the complete documentation index, see [llms.txt](https://docs.partssource.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.partssource.com/api/core-concepts/pagination.md).

# Pagination

Navigate large result sets with offset-based pagination

The PartsSource APIs use **offset-based pagination** for list and search endpoints. This provides predictable result ordering and consistent navigation through large datasets.

***

## Request Format

Include pagination parameters in the request body for POST search endpoints:

```json
{
  "filters": {
    "email": "john@example.com"
  },
  "pagination": {
    "limit": 50,
    "offset": 0
  }
}
```

***

## GET Search Endpoints

GET search endpoints (e.g., `/manufacturers/search`, `/users/search`) use **query parameter pagination** instead of a request body. Pagination parameters are passed as URL query parameters alongside the `q` search query:

```
GET /orders/search?q=status:"Pending"&limit=25&offset=0
```

| Parameter | Default | Constraints |
| --------- | ------- | ----------- |
| `limit`   | 50      | 1–100       |
| `offset`  | 0       | >= 0        |

{% hint style="info" %}
GET search endpoints have a lower maximum limit of **100** compared to POST search endpoints (up to 10,000). Use filters in the `q` parameter to narrow results.
{% endhint %}

The response shape is the same — results in `data.items` with a `data.pagination` object:

```json
{
  "data": {
    "items": [ ... ],
    "pagination": {
      "total": 142,
      "limit": 25,
      "offset": 0,
      "hasMore": true
    }
  }
}
```

For the full query syntax, operators, and field references, see [Search Query Language](/api/core-concepts/search-query-language.md).

***

## Pagination Parameters

| Parameter | Type    | Default | Range    | Description               |
| --------- | ------- | ------- | -------- | ------------------------- |
| `limit`   | integer | 50      | 1-10,000 | Maximum records to return |
| `offset`  | integer | 0       | 0+       | Number of records to skip |

{% hint style="info" %}
The maximum limit per page is 500 records.
{% endhint %}

***

## Response Format

Paginated responses include metadata alongside the results:

```json
{
  "success": true,
  "data": {
    "customers": [
      {"contactId": 1, "firstName": "John", "lastName": "Doe"},
      {"contactId": 2, "firstName": "Jane", "lastName": "Smith"}
    ],
    "pagination": {
      "total": 150,
      "limit": 50,
      "offset": 0,
      "hasMore": true
    }
  },
  "correlationId": "0HN7QJKV3QJ8K:00000001",
  "timestamp": "2025-10-21T14:30:00.000Z"
}
```

### Response Metadata

| Field     | Type    | Description                      |
| --------- | ------- | -------------------------------- |
| `total`   | integer | Total records matching the query |
| `limit`   | integer | Page size used                   |
| `offset`  | integer | Records skipped                  |
| `hasMore` | boolean | `true` if more pages exist       |

***

## Navigating Pages

### Example: Fetching All Pages

```bash
# First page (records 0-49)
{"pagination": {"limit": 50, "offset": 0}}
# Response: total=150, hasMore=true

# Second page (records 50-99)
{"pagination": {"limit": 50, "offset": 50}}
# Response: total=150, hasMore=true

# Third page (records 100-149)
{"pagination": {"limit": 50, "offset": 100}}
# Response: total=150, hasMore=false
```

### Code Example

```csharp
public async IAsyncEnumerable<Customer> GetAllCustomers(CustomerSearchFilters filters)
{
    int offset = 0;
    const int pageSize = 100;
    bool hasMore = true;

    while (hasMore)
    {
        var request = new CustomerSearchRequest
        {
            Filters = filters,
            Pagination = new PaginationRequest
            {
                Limit = pageSize,
                Offset = offset
            }
        };

        var response = await _apiClient.SearchCustomers(request);

        foreach (var customer in response.Data.Customers)
        {
            yield return customer;
        }

        hasMore = response.Data.Pagination.HasMore;
        offset += pageSize;
    }
}
```

***

## Validation & Normalization

Invalid pagination values are automatically corrected:

| Input          | Normalized To  | Reason                       |
| -------------- | -------------- | ---------------------------- |
| `limit: 50000` | `limit: 10000` | Exceeds maximum              |
| `limit: -5`    | `limit: 50`    | Below minimum (uses default) |
| `offset: -10`  | `offset: 0`    | Cannot be negative           |

{% hint style="warning" %}
The API silently normalizes values rather than returning an error. Always check the `pagination` object in the response to see what values were actually used.
{% endhint %}

***

## Performance Considerations

### Large Offsets

For very large result sets, performance may degrade with high offset values:

| Offset Range     | Performance   |
| ---------------- | ------------- |
| 0 - 10,000       | Excellent     |
| 10,000 - 100,000 | Good          |
| 100,000+         | May be slower |

**Recommendations for large datasets:**

1. **Use filters** to reduce the result set size
2. **Use keyset pagination** for sequential processing (if supported)
3. **Cache results** when possible
4. **Process incrementally** rather than loading all data at once

### Efficient Pagination Patterns

```csharp
// Good: Use filters to reduce result set
var request = new CustomerSearchRequest
{
    Filters = new { status = "active", createdAfter = "2024-01-01" },
    Pagination = new { limit = 100 }
};

// Avoid: Fetching all records with no filters
var request = new CustomerSearchRequest
{
    Pagination = new { limit = 10000 }  // May be slow
};
```

***

## Complete Request Example

### cURL

```bash
curl -X POST https://api.partssource.com/customer/api/users/search \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "emailContains": "@hospital.org",
      "lastName": "Smith"
    },
    "pagination": {
      "limit": 25,
      "offset": 0
    }
  }'
```

### Response

```json
{
  "success": true,
  "data": {
    "users": [
      {
        "id": 12345,
        "userName": "asmith",
        "email": "alice.smith@hospital.org",
        "firstName": "Alice",
        "lastName": "Smith",
        "companies": [...]
      },
      {
        "id": 12346,
        "userName": "bsmith",
        "email": "bob.smith@hospital.org",
        "firstName": "Bob",
        "lastName": "Smith",
        "companies": [...]
      }
    ],
    "pagination": {
      "total": 47,
      "limit": 25,
      "offset": 0,
      "hasMore": true
    }
  },
  "correlationId": "0HN7QJKV3QJ8K:00000002",
  "timestamp": "2025-10-21T14:35:00.000Z"
}
```

***

## TypeScript Helper

```typescript
interface PaginatedResponse<T> {
  data: T[];
  pagination: {
    total: number;
    limit: number;
    offset: number;
    hasMore: boolean;
  };
}

async function* fetchAllPages<T>(
  fetchPage: (offset: number, limit: number) => Promise<PaginatedResponse<T>>,
  pageSize = 100
): AsyncGenerator<T> {
  let offset = 0;
  let hasMore = true;

  while (hasMore) {
    const response = await fetchPage(offset, pageSize);

    for (const item of response.data) {
      yield item;
    }

    hasMore = response.pagination.hasMore;
    offset += pageSize;
  }
}

// Usage
for await (const customer of fetchAllPages(
  (offset, limit) => api.searchCustomers({ pagination: { offset, limit } })
)) {
  console.log(customer.firstName);
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.partssource.com/api/core-concepts/pagination.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
