Documentation

Pages and profiles

Community pages, member profiles, and the public read endpoints behind them.

A page is a shared community space — an interest group, a brand fan club, a topic forum. Pages own posts, members, announcements and a category. A profile is the public-facing slice of a customer record — name, image, bio, company, social links — exposed by /client/community/people/:email.

Endpoints

GET/client/community/pagesNo auth
GET/client/community/pages/:pageIdNo auth
POST/client/community/pagesJWT
PUT/client/community/pages/:pageIdJWT
GET/client/community/pages/mineJWT
POST/client/community/pages/:pageId/joinJWT
POST/client/community/pages/:pageId/leaveJWT
POST/client/community/pages/:pageId/inviteJWT
GET/client/community/pages/:pageId/membersNo auth
GET/client/community/peopleNo auth
GET/client/community/people/:emailNo auth

Listing pages

GET /client/community/pages accepts type, category, q (search), limit and page query params. The response is the standard paginated { data, total } shape used across the customer API.

const res = await fetch('/client/community/pages?category=design&limit=20', {
  headers: { orgid: 'my-org' },
});
const { data, total } = await res.json();

Creating a page

The currently authenticated customer becomes the owner. The body is a free-form page payload — minimum is name, type, and category.

FieldTypeDescription
name*string

Display name of the page.

type*string

Page type — typical values are community, brand, event, topic.

categorystring

Primary category. Used by the public listing filter.

descriptionstring

Long-form description shown on the page header.

imagestring

URL of the page header image.

visibilitystring

public (default), private, or invite-only.

await fetch('/client/community/pages', {
  method: 'POST',
  headers: {
    orgid: 'my-org',
    Authorization: `Bearer ${customerJwt}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Type Designers',
    type: 'community',
    category: 'design',
    description: 'A space for typography enthusiasts.',
    visibility: 'public',
  }),
});

The service backfills owner and ownerEmail from the JWT — you cannot override them.

Membership

POST /pages/:pageId/join adds the caller as a member. POST /pages/:pageId/leave removes them. POST /pages/:pageId/invite lets a caller invite another email by passing { email } in the body. The members collection records each membership with a source (request, invitation, auto) and an optional inviter.

GET /pages/:pageId/members is public and supports role, limit and page. Use it to render a member list on the page header.

Profiles

Profiles aren't a separate collection — they're the safe-public slice of the customer record. GET /client/community/people/:email returns:

{
  "email": "[email protected]",
  "firstName": "Alice",
  "lastName": "Lee",
  "image": "https://cdn/.../avatar.png",
  "company": "Acme",
  "jobTitle": "Designer",
  "bio": "...",
  "city": "Berlin",
  "country": "DE",
  "interests": ["typography", "ui"],
  "social": { "twitter": "@alice", "linkedin": "..." }
}

Sensitive fields (phone, addresses, payment refs) are stripped server-side — even an authenticated caller only ever sees the public projection through this endpoint. To edit your own profile, write to the customer record via PUT /client-account/profile (see Client account).

People search

GET /client/community/people?q=alice performs a global member search. When you pass ?page=<pageId> it scopes the search to that page's members. The response shape is { data, total }.

The current build returns an empty global search result without a q term — pass a query or scope to a page to get matches.