Outcome
Read the app’s local member roster and distinguish user identities, pending members and platform grants.
Action: app_topolo_socialize.brands.members.list.
Before you start
- Verify production, the original signed-in principal and intended organization. Socialize calls a canonical Auth workspace a brand; do not fabricate a brand id from a name or change the caller.
- Use only actual discovered workspace grants and the published action permission. API-key workspace bindings further narrow the grant; organization membership alone is insufficient. Keep resource context separate from action input.
- Published permission: app_topolo_socialize.accounts:read. No mutation confirmation is requested by the published read action, but source side effects below remain relevant.
Find the workspace
- Discover the actual brand/workspace id through supported workspace reads or brands.list. Bind the exact workspace and use its id, not a user or organization id, as action input.
Request
GET /api/brands/{id}/members
{
"id": "ws_socialize_example"
}
Input fields are exactly those in the current published action schema. id is required and must be the discovered workspace id.
For an authorized CLI operation, pin the actual context/environment, discover the workspace, then use the actual values in place of the placeholders below. These commands are illustrative and were not executed against Socialize.
TOPOLO_CONTEXT="org:<verified-org-id>" topolo --env production actions validate app_topolo_socialize.brands.members.list --data '<reviewed-input-json>' --json
TOPOLO_CONTEXT="org:<verified-org-id>" topolo --env production actions plan app_topolo_socialize.brands.members.list --resource-type workspace --resource-id '<verified-workspace-id>' --data '<reviewed-input-json>' --json
Interpret the response
- Returns a bare array of local membership projections. It does not wrap results in data/items or provide pagination.
- Suspended memberships are excluded. Active and pending rows can be returned, ordered by role owner/admin/member/viewer then joined_at ascending.
- Each id is the membership’s user_id, not the membership-row id or workspace id. email comes from the membership record, falling back to stripping an email: user-id prefix. name is a display fallback derived from email or a truncated user id, not a verified Auth display name.
- The projection includes role, status, joinedAt and invitedBy when present. Although the interface allows avatar/lastActiveAt, this mapping does not supply them.
- This roster is local Socialize state. It is not an Auth directory, complete platform-grant list, pending-invitation list or proof that each returned user can currently act.
Effects
- Although the published action is marked readOnly, requireBrandWorkspace/listBrandWorkspaces can insert a local brand mirror or reactivate/synchronize its organization/status. This is not a zero-SQL-write promise.
- The member query itself reads local non-suspended memberships. This route does not call the invitation/email membership reconciliation used by brands.list, and does not send invitations or change member roles.
Worked examples
Every example below is source-derived, synthetic and unrun. Placeholder ids, emails and timestamps confer no real authority. Returned shape illustrates the pinned handler; the published structural schema alone does not guarantee application semantics.
A local active member
Source-derived synthetic and unrun; example.invalid is placeholder email data. The displayed name is the source mapping’s fallback.
Request:
{
"id": "ws_socialize_example"
}
Illustrative successful response:
[
{
"id": "user_example",
"email": "editor@example.invalid",
"name": "editor",
"role": "member",
"status": "active",
"joinedAt": "2026-10-21T00:00:00.000Z",
"invitedBy": "user_owner_example"
}
]
Interpret id as user identity and role/status as local membership fields.
No non-suspended local members
Source-derived synthetic and unrun; assumes workspace authorization succeeded and the local query had no eligible rows.
Request:
{
"id": "ws_socialize_example"
}
Illustrative successful response:
[]
Do not infer that the caller lost its platform grant merely from this empty roster.
Refusals and recovery
| Status | Source-specific condition | Next step |
|---|---|---|
| 400 | /problems/validation-error | Use the original verified organization and valid resource-binding context. This GET handler does not parse or validate a JSON body; correct the actual context issue rather than inventing a body-validator refusal. |
| 403 | workspace_forbidden | Named workspace absent or inaccessible; re-discover the original allowed workspace, without guessed fallback or widened authority. |
| 503 | workspace_unresolved | Auth could not verify workspace access. Preserve the error and request id; do not interpret it as an empty authorized list. |
| 500 | failed_to_get_brand_members | Preserve the response and request evidence; verify original context and source-specific dependencies. Earlier mirror/reconciliation effects may remain. |
Outer authentication, permission and rate-limit refusals can differ from handler responses. Retain actual codes/request ids and use current discovery; no simulated refusal here is a deployed carrier test.
Verify the result
- Check the requested workspace, then inspect each returned role and status separately. Treat an empty array as no non-suspended local rows, not a grant-repair instruction.
- A user id returned here must not be silently substituted for another principal or used as a workspace resource id.
Related actions
Change log
2026-10-21: Added a source-qualified task guide with paired agent instructions, source-derived examples, workspace boundaries, actual response shape and side-effect/recovery notes. Reviewed source: f8e30bad6947f868302f24e9cb31b6a2bdd1fbf6; current catalog marker: bc22ce7a2ceaa4396388794c4d42895c777bed76. Their deployed serving association has not been established. No action execution, provider effect or test capture is claimed.