Skip to main content
The API pages a list with an opaque keyset cursor, not an offset. Ask for a page. Read page.next_cursor. Send it back unchanged. If it is null, stop.
The next page is the same request with cursor= added. Change nothing else:
returned is how many rows this page holds. A short page is not the end of the list. A null cursor is the end. Do not compute a page count: the API never counts the whole set for you. summary, where a route has one, is the totals over the filtered set. It is not a row count you can page through.

Page sizes

These are the API’s own maxima. On api.investorlift.com, the API lowers a limit above your plan’s largest page to that page before the request runs. page.limit says what the API used. Plans and limits has the page per plan. /v1/investors/search and the other name searches are ranked lookups, not lists. They return at most 50 hits, and page.next_cursor is always null. page.capped is true when more names matched than limit allowed, and the API cut the page there.

What kills a cursor

The API issues a cursor for one query against one build of the data. The cursor encodes the dataset version of every market it touched, a fingerprint of the query, and the sort keys of the last row. Any change to those makes it undecodable, and the API answers 400 invalid_cursor for the next page:
  • The data refreshed while you paged. The dataset version moved, so the row order is no longer the one you walked.
  • You changed a filter, the geometry, the sort, the ranking weights or w_activity between pages.
  • You sent a cursor from a different endpoint.
The only recovery is to restart from page 1 without the cursor. The error says so. A change of limit alone is safe: the limit is not part of the fingerprint.
Cursors are opaque. Their contents are an implementation detail and will change. Read next_cursor and pass it back. Never parse or construct one.

Sort order

sort= fixes the order a cursor walks. Deals take distance, date_desc or date_asc, and price_desc or price_asc. distance is the default when you gave a point, and sorts nearest first. date_desc is the default with a bbox alone. Investors take events_desc (the default), parcels_desc, volume_desc, last_bought_desc, last_deal_desc, flips_desc or holds_desc (the holdings inside the geometry). Rows with a null key sort last in both directions. So an undated deal stays at the tail if you asked for oldest first or for newest first. An unpriced one does the same. For sort=distance without a reference point, the API answers 400 sort_requires_point.