Outcome
Find the caller’s authorized workspace profiles and understand membership reconciliation and cached counts.
Action: app_topolo_socialize.brands.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 actual workspace ids with supported Socialize workspace/resource listing; brands.list input is exactly {}, with no brandId, organizationId or pagination fields.
- Use data[].id for subsequent brands.get/member reads. The derived catalog’s $.items[].id pointer does not describe this source handler’s data array.
Request
GET /api/brands
{}
Input fields are exactly those in the current published action schema. This action accepts no input properties.
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.list --data '<reviewed-input-json>' --json
TOPOLO_CONTEXT="org:<verified-org-id>" topolo --env production actions plan app_topolo_socialize.brands.list --resource-type workspace --resource-id '<verified-workspace-id>' --data '<reviewed-input-json>' --json
Interpret the response
- Returns {data:[profile,...]} with no pagination, cursor or total count in the pinned handler. It does not enumerate every brand in the organization.
- Auth verifies the caller’s accessible workspaces before the profile cache is consulted. The source filters active local profiles, ordered by created_at descending. An empty data array is a successful empty result, not evidence of an authorization-service failure.
- Profiles contain id, description, logoUrl, memberCount, organizationId, createdAt and updatedAt. Name, slug and default status are Auth workspace identity fields; use supported workspace discovery for them.
- memberCount counts active local memberships, not all Auth grants, pending invitations or the organization directory.
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.
- Before loading the profile cache, this route calls syncInvitedMemberships for the verified user/email. Accepted invitations can create memberships and member_joined activity; older email-based active memberships can migrate to the current user id. The service catches/logs individual reconciliation errors, so HTTP200 is not a receipt proving every membership was migrated.
- Reconciliation uses matching email records and is not restricted by the returned workspace-id array in that helper. It does not create an Auth workspace grant. Never invoke this endpoint merely as a harmless zero-effect permission probe.
- Profile caching uses caller id, organization and sorted verified workspace ids, with a configured300-second cache write TTL. Cache hits can show older profile/member counts after reconciliation or profile updates; optional KV warms local memory for60seconds. This is not a strict freshness SLA or a bypass parameter. No profile-update invalidation is shown.
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.
An accessible profile
Source-derived synthetic and unrun. Assumes Auth grants exactly the illustrated workspace and the local mirror/profile exists.
Request:
{}
Illustrative successful response:
{
"data": [
{
"id": "ws_socialize_example",
"description": "Example editorial workspace",
"logoUrl": "",
"memberCount": 2,
"organizationId": "org_example",
"createdAt": "2026-10-21T00:00:00.000Z",
"updatedAt": "2026-10-21T00:00:00.000Z"
}
]
}
Use data[0].id as the workspace identity; no name or default flag is returned.
No accessible profiles
Source-derived synthetic and unrun. Represents a successful empty authorized profile result; not an Auth-outage response.
Request:
{}
Illustrative successful response:
{
"data": []
}
Do not guess a different workspace id or interpret a503 as the same empty result.
Refusals and recovery
The listing filters the caller’s accessible grants and API-key bindings; it does not perform the named-resource workspace_forbidden check used by single-brand reads/edits. Outer authentication/permission refusals can still occur.
| 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. |
| 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_user_brands | 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
- Call brands.get for an exact intended workspace when a fresh profile/count is needed; keep returned workspace identity and original Auth grant distinct.
- No membership repair is justified merely by an old list count; do not repeat listings in a tight loop to force reconciliation.
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.