Skip to content

Pagination

Some endpoints return long lists. They return the list one page at a time.

These endpoints are paginated:

Endpoint Order
GET /templates Most recently updated first.
GET /contacts By phone number.
GET /tags Oldest first (by id).
GET /campaigns Newest first (by id).

GET /phone-numbers returns all your numbers in one response.

Send these as query parameters:

Parameter Default Rules
page 1 The page number, starting at 1. A value below 1, or a value that is not a number, is treated as 1.
limit 50 Items per page, at most 200. A larger value is treated as 200. A missing, zero or non-numeric value is treated as 50. A negative value is treated as 1.

Send whole numbers in range. Other values are not rejected, but they are not always replaced by the nearest allowed value:

  • On GET /tags, GET /contacts and GET /campaigns, a fractional value is first cut to a whole number (2.7 becomes 2, 0.5 becomes 0), and then the rules above apply.
  • On GET /templates, fractional values are not cut. A limit between 0 and 1 becomes 1, and a fractional limit or page above 1 can fail with 500 templates_lookup_failed.

The response repeats the page and limit that were used, and the items are in data:

{
"success": true,
"page": 2,
"limit": 50,
"data": [
{ "name": "order_update", "language": "en", "category": "UTILITY", "status": "APPROVED", "waba_id": "200000000000002", "components": [] }
]
}

The response does not include a total count or a “next page” link.

Request page 1, then 2, then 3, and so on. Stop when a page has fewer items than limit. That is the last page. If the total is an exact multiple of limit, the page after the last full page is empty; stop there too.

async function listAllTemplates() {
const limit = 200;
const all = [];
for (let page = 1; ; page++) {
const url = `https://api.sanadwa.com/v1/templates?page=${page}&limit=${limit}`;
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.SANADWA_API_KEY}` },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const { data } = await res.json();
all.push(...data);
if (data.length < limit) return all;
}
}

If items are added, changed or deleted while you are reading pages, items can move between pages: you may see an item twice or miss one. For example, templates are sorted by last update, so a template that is approved while you read moves to the first page. If you need a complete list, read all pages quickly and remove duplicates: by id for contacts, tags and campaigns, and by name, language and waba_id for templates.

Every page counts toward your rate limit. Use limit=200 to make fewer requests.