# Pagination

List endpoints support pagination so you can work through large datasets in pages.

## How Pagination Works

iClosed uses **page-based pagination** (not offset). Pass `page` (zero-based index) and `limit` (records per page).

| Parameter | Type | Default | Description |
|  --- | --- | --- | --- |
| `page` | integer | `0` | Zero-based page index. Page 0 = first page, page 1 = second page, etc. |
| `limit` | integer | `20` | Records per page. Maximum: `100` |


## Endpoints That Support Pagination

| Endpoint | Pagination params | Total field |
|  --- | --- | --- |
| `GET /v1/eventCalls` | `page`, `limit` | `data.count` |
| `GET /v1/fields/objects` | `page`, `limit` | `count`, `hasMore`, `nextPage` |
| `GET /v1/deals` | `page`, `limit` | varies |
| `GET /v1/transactions` | `page`, `limit` | varies |


## Response Shapes

### `GET /v1/eventCalls`

```json
{
  "data": {
    "eventCalls": [ ... ],
    "count": 248
  }
}
```

Calculate whether there are more pages:

```
hasMore = (page + 1) * limit < count
```

### `GET /v1/fields/objects`

```json
{
  "count": 45,
  "data": [ ... ],
  "hasMore": true,
  "nextPage": 1
}
```

Use `hasMore` and `nextPage` directly.

## Fetching All Records

### Python — `GET /v1/eventCalls`

```python
import requests

BASE_URL = 'https://public.api.iclosed.io'
HEADERS  = {'Authorization': 'Bearer iclosed_YOUR_API_KEY'}

def get_all_calls(event_type='ALL', limit=100):
    all_calls = []
    page = 0

    while True:
        resp = requests.get(
            f'{BASE_URL}/v1/eventCalls',
            headers=HEADERS,
            params={'eventType': event_type, 'limit': limit, 'page': page}
        )
        resp.raise_for_status()
        body = resp.json()['data']

        all_calls.extend(body['eventCalls'])
        total = body['count']
        print(f"Fetched {len(all_calls)} of {total}")

        if len(all_calls) >= total:
            break
        page += 1

    return all_calls
```

### Node.js — `GET /v1/eventCalls`

```javascript
const BASE_URL = 'https://public.api.iclosed.io';
const HEADERS  = { 'Authorization': 'Bearer iclosed_YOUR_API_KEY' };

async function getAllCalls(eventType = 'ALL', limit = 100) {
  const allCalls = [];
  let page = 0;

  while (true) {
    const url = `${BASE_URL}/v1/eventCalls?eventType=${eventType}&limit=${limit}&page=${page}`;
    const { data } = await fetch(url, { headers: HEADERS }).then(r => r.json());

    allCalls.push(...data.eventCalls);
    console.log(`Fetched ${allCalls.length} of ${data.count}`);

    if (allCalls.length >= data.count) break;
    page++;
  }

  return allCalls;
}
```

## Filtering on List Endpoints

`GET /v1/eventCalls` supports rich filtering alongside pagination:

| Parameter | Type | Description |
|  --- | --- | --- |
| `eventType` | enum | `PAST`, `UPCOMING`, or `ALL` |
| `dateFrom` | string | Start of date range (inclusive) |
| `dateTo` | string | End of date range (inclusive) |
| `ids` | string | Comma-separated call IDs |
| `userIds` | string | Comma-separated closer user IDs |
| `eventIds` | string | Comma-separated event template IDs |
| `outcomes` | string | Comma-separated: `WON`, `NO_SALE`, `QUALIFIED`, `UNQUALIFIED`, `PENDING`, `APPROVED`, `REJECTED`, `PENDING_OUTCOME` |
| `types` | string | Comma-separated: `scheduled_events`, `rescheduled_events`, `cancelled_events` |
| `callTypes` | string | Comma-separated: `STRATEGY_EVENT`, `DISCOVERY_EVENT` |
| `inviteeEmails` | string | Comma-separated invitee email addresses |
| `search` | string | Free-text search across name, email, and phone |
| `setterIds` | string | Comma-separated setter user IDs |
| `contactId` | integer | Filter by a single contact ID |
| `previewId` | string | Filter by call preview ID |


**Example — get all WON calls from April 2026:**

```
GET /v1/eventCalls?eventType=PAST&dateFrom=2026-04-01&dateTo=2026-04-30&outcomes=WON&limit=100&page=0
```

## See Also

- [Data Models](/docs/api-reference) — Response field schemas
- [API Reference](https://api-docs-iclosed.redocly.app/openapi/v1/openapi) — Full query parameter reference per endpoint
- [Webhooks](/docs/webhooks/introduction) — Use webhooks to avoid polling list endpoints altogether