# Pagination

This document explains how to paginate through large log result sets using the groundcover logs query API.

### Overview

When querying logs, you may receive more results than can be efficiently returned in a single response. Pagination allows you to retrieve results in smaller, manageable chunks by using the `limit` and `skip` parameters.

### Parameters

| Parameter | Type    | Description                                                                          | Example |
| --------- | ------- | ------------------------------------------------------------------------------------ | ------- |
| `limit`   | integer | Maximum number of log entries to return per page. The maximum allowed value is: 5000 | `200`   |
| `skip`    | integer | Number of log entries to skip from the start                                         | `0`     |

{% hint style="warning" %}
Note: The `limit` parameter can get a maximum value of 5000
{% endhint %}

### Basic Pagination

To paginate through results:

1. **First page**: Set `skip: 0` and `limit` to your desired page size
2. **Subsequent pages**: Increment `skip` by the `limit` value for each page

**Example: First Page**

```bash
curl 'https://app.groundcover.com/api/logs/v2/query' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "start": "2025-12-24T07:54:29.459Z",
    "end": "2025-12-24T13:54:29.459Z",
    "group": null,
    "limit": 200,
    "skip": 0,
    "sortBy": "timestamp",
    "sortOrder": "desc",
    "selectors": [],
    "optimizeSearch": true
  }'
```

**Example: Second Page**

```bash
curl 'https://app.groundcover.com/api/logs/v2/query' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "start": "2025-12-24T07:54:29.459Z",
    "end": "2025-12-24T13:54:29.459Z",
    "group": null,
    "limit": 200,
    "skip": 200,
    "sortBy": "timestamp",
    "sortOrder": "desc",
    "selectors": [],
    "optimizeSearch": true
  }'
```

**Example: Third Page**

```bash
curl 'https://app.groundcover.com/api/logs/v2/query' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "start": "2025-12-24T07:54:29.459Z",
    "end": "2025-12-24T13:54:29.459Z",
    "group": null,
    "limit": 200,
    "skip": 400,
    "sortBy": "timestamp",
    "sortOrder": "desc",
    "selectors": [],
    "optimizeSearch": true
  }'
```

### Pagination Formula

To calculate the `skip` value for any page:

```
skip = (page_number - 1) × limit
```

Where:

* `page_number` is the page you want to retrieve (1, 2, 3, ...)
* `limit` is your page size

**Examples:**

* Page 1 with limit 200: `skip = (1 - 1) × 200 = 0`
* Page 2 with limit 200: `skip = (2 - 1) × 200 = 200`
* Page 3 with limit 200: `skip = (3 - 1) × 200 = 400`
* Page 1 with limit 50: `skip = (1 - 1) × 50 = 0`
* Page 5 with limit 50: `skip = (5 - 1) × 50 = 200`

### Determining When to Stop

The response includes a `limitReached` field that indicates whether the result limit was reached:

```json
{
  "logs": [...],
  "limitReached": true,
  "done": true,
  ...
}
```

* If `limitReached: true`, there may be more results available. Continue to the next page.
* If `limitReached: false` and you received fewer results than your `limit`, you've reached the end of the results.

### Best Practices

1. **Consistent Page Size**: Use the same `limit` value for all pages in a pagination sequence to ensure consistent results.
2. **Reasonable Limits**: Choose a `limit` value that balances performance and usability. Common values are 50, 100, or 200.
3. **Sort Order**: Always use the same `sortBy` and `sortOrder` parameters across all pages to maintain consistent ordering.
4. **Time Range**: Keep the same `start` and `end` time range across all pages to ensure you're paginating through the same dataset.
5. **Filtering**: If using the `group` parameter for filtering, use the same `group` conditions across all pages to maintain consistent filtering.
6. **Error Handling**: Implement retry logic and error handling for pagination requests, as network issues can occur between pages.
7. **Check limitReached**: Use the `limitReached` field in the response to determine if more pages are available.

### Example: Pagination Loop

Here's a pseudo-code example of how to implement pagination:

```python
page_size = 200
skip = 0
all_logs = []

while True:
    response = query_logs(limit=page_size, skip=skip)
    logs = response['logs']
    all_logs.extend(logs)
    
    # Check if we've reached the end
    if not response['limitReached'] or len(logs) < page_size:
        break
    
    # Move to next page
    skip += page_size
```

### Pagination with Filtering

When using pagination with filtered queries (using the `group` parameter), ensure you use the same `group` conditions across all pages to maintain consistent filtering:

```bash
# First page with filtering
curl 'https://app.groundcover.com/api/logs/v2/query' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "start": "2025-12-24T12:06:54.169Z",
    "end": "2025-12-24T18:06:54.169Z",
    "group": {
      "operator": "and",
      "conditions": [{
        "filters": [{"op": "match", "value": "error"}],
        "key": "level",
        "origin": "root",
        "type": "string"
      }]
    },
    "limit": 200,
    "skip": 0,
    "sortBy": "timestamp",
    "sortOrder": "desc",
    "selectors": [],
    "optimizeSearch": true
  }'

# Second page - same group conditions, different skip value
curl 'https://app.groundcover.com/api/logs/v2/query' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "start": "2025-12-24T12:06:54.169Z",
    "end": "2025-12-24T18:06:54.169Z",
    "group": {
      "operator": "and",
      "conditions": [{
        "filters": [{"op": "match", "value": "error"}],
        "key": "level",
        "origin": "root",
        "type": "string"
      }]
    },
    "limit": 200,
    "skip": 200,
    "sortBy": "timestamp",
    "sortOrder": "desc",
    "selectors": [],
    "optimizeSearch": true
  }'
```

**Important:** Keep the same `group`, `start`, `end`, `sortBy`, and `sortOrder` values across all pages to ensure consistent pagination through the same filtered dataset.


---

# Agent Instructions: 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:

```
GET https://docs.groundcover.com/use-groundcover/remote-access-and-apis/api-examples/query-logs/pagination.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
