Developers

Pagination

Page through long lists with limit and offset, and read the total that comes back.

Lists that can grow long (customers, jobs, invoices, payments, the event log and others) come back one page at a time.

Limit and offset

Send limit (how many to return) and offset (how many to skip) in the query string:

curl "https://app.servflo.ai/api/organizations/$ORGANIZATION_ID/invoices?limit=100&offset=200" \
  -H "Authorization: Bearer $SERVFLO_API_KEY"

The answer is an object with the page's items and the total number of matches across every page:

{
	"items": [{ "id": "…", "identifier": "INV-201" }],
	"total": 1342
}
  • limit is 50 when you leave it out. Most lists allow up to 200; each list's maximum is in the API reference.
  • offset starts at 0.
  • Keep going while offset + items.length < total.
  • Filters (status, query, dates …) apply before paging, so total counts only what matches.
async function allInvoices(organizationId) {
	const all = [];
	for (let offset = 0; ; offset += 200) {
		const response = await fetch(
			`https://app.servflo.ai/api/organizations/${organizationId}/invoices?limit=200&offset=${offset}`,
			{ headers: { Authorization: `Bearer ${process.env.SERVFLO_API_KEY}` } },
		);
		const page = await response.json();
		all.push(...page.items);
		if (offset + page.items.length >= page.total || page.items.length === 0) return all;
	}
}

Each list has a fixed order. If records are added or changed while you page, a record can shift to the next page. For a complete export, filter by a date range that has already ended, or use the list's CSV export where there is one.

Cursors

A few feeds that only grow use a cursor instead: a customer's timeline, the website and email image libraries, and team chat. Pass the nextCursor from one answer as cursor in the next call (team chat takes before, the time of the oldest message you have). When nextCursor is null, you have everything.

Short lists

Settings-style lists that stay small (service types, lead sources, custom fields, technicians, webhook endpoints) come back whole, as an array or an object without total. The reference shows which shape each endpoint returns.

On this page