download the app
§ Conventions

Pagination

All list endpoints use cursor-based pagination. There are no page numbers, no offsets, and no total counts — just a stable opaque cursor and a fixed limit.

How it works

Pass limit (default 25, max 100). The response includes a data array and a nextCursor. When nextCursoris null, you've reached the end.

First pagebash
curl "https://livesofthesaintscalendar.com/api/v1/saints?limit=25" \
  -H "Authorization: Bearer osc_live_…"
jsonjson
{
  "data": [ /* 25 saints */ ],
  "nextCursor": "saint-john-chrysostom"
}
Next pagebash
curl "https://livesofthesaintscalendar.com/api/v1/saints?limit=25&cursor=saint-john-chrysostom" \
  -H "Authorization: Bearer osc_live_…"

Looping through everything

javascriptjavascript
let cursor = undefined;
const all = [];
do {
  const url = new URL("https://livesofthesaintscalendar.com/api/v1/saints");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.LOTS_API_KEY}` },
  });
  const page = await res.json();
  all.push(...page.data);
  cursor = page.nextCursor;
} while (cursor);

Stability

Cursors are stable for at least 24 hours. If you re-run a paginated walk after a long delay and a row was deleted, you may skip the immediate next slug — re-fetch the first page if you need a strict snapshot.