Skip to main content

Pagination

All list endpoints in the Arsel API use cursor-based pagination. Cursors stay stable as new items are created or removed, and avoid the slow page-counts that offset pagination needs at scale.

Response Shape

Every paginated response has the same envelope:

{
"object": "list",
"has_more": true,
"data": [
/* page items */
]
}
FieldTypeDescription
objectstringAlways "list".
has_morebooleantrue when there are more items beyond the current page.
dataarrayThe items on this page.

There is no total, page, or totalPages — those numbers are expensive to compute at scale and rarely needed in practice. Use has_more to drive your "next page" logic.

Query Parameters

ParameterTypeDefaultDescription
limitnumber20Items per page (min: 1, max: 100).
afterstringReturn items after this id (exclusive). Use the id of the last item from the previous page to fetch the next one.
beforestringReturn items before this id (exclusive). Use the id of the first item from a page to walk backwards.
warning

You can't pass both after and before in the same request. Doing so returns 400 bad_request.

Order

Results are always returned newest first. There is no sort_by parameter.

Forward Pagination

Walk from newest to oldest by reading the last item's id and passing it as after:

# First page
curl "https://api.arsel.sa/v1/contacts?limit=50" \
-H "Authorization: Bearer be_your_api_key"

# Next page — use the id of the LAST item from the previous response
curl "https://api.arsel.sa/v1/contacts?limit=50&after=01957e3a-4b5c-7d8e-9f0a-1b2c3d4e5f6a" \
-H "Authorization: Bearer be_your_api_key"
async function* paginate(url, apiKey) {
let cursor = null;
while (true) {
const u = new URL(url);
u.searchParams.set("limit", "100");
if (cursor) u.searchParams.set("after", cursor);

const res = await fetch(u, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const page = await res.json();

for (const item of page.data) yield item;

if (!page.has_more) return;
cursor = page.data[page.data.length - 1].id;
}
}

for await (const contact of paginate(
"https://api.arsel.sa/v1/contacts",
"be_your_api_key",
)) {
console.log(contact.id, contact.email);
}

Backward Pagination

To walk from a known point toward newer items, pass the id of the first item from the page you have as before:

curl "https://api.arsel.sa/v1/contacts?limit=50&before=01957e3a-4b5c-7d8e-9f0a-1b2c3d4e5f6a" \
-H "Authorization: Bearer be_your_api_key"

Endpoints That Paginate

Every list endpoint in the API uses this shape:

  • GET /contacts
  • GET /lists
  • GET /tags
  • GET /templates
  • GET /templates/gallery
  • GET /properties
  • GET /email
  • GET /sms
  • GET /email/campaigns
  • GET /sms/campaigns

Single-resource endpoints (GET /contacts/:id, etc.) and operation endpoints (e.g., POST /lists/:id/contacts) are not paginated.

Errors

ErrorWhen
validation_errorlimit outside the 1–100 range, or invalid types.
bad_requestBoth after and before provided in the same request.