Index: src/routes/activitypub.js
===================================================================
--- src/routes/activitypub.js	(revision da84110b6ca109b72d7666682dc52070dbb6b891)
+++ src/routes/activitypub.js	(revision 3e1aab1d0ca77fdf994b3cd2daa1b48e94c68d1b)
@@ -630,4 +630,19 @@
 });
 
+// ── Playlist als dereferenceerbare AP-collectie (shaer-ayc) ───────
+// De eerste stap van het Funkwhale-spoor: een playlist heeft een id, dus een
+// stabiele URI. Alleen het fedi_open-deel staat erin (de poort is per bestand
+// en eenrichtings; zie setAudioFediOpen in routes/posts.js) — een collectie
+// zonder open tracks bestaat wel maar is leeg, want de playlist zelf is niet
+// geheim, alleen de bestanden erachter.
+router.get('/ap/users/:slug/playlists/:id', (req, res) => {
+  const site = publicSite(req.params.slug);
+  if (!site) return res.status(404).end();
+  const pl = db.prepare('SELECT id, title, artist, year, cover_url, kind FROM playlists WHERE id = ? AND site_id = ?')
+    .get(req.params.id, site.id);
+  if (!pl) return res.status(404).end();
+  AP.sendAP(res, AP.buildPlaylistCollection(baseUrl(req), site, pl, AP.playlistOpenTracks(pl.id)));
+});
+
 // ── Note ──────────────────────────────────────────────────────────
 router.get('/ap/notes/:id', async (req, res) => {
