Reference
Pagination
Page through Emailit API list endpoints with page and limit, read next_page_url, handle the per_page and offset formats and the email and event time windows.
List endpoints return results one page at a time. Most of them use page numbers with page and limit, templates and automations use page and per_page, and DMARC endpoints use limit and offset. This page explains each format, the time windows on the email and event lists, and how to loop through every page.
Page and limit
Most list endpoints accept two query parameters:
| Parameter | Description |
|---|---|
page |
The page to return, starting at 1. Default 1. |
limit |
Objects per page, from 1 to 100. Values outside that range return a 400 validation error. |
The default page size depends on the endpoint:
Default limit |
Endpoints |
|---|---|
| 10 | Domains, API keys, audiences, contacts, campaigns, forms, suppressions, webhooks, email verification lists |
| 25 | Emails, subscribers |
| 50 | Email verification list results |
| 100 | Events |
List subscribers also accepts per_page as an alias for limit.
Response
{
"data": [
{ "object": "domain", "id": "dom_4K468YrjOkR1wwdhqiO0G9XEUey", "name": "acme.com" }
],
"next_page_url": "/v2/domains?page=3&limit=10",
"previous_page_url": "/v2/domains?page=1&limit=10"
}| Field | Description |
|---|---|
data |
The objects on this page, newest first unless you sort them. |
next_page_url |
Path of the next page, or null on the last page. |
previous_page_url |
Path of the previous page, or null on the first page. |
The page URLs are paths, not full URLs, and on most endpoints they only carry page and limit, not your filters. To fetch the next page, repeat your own request with page increased by one, and stop when next_page_url is null.
Some lists add fields next to data:
| Field | Endpoints | Contains |
|---|---|---|
total_records |
Contacts, audiences, campaigns, forms | The number of objects that match, across all pages. |
usage |
Webhooks | used and limit webhook endpoints for your plan, and filters_allowed. |
usage |
Subscribers | used and limit subscribers for the audience, and the plan. |
domain_limit, domain_count, plan_name |
Domains | How many sending domains your plan allows (null means no limit), how many you have, and the plan name. |
Page and per_page
List templates, List automations and List runs use per_page instead of limit and return page counts instead of page URLs:
| Parameter | Description |
|---|---|
page |
The page to return, starting at 1. Default 1. |
per_page |
Objects per page, from 1 to 100. Default 25. |
{
"data": [],
"total_records": 42,
"per_page": 25,
"current_page": 2,
"total_pages": 2
}Keep requesting pages while current_page is less than total_pages.
Limit and offset
The DMARC endpoints skip a number of rows instead of counting pages:
| Parameter | Description |
|---|---|
limit |
Rows to return. Reports: default 25, maximum 100. Sources, countries, networks and reporters: default 50, maximum 200. |
offset |
Rows to skip. Default 0. |
List aggregate reports and List forensic reports return the total count, so you know when to stop:
{
"data": [],
"meta": { "total": 130, "limit": 25, "offset": 50 }
}The breakdown endpoints return meta with limit and offset only. Stop when a page has fewer rows than limit.
Time windows
Two lists only look at recent data unless you ask for more:
- Emails. List emails returns emails from the last 14 days by default. Pass
date_from(and optionallydate_to) as a date such as2026-08-01to search further back.created_atfilters don’t widen the window, so usedate_from. - Events. List events returns events from the last two days by default. Any
created_atfilter, such ascreated_at.after=2026-09-01, replaces that window. The list also stops at an offset of 2,500: a page that starts beyond the 2,500th event returns422with the codeevents_offset_too_large. Narrow the results withtypeorcreated_atfilters to reach older events.
Fetch every page
Loop until the API says there’s no next page. These examples collect every contact in an audience:
page=1
while : ; do
response=$(curl -s -G https://api.emailit.com/v2/contacts \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
--data-urlencode "audience_id=aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2" \
--data-urlencode "limit=100" \
--data-urlencode "page=$page")
echo "$response" | jq -c '.data[]'
[ "$(echo "$response" | jq -r '.next_page_url')" = "null" ] && break
page=$((page + 1))
doneasync function* listAll(path, params = {}) {
for (let page = 1; ; page++) {
const query = new URLSearchParams({ ...params, limit: '100', page: String(page) });
const response = await fetch(`https://api.emailit.com/v2${path}?${query}`, {
headers: { Authorization: `Bearer ${process.env.EMAILIT_API_KEY}` },
});
if (!response.ok) throw new Error(`Emailit ${response.status}`);
const body = await response.json();
yield* body.data;
if (!body.next_page_url) return;
}
}
for await (const contact of listAll('/contacts', { audience_id: 'aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2' })) {
console.log(contact.email);
}import os
import requests
def list_all(path, params=None):
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['EMAILIT_API_KEY']}"
page = 1
while True:
response = session.get(
f"https://api.emailit.com/v2{path}",
params={**(params or {}), "limit": 100, "page": page},
timeout=30,
)
response.raise_for_status()
body = response.json()
yield from body["data"]
if not body["next_page_url"]:
return
page += 1
for contact in list_all("/contacts", {"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2"}):
print(contact["email"])Consistent results
Pages are computed when you request them. If objects are created or deleted while you page through a newest-first list, objects can move between pages, so you might see one twice or miss one. For a stable export of a list that keeps growing, sort oldest first with order=created_at&direction=asc (or sort=created_at&order=asc on contacts and suppressions), and skip IDs you’ve already seen.