Pagination
List endpoints return pages. Each page gives you a cursor for the next one, so a record added while you page through never makes you skip or repeat one. Records come oldest first, or in the order you ask for with sort.
| Parameter | What it does |
|---|---|
limit | Records per page, 1 to 100. Default 25. |
cursor | The next_cursor from the previous page. Leave it out for the first page. |
sort | Contacts, companies and deals: one field, with - in front for newest or largest first. See Sorting. |
updated_since | Contacts only: records changed at or after this time (ISO 8601). |
The list shape
{
"data": [
"…up to limit records…"
],
"has_more": true,
"next_cursor": "66f2a1c0e4b0a1b2c3d4e5f6"
}On the last page has_more is false and there is no next_cursor.
Without sort, records come in the order they were created in, and a cursor is the id of the last record on the page. A cursor never expires.
Sorting
Lists and searches of contacts, companies and deals take sort: one field, oldest or smallest first, or with - in front for newest or largest first. Searches take it in the body. Records with the same value keep the order they were created in, and records with no value come first ascending and last descending.
| Records | Sort on |
|---|---|
| Contacts | created_at, updated_at |
| Companies | created_at, updated_at, employee_count |
| Deals | created_at, updated_at, amount, expected_close_date, closed_at |
curl "https://api.useworkloom.com/api/public/v1/deals?status=open&sort=-amount&limit=10" \
-H "Authorization: Bearer $WORKLOOM_KEY"const res = await fetch("https://api.useworkloom.com/api/public/v1/deals?status=open&sort=-amount&limit=10", {
headers: { Authorization: `Bearer ${process.env.WORKLOOM_KEY}` },
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://api.useworkloom.com/api/public/v1/deals",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
params={"status": "open", "sort": "-amount", "limit": 10},
)
deals = res.json()["data"]Keep the same sort while you follow next_cursor. A sorted cursor holds the last record’s value and id, so it only works with the sort that made it; one used with another sort is refused with invalid_request. Only dates and numbers sort. Sort names on your side.
let cursor = null;
const all = [];
do {
const qs = new URLSearchParams({ limit: "100", ...(cursor && { cursor }) });
const res = await fetch(`https://api.useworkloom.com/api/public/v1/contacts?${qs}`, {
headers: { Authorization: `Bearer ${process.env.WORKLOOM_KEY}` },
});
const page = await res.json();
all.push(...page.data);
cursor = page.has_more ? page.next_cursor : null;
} while (cursor);import os, requests
url = "https://api.useworkloom.com/api/public/v1/contacts"
headers = {"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"}
params = {"limit": 100}
contacts = []
while True:
page = requests.get(url, headers=headers, params=params).json()
contacts += page["data"]
if not page["has_more"]:
break
params["cursor"] = page["next_cursor"]For a nightly contact sync, store the time you started and pass it as updated_since next time, so you only fetch what changed.