Social guides
Guides

Post search.

Same Postgres FTS shape as user search, this time over post.title (weight A) + post.body (B). Pick relevance ranking or recency ordering with one query param. Drafts, removed, hidden, and expired posts are stripped at the SQL layer.


1

Search by relevance

Default mode. Returns up to limit hits (default 20, max 50) ordered by ts_rank. Title matches are weighted higher than body matches.

bash
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<communityId>/search/posts?q=phase+8&limit=10"

2

Or by recency

Same FTS filter, but ordered by created_at desc among matching rows. Useful when the user is asking “what's the newest mention of X” rather than “the best mention”. Any other value is a 400 INVALID_ORDER.

bash
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<communityId>/search/posts?q=phase+8&order=recent"

3

Paginate past the first page

Every response carries pagination: { next_cursor, has_more }; pass next_cursor back as ?cursor= to fetch the next page. Relevance pages by (rank, id), recent by (created_at, id). A cursor is bound to the exact (q, order) that produced it — reusing it against a different query simply restarts from page one.

bash
# page 1
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<c>/search/posts?q=phase+8&limit=25"
# → { data: [...], pagination: { next_cursor: "eyJ...", has_more: true } }

# page 2 — feed next_cursor back
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<c>/search/posts?q=phase+8&limit=25&cursor=eyJ..."

4

Filter to the requester's view

Without actor_id the caller is treated as anonymous: only visibility="public" posts from non-private authors surface. Pass an actor uuid to search as that actor — the same read rules a feed applies:

  • The requester's own posts always surface, whatever their visibility.
  • followers posts surface only with a follow edge to the author; close_friends only when the requester is on the author's close-friends list; private never surfaces to anyone else.
  • Posts authored by anyone the requester has muted / blocked — or who has blocked the requester — drop out.

Drafts, removed, hidden, and expired posts are stripped in SQL for every caller.

bash
curl -H "Authorization: Bearer pcft_live_..." \
  "https://social.productcraft.co/v1/communities/<communityId>/search/posts?q=phase+8&actor_id=<actorId>"

5

Response shape

json
{
  "data": [
    {
      "post": {
        "id": "...",
        "title": "Shipping Phase 8",
        "body": "stories live today",
        "kind": "text",
        "visibility": "public",
        "status": "published",
        "...": "..."
      },
      "rank": 0.6079
    }
  ],
  "pagination": { "next_cursor": "eyJ...", "has_more": true }
}

Out of scope

Follow-ups

  • Trigram fuzzy matching. Same trade- off as user search; deferred.
  • Cross-community search. Per-community only.

Permissions

PAK scopes

  • GET requires social.list on pcft:agora:community/<communityId>.