Pagination
List endpoints use cursor-based pagination to efficiently page through large result sets.
How It Works
Section titled “How It Works”- Make your first request with an optional
limit - If there are more results, the response includes a
next_cursor - Pass
next_cursorascursorin your next request - Repeat until
next_cursoris empty or absent
Example
Section titled “Example”First page:
curl -X POST https://api.driftwoodapp.com/api/contacts-list \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"limit": 25}'{ "ok": true, "result": { "items": [ ... 25 contacts ... ], "next_cursor": "MjAyNS0wNi0wMVQxMjowMDowMFp8NTUwZTg0MDA..." }}Next page:
curl -X POST https://api.driftwoodapp.com/api/contacts-list \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "limit": 25, "cursor": "MjAyNS0wNi0wMVQxMjowMDowMFp8NTUwZTg0MDA..." }'Last page (no more results):
{ "ok": true, "result": { "items": [ ... 12 contacts ... ], "next_cursor": "" }}Detecting the last page
Section titled “Detecting the last page”Keep requesting the next page until next_cursor is empty. A non-empty next_cursor means there are more results; an empty string (""), null, or a missing next_cursor all mean you have reached the end — stop paginating.
The safest check works across all three cases (truthiness):
cursor = ""while True: res = post("/api/contacts-list", {"cursor": cursor, "limit": 100})["result"] process(res["items"]) cursor = res.get("next_cursor") if not cursor: # "" , None, or absent → done breakDo not loop on a fixed page count — always drive the loop off next_cursor.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | string | – | Pagination cursor from a previous response. Omit or send "" for the first page. |
limit | integer | 25 | Number of items per page (max varies by endpoint) |
Ordering
Section titled “Ordering”Results are ordered by created_at descending (newest first). The cursor encodes both the timestamp and record ID to ensure stable pagination even when new records are created between pages.
Iterating All Records
Section titled “Iterating All Records”def get_all_contacts(token): contacts = [] cursor = None while True: body = {"limit": 100} if cursor: body["cursor"] = cursor result = driftwood_api("contacts-list", token, body) contacts.extend(result["items"]) cursor = result.get("next_cursor") if not cursor: break return contactsEndpoints Using Cursor Pagination
Section titled “Endpoints Using Cursor Pagination”contacts-listcompanies-listprojects-listactivities-listinbound-emails-listimports-errors