Actor lists & list feeds.
X-style lists. An actor curates a set of other actors — private for themselves or public for anyone — and reads a dedicated feed of just those members' posts, chronological or ranked.
1
Create a list
Lists default to private (owner-only). Pass visibility: "public" to make the list and its member roster discoverable by anyone in the community.
A list has no natural key — one owner can hold many same-named lists — so send an Idempotency-Key header to make retries safe.
curl -X POST -H "Authorization: Bearer pcft_live_..." \
-H "content-type: application/json" -H "Idempotency-Key: <uuid>" \
-d '{
"owner_id": "<owner-actor-uuid>",
"name": "Tech news",
"description": "Curated tech accounts I follow.",
"visibility": "public"
}' \
"https://social.productcraft.co/v1/communities/<communityId>/lists"{
"id": "<list-uuid>",
"community_id": "<community-uuid>",
"owner_id": "<owner-actor-uuid>",
"name": "Tech news",
"description": "Curated tech accounts I follow.",
"visibility": "public",
"member_count": 0,
"created_at": "2026-05-01T12:00:00.000Z",
"updated_at": "2026-05-01T12:00:00.000Z"
}2
Manage members
Membership is owner-managed (adds carry caller_actor_id in the body, removals pass ?actor_id= — both must equal the owner) and block-aware: adding a member with whom the owner has a block — in either direction — returns 409. Adds are idempotent; re-adding an existing member returns the row again. Removal is idempotent too — 204 even if the actor wasn't a member.
# Add a member (owner-only)
curl -X POST -H "Authorization: Bearer pcft_live_..." \
-H "content-type: application/json" \
-d '{ "caller_actor_id": "<owner>", "actor_id": "<member>" }' \
"https://social.productcraft.co/v1/communities/<communityId>/lists/<listId>/members"
# Remove a member (idempotent 204)
curl -X DELETE -H "Authorization: Bearer pcft_live_..." \
"https://social.productcraft.co/v1/communities/<communityId>/lists/<listId>/members/<member>?actor_id=<owner>"
# Page through the roster
curl -H "Authorization: Bearer pcft_live_..." \
"https://social.productcraft.co/v1/communities/<communityId>/lists/<listId>/members?actor_id=<viewer>&limit=50"3
Discover lists
GET /lists returns the community's public catalog, cursor-paginated. Pass actor_id to surface that viewer's own private lists alongside it, and owner_actor_id to filter to one owner's lists (a "their lists" profile tab). Fetching a private list by id 404s unless actor_id is the owner — privacy is opaque, not a 403.
curl -H "Authorization: Bearer pcft_live_..." \
"https://social.productcraft.co/v1/communities/<communityId>/lists?actor_id=<viewer>&limit=20"4
Read the list feed
The payoff: a feed of posts authored by the list's members. actor_id is required — it drives visibility filtering (followers-only / close-friends posts appear only when the viewer qualifies) and excludes authors involved in a block with the viewer. Default order is chronological; pass order=ranked for the same engagement-blended scoring as the home feed (tunable via community settings). Same { data, pagination } envelope, and cursors are not interchangeable between the two orders.
curl -H "Authorization: Bearer pcft_live_..." \
"https://social.productcraft.co/v1/communities/<communityId>/lists/<listId>/feed?actor_id=<viewer>&order=chronological&limit=20"Permissions
PAK scopes
- Create list:
social.createonpcft:agora:list/*. - Update / delete / member mutations:
social.update/social.deleteon the list URN. - Reads (catalog, list, members, feed):
social.read/social.list.