Index: src/routes/activitypub.js
===================================================================
--- src/routes/activitypub.js	(revision 732272a320793693be207b1b67af729b1feca30f)
+++ src/routes/activitypub.js	(revision 5e16b8aa5bff59005d55b10e60ba39fb7989e733)
@@ -1115,5 +1115,5 @@
      ORDER BY pinned DESC, COALESCE(published_at, created_at) ASC LIMIT 20`
   ).all(site.id);
-  AP.sendAP(res, AP.buildFeatured(baseUrl(req), site, posts));
+  AP.sendAP(res, AP.buildFeatured(baseUrl(req), site, posts, { page: paginaNr(req) }));
 });
 
@@ -1130,5 +1130,5 @@
   const site = publicSite(req.params.slug);
   if (!site) return res.status(404).end();
-  AP.sendAP(res, AP.listPlaylistsAP(baseUrl(req), site, wantsEnriched(req, res)));
+  AP.sendAP(res, AP.listPlaylistsAP(baseUrl(req), site, wantsEnriched(req, res), { page: paginaNr(req) }));
 });
 
@@ -1139,5 +1139,5 @@
   const site = publicSite(req.params.slug);
   if (!site) return res.status(404).end();
-  AP.sendAP(res, AP.buildTrackCollection(baseUrl(req), site, AP.siteOpenTracks(site.id, { alles: await magAlles(req, site.slug) })));
+  AP.sendAP(res, AP.buildTrackCollection(baseUrl(req), site, AP.siteOpenTracks(site.id, { alles: await magAlles(req, site.slug) }), { page: paginaNr(req) }));
 });
 
@@ -1150,8 +1150,14 @@
 // Openbaar, want alles erin is fedi_open. Er valt dus niets goed te keuren en de
 // volgerslijst blijft leeg: wie ons volgt volgt de ACTOR, niet de bak.
+//
+// `?page=` MOET hier doorgegeven worden. Zonder dat adverteert de wortel een
+// `first` die op zichzelf uitkomt: de lezer volgt hem, krijgt weer een `Library`
+// in plaats van een pagina, en klapt eruit -- open.audio gaf op 15-8 een 500 op
+// precies deze URL. Dezelfde les als bij de outbox (shaer-sk4): een `first`
+// beloven is een pagina beloven.
 router.get('/ap/users/:slug/library', (req, res) => {
   const site = publicSite(req.params.slug);
   if (!site) return res.status(404).end();
-  AP.sendAP(res, AP.buildLibrary(baseUrl(req), site, AP.siteOpenTracks(site.id)));
+  AP.sendAP(res, AP.buildLibrary(baseUrl(req), site, AP.siteOpenTracks(site.id), { page: paginaNr(req) }));
 });
 
@@ -1161,5 +1167,5 @@
   const site = publicSite(req.params.slug);
   if (!site) return res.status(404).end();
-  AP.sendAP(res, AP.pagedCollection(`${AP.libraryId(baseUrl(req), site)}/followers`, []));
+  AP.sendAP(res, AP.pagedCollection(`${AP.libraryId(baseUrl(req), site)}/followers`, [], { page: paginaNr(req) }));
 });
 
Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision 732272a320793693be207b1b67af729b1feca30f)
+++ src/services/ActivityPubService.js	(revision 5e16b8aa5bff59005d55b10e60ba39fb7989e733)
@@ -1200,8 +1200,8 @@
 // these as the "Featured" tab (pinned to the profile). Posts come ordered by pin
 // rank; embedded as full Notes so a remote server doesn't need extra fetches.
-export function buildFeatured(base, site, posts) {
+export function buildFeatured(base, site, posts, { page = false } = {}) {
   const id = `${actorId(base, site.slug)}/featured`;
   const items = (posts || []).map((p) => buildNote(base, site, p));
-  return pagedCollection(id, items);
+  return pagedCollection(id, items, { page });
 }
 
Index: src/services/music/index.js
===================================================================
--- src/services/music/index.js	(revision 732272a320793693be207b1b67af729b1feca30f)
+++ src/services/music/index.js	(revision 5e16b8aa5bff59005d55b10e60ba39fb7989e733)
@@ -247,9 +247,10 @@
  * ooit een besloten variant, dan hoort daar het Follow/Accept-werk bij.
  */
-export function buildLibrary(base, site, rows) {
+export function buildLibrary(base, site, rows, { page = false } = {}) {
   const id = libraryId(base, site);
   const hostPosts = site.id ? trackHostPosts(site.id) : null;
   const items = (rows || []).map((r) => buildTrackAudio(base, site, r, { hostPosts }));
   return pagedCollection(id, items, {
+    page,
     extra: {
       type: 'Library',
@@ -265,9 +266,9 @@
 
 /** De collectie van alle open tracks van een site (shaer-0nh, stap 3). */
-export function buildTrackCollection(base, site, rows) {
+export function buildTrackCollection(base, site, rows, { page = false } = {}) {
   // Eén zoekopdracht voor alle rijen samen; zie trackHostPosts.
   const posts = site.id ? trackHostPosts(site.id) : null;
   const items = (rows || []).map((r) => buildTrackAudio(base, site, r, { hostPosts: posts }));
-  return pagedCollection(`${actorId(base, site.slug)}/tracks`, items, { extra: { attributedTo: actorId(base, site.slug) } });
+  return pagedCollection(`${actorId(base, site.slug)}/tracks`, items, { page, extra: { attributedTo: actorId(base, site.slug) } });
 }
 
@@ -314,5 +315,5 @@
 // collectie zelf, want ook een lijst mag niet verklappen wat er achter de
 // poort staat.
-export function listPlaylistsAP(base, site, enriched) {
+export function listPlaylistsAP(base, site, enriched, { page = false } = {}) {
   const rows = db.prepare(
     'SELECT id, title, artist, year, cover_url FROM playlists WHERE site_id = ? ORDER BY created_at, id'
@@ -327,5 +328,5 @@
     return stub;
   });
-  return pagedCollection(colId, items, { extra: { attributedTo: actorId(base, site.slug) } });
+  return pagedCollection(colId, items, { page, extra: { attributedTo: actorId(base, site.slug) } });
 }
 
