Outcome
Read registered sources in the granted workspace, decrypting name and endpoint URL with snake_case status fields. The unpaginated list is ordered by creation and id; the local mirror can be initialized.
Before you start
- Verify the authenticated identity, exact environment and pinned approved organization context before preparing an action.
- Development stores content without encryption and uses scoped SHA-256 identifier hashes. Staging and production require envelope encryption and a provisioned application root; missing custody does not permit plaintext.
- The published application permission is feed:read. Discover a granted Feed workspace and bind that exact resource. Supplied identifiers and query selectors do not grant access.
- Authorize the documented mirror, security, external-fetch, reporting, privacy or archival effects before CLI --confirm or MCP confirm:true. A GET request can initialize a local mirror.
Discover the target
topolo whoami --json
topolo actions get app_topolo_feed.sources.list --detail --json
topolo resources topolo-feed --json
topolo workspaces list topolo-feed --json
- Select the exact granted workspace id as FEED_WORKSPACE_ID. Fixture ids authorize no live operation.
Request
GET /api/analytics/sources
Save action input as payload.json. Inspect the plan for the exact path, query and body. Set FEED_WORKSPACE_ID from granted resource discovery.
Inspect and test this action in the signed action console, then perform the verification below.
Input fields
| Field | Required | Type | Constraints |
|---|---|---|---|
workspaceId | Optional | string | Canonical Feed workspace id. Resolve it through credential-scoped grants; it does not grant access. For archival it is also the path id and must match the resolved resource.; {"minLength":1} |
workspace_id | Optional | string | Alternative workspace selector accepted by the published input. Prefer one explicit granted workspace resource; do not send conflicting selectors.; {"minLength":1} |
Exact input schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"workspaceId": {
"type": "string",
"minLength": 1,
"description": "Canonical Feed workspace id. Resolve it through credential-scoped grants; it does not grant access. For archival it is also the path id and must match the resolved resource."
},
"workspace_id": {
"type": "string",
"minLength": 1,
"description": "Alternative workspace selector accepted by the published input. Prefer one explicit granted workspace resource; do not send conflicting selectors."
}
},
"additionalProperties": false
}
Effects
- Resolves the workspace through platform grants and can insert its identity-only local mirror before the route permission check. GET is therefore a mutation for action planning; it does not create a canonical workspace or change its name.
- Returns source ids, organization/workspace scope, endpoint_url and nullable last_synced_at/last_error fields.
- Listing does not fetch a source, import content or update playback configuration.
Interpret the response
Use response path $.sources[].id for feed_source. An empty list does not discover a target.
Select a source.id from the same workspace. Inspect last_error and last_synced_at rather than treating registration as successful synchronization.
The success schema below was checked against captured handler responses. Polymorphic configuration and protected device assignment fields vary; exact envelope and SQL row fields are source-reviewed. Error examples retain their actual refusal shapes.
Success schema:
{
"type": "object",
"properties": {
"sources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"organization_id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"endpoint_url": {
"type": "string"
},
"last_synced_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"last_error": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
}
},
"required": [
"id",
"organization_id",
"workspace_id",
"name",
"endpoint_url",
"last_synced_at",
"last_error",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"sources"
],
"additionalProperties": false
}
Worked examples
Actual Feed Worker response using synthetic Auth, workspace grants, in-memory D1/KV and simulated source/notification transport. No live provider, encryption audit, device enrollment or external delivery is established. Credentials are excluded or explicitly redacted. SQL result shapes are also reviewed against migrations and handlers; empty captures do not exercise every populated export store. Live publication and read-back are separate environment evidence. Refused examples demonstrate boundaries and must not be executed as successful workflows.
Successful request
Actual Feed Worker response using synthetic Auth, workspace grants, in-memory D1/KV and simulated source/notification transport. No live provider, encryption audit, device enrollment or external delivery is established. Credentials are excluded or explicitly redacted. Captured scenario: source registry is discoverable, workspace-scoped, SSRF-safe, and records failed syncs.
Input · payload.json:
{}
CLI:
topolo actions validate app_topolo_feed.sources.list --data @payload.json --json
topolo actions plan app_topolo_feed.sources.list --resource-type workspace --resource-id "$FEED_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_feed.sources.list --resource-type workspace --resource-id "$FEED_WORKSPACE_ID" --data @payload.json --confirm --json
MCP tool and arguments:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_feed.sources.list",
"input": {},
"resourceType": "workspace",
"resourceId": "<identifier returned by granted resource discovery>",
"confirm": true
}
}
Captured local response · HTTP 200:
{
"sources": [
{
"id": "source_0f815beb-1299-409a-a199-4372e699da4c",
"organization_id": "org_acme",
"workspace_id": "feed_workspace_alpha",
"name": "Partner",
"endpoint_url": "https://partner.example/feed.json",
"last_synced_at": null,
"last_error": null,
"created_at": "2026-10-04T04:12:42.927Z",
"updated_at": "2026-10-04T04:12:42.927Z"
}
]
}
HTTP 200. Select a source.id from the same workspace. Inspect last_error and last_synced_at rather than treating registration as successful synchronization.
Verify the result
- Select a source.id from the same workspace. Inspect last_error and last_synced_at rather than treating registration as successful synchronization.
Errors and recovery
forbidden(HTTP 403): Use the published permission in the approved credential scope. Do not switch contexts to bypass a denial.
Auth, action-input validation and platform resource resolution can refuse a request before its handler. Retain the exact error, request id and context; requesting another context is not a legitimate way to bypass a refusal.
Recovery boundary
No source records are changed. Do not erase an organization or archive a workspace to undo a listing.
Related actions
- Record Feed source fetch attempt: Fetch a registered workspace HTTPS source without redirects, consume at most 1,048,576 response bytes, discard the body and persist its terminal attempt. HTTP 200 may contain a failed sync; no content is imported.
Evidence
Actual Feed Worker response using synthetic Auth, workspace grants, in-memory D1/KV and simulated source/notification transport. No live provider, encryption audit, device enrollment or external delivery is established. Credentials are excluded or explicitly redacted. SQL result shapes are also reviewed against migrations and handlers; empty captures do not exercise every populated export store. Live publication and read-back are separate environment evidence. Capture digests and test scenarios are retained in the source fixture records.