Documentation

Follows and connections

One-way follows for content, two-way connections for relationships.

Community supports two distinct relationship models. Follows are one-way subscriptions to a person or page — like Twitter follows or Facebook page likes. Connections are two-way handshakes — like LinkedIn connections — where both sides must confirm. Pick whichever matches your social model; you can use both at once if you need to.

Follows

A follow is a one-way edge from the current customer to a target email or pageId. No approval needed.

POST/client/community/followJWT
DELETE/client/community/follow/:followingIdJWT
GET/client/community/followersJWT
GET/client/community/followingJWT
// Follow a person
await fetch('/client/community/follow', {
  method: 'POST',
  headers: { orgid: 'my-org', Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    following: '[email protected]',
    followingType: 'person', // 'person' | 'page'
  }),
});

// Follow a page
await fetch('/client/community/follow', {
  method: 'POST',
  headers: { orgid: 'my-org', Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    following: 'page-id-here',
    followingType: 'page',
  }),
});

GET /followers returns who follows you. GET /following?followingType=person returns who/what you follow. Both are paginated by limit + page.

Connections

A connection is a request → response handshake. Either side can cancel; once accepted both sides see the connection in their list. This lives on the staff-facing controller because connections are typically used for B2B-style member networks where status (pending, accepted, rejected) matters operationally.

POST/community/connections/requestJWT
PUT/community/connections/:id/respondJWT
GET/community/connectionsJWT
GET/community/connections/pendingJWT
GET/community/connections/sentJWT
GET/community/connections/statsJWT
POST/community/connections/accept-allJWT
DELETE/community/connections/:idJWT

The same set is mirrored at /client/community/connections/* for customer-token usage.

// Send a request
await fetch('/community/connections/request', {
  method: 'POST',
  headers: { orgid: 'my-org', Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    targetId: '[email protected]',
    message: 'Hi Bob — saw your design talk.',
    context: { event: 'figma-conf-2026' },
  }),
});

// Respond
await fetch(`/community/connections/${connectionId}/respond`, {
  method: 'PUT',
  headers: { orgid: 'my-org', Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ action: 'accept' }), // 'accept' | 'reject'
});

Connection states and stats

A connection record carries status (pending, accepted, rejected), requesterEmail, targetEmail, optional message, optional context, and timestamps for request/response. GET /connections/stats returns counts by status — useful for a dashboard widget.

{
  "total": 124,
  "accepted": 98,
  "pending": 12,
  "sent": 14
}

Mutual connections

There is no first-class mutual endpoint. To find mutuals between yourself and another person, fetch both /connections?status=accepted lists and intersect them client-side, or run a Dynamic Query over community_connection joining on email. For high-traffic UIs, denormalise — write a mutuals array to the customer record on each accept event.

Side effects

  • Accepting a connection emits an event used by Sync to send a notification template (in-app + optional email).
  • A new follow from a customer to a community page increments the page's followerCount denormalised counter.
  • Both follows and connections are checked when computing feed visibility for visibility: 'connections' posts — only accepted connections see those posts.