Skip to content
Last updated

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).

ParameterTypeDefaultDescription
pageinteger0Zero-based page index. Page 0 = first page, page 1 = second page, etc.
limitinteger20Records per page. Maximum: 100

Endpoints That Support Pagination

EndpointPagination paramsTotal field
GET /v1/eventCallspage, limitdata.count
GET /v1/fields/objectspage, limitcount, hasMore, nextPage
GET /v1/dealspage, limitvaries
GET /v1/transactionspage, limitvaries

Response Shapes

GET /v1/eventCalls

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

Calculate whether there are more pages:

hasMore = (page + 1) * limit < count

GET /v1/fields/objects

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

Use hasMore and nextPage directly.


Fetching All Records

Python — GET /v1/eventCalls

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

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:

ParameterTypeDescription
eventTypeenumPAST, UPCOMING, or ALL
dateFromstringStart of date range (inclusive)
dateTostringEnd of date range (inclusive)
idsstringComma-separated call IDs
userIdsstringComma-separated closer user IDs
eventIdsstringComma-separated event template IDs
outcomesstringComma-separated: WON, NO_SALE, QUALIFIED, UNQUALIFIED, PENDING, APPROVED, REJECTED, PENDING_OUTCOME
typesstringComma-separated: scheduled_events, rescheduled_events, cancelled_events
callTypesstringComma-separated: STRATEGY_EVENT, DISCOVERY_EVENT
inviteeEmailsstringComma-separated invitee email addresses
searchstringFree-text search across name, email, and phone
setterIdsstringComma-separated setter user IDs
contactIdintegerFilter by a single contact ID
previewIdstringFilter 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 — Response field schemas
  • API Reference — Full query parameter reference per endpoint
  • Webhooks — Use webhooks to avoid polling list endpoints altogether