SpendRock Docs

Pagination

List transactions page by page with an opaque cursor.

Lists that can grow without bound are paginated with a cursor. Today that's GET /transactions. Other lists (households, members, invites, a month's groups and items) are small and come back whole.

Parameters

ParameterMeaning
limitPage size, 1 to 200. Default 100.
cursorWhere to continue. Omit it for the first page; then pass the previous response's next_cursor.

The response has the page's items plus next_cursor. When next_cursor is null (or missing), you've reached the end. Treat the cursor as an opaque string: don't parse or build it, and don't reuse it with different filters.

Example

# first page
curl -s "$SR_API/transactions?view=tracked&month=2026-12&limit=50" \
  -H "Authorization: Bearer $SR_TOKEN"
{
  "transactions": [ … 50 transactions, newest first … ],
  "next_cursor": "eyJkIjoiMjAyNi0xMi0wMyIsImkiOiIwMUpDWEs2UThXNk01VDdWM04yQjlSNFkxWiJ9",
  "untracked_count": 2
}
# next page: same filters, plus the cursor
curl -s "$SR_API/transactions?view=tracked&month=2026-12&limit=50&cursor=eyJkIjoi…" \
  -H "Authorization: Bearer $SR_TOKEN"

A loop that reads everything:

let cursor;
const all = [];
do {
  const url = new URL(`${SR_API}/transactions`);
  url.search = new URLSearchParams({ view: 'tracked', month: '2026-12', limit: '200' });
  if (cursor) url.searchParams.set('cursor', cursor);
  const res = await fetch(url, { headers: { Authorization: `Bearer ${SR_TOKEN}` } });
  const page = await res.json();
  all.push(...page.transactions);
  cursor = page.next_cursor;
} while (cursor);

Filters

GET /transactions needs a view: untracked, tracked, or deleted (the three tabs of the app's Transactions panel). month limits tracked to one budget month, and q searches by merchant (a case-insensitive substring) or by an exact amount such as 54.20. Results are newest first by date.

On this page