API Pagination
Cursor pagination is the preferred contract for new or externally consumed list endpoints. Existing endpoints are not assumed to share one envelope; preserve their published response shape unless the endpoint is versioned or all consumers are migrated together.
Standard Contract
Section titled “Standard Contract”Endpoints adopting the shared web pagination helpers return:
{ "items": [], "nextCursor": null, "limit": 20}cursoris an opaque value previously returned asnextCursor.limitis validated and capped by the backend.nextCursor: nullmeans there is no next page.- Clients must not parse, construct, or persist assumptions about cursor encoding.
Some established APIs use a resource-specific item field or snake_case. Those shapes remain endpoint contracts; do not normalize them only in documentation.
Web Helpers
Section titled “Web Helpers”apps/web/src/lib/paginated-fetch.tsprovidesfetchPage<T>for stores and callers that own their merge/cache behavior.apps/web/src/hooks/use-paginated-query.tsprovidesusePaginatedQuery<T>for components that need loading, refresh, and load-more state.
Both helpers expect the standard items, nextCursor, and limit envelope.
Use a domain adapter when an established endpoint returns a different shape.
Build a7f47a5ca54ddcf7806cd48b81ce1b9827042766