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
/client/community/pagesNo auth/client/community/pages/:pageIdNo auth/client/community/pagesJWT/client/community/pages/:pageIdJWT/client/community/pages/mineJWT/client/community/pages/:pageId/joinJWT/client/community/pages/:pageId/leaveJWT/client/community/pages/:pageId/inviteJWT/client/community/pages/:pageId/membersNo auth/client/community/peopleNo auth/client/community/people/:emailNo authListing 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.
| Field | Type | Description |
|---|---|---|
| name* | string | Display name of the page. |
| type* | string | Page type — typical values are |
| category | string | Primary category. Used by the public listing filter. |
| description | string | Long-form description shown on the page header. |
| image | string | URL of the page header image. |
| visibility | string |
|
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.