Topolo Docs Topolo Platform
Open workspace

Register Feed HTTPS source

Store a named HTTPS source in the granted workspace after validating its URL. Registration neither fetches nor imports source content, and every call creates a new record even for a duplicate endpoint.

Outcome

Store a named HTTPS source in the granted workspace after validating its URL. Registration neither fetches nor imports source content, and every call creates a new record even for a duplicate endpoint.

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:write. 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.create --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

POST /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

FieldRequiredTypeConstraints
nameRequiredstringTrimmed source label, 1 to 120 characters; duplicate labels and endpoints do not deduplicate creation.; {"minLength":1,"maxLength":120}
endpointUrlRequiredstringHTTPS source URL subject to handler URL validation. Registration does not fetch or import content.; {}

Exact input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120,
      "description": "Trimmed source label, 1 to 120 characters; duplicate labels and endpoints do not deduplicate creation."
    },
    "endpointUrl": {
      "type": "string",
      "format": "uri",
      "pattern": "^https:\\/\\/.*",
      "description": "HTTPS source URL subject to handler URL validation. Registration does not fetch or import content."
    }
  },
  "required": [
    "name",
    "endpointUrl"
  ],
  "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.
  • Encrypts the source name and endpoint URL in staging and production; development stores them without encryption. Persists a new id and returns camelCase endpointUrl/createdAt.
  • Requires HTTPS and rejects URL user info, explicit non-default ports and the handler listed local/private address and hostname patterns. This is URL validation, not independent DNS or content safety certification.

Interpret the response

Use response path $.source.id for feed_source. An empty list does not discover a target.

Retain source.id and compare name and endpointUrl. Read sources.list in the same workspace to inspect the registered snake_case record. Before retrying an uncertain creation, discover an exact matching source; repeated calls do not provide idempotency.

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": {
    "source": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "endpointUrl": {
          "type": "string"
        },
        "createdAt": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "name",
        "endpointUrl",
        "createdAt"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "source"
  ],
  "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.

Refused request · HTTP 400

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:

{
  "name": "Metadata",
  "endpointUrl": "https://127.0.0.1/latest"
}

CLI:

topolo actions validate app_topolo_feed.sources.create --data @payload.json --json
topolo actions plan app_topolo_feed.sources.create --resource-type workspace --resource-id "$FEED_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "error": "invalid_source_url"
}

HTTP 400. The handler refused this request. Resolve its exact cause before retrying; input validation can reject an invalid fixture before it reaches the handler.

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:

{
  "name": "Partner",
  "endpointUrl": "https://partner.example/feed.json"
}

CLI:

topolo actions validate app_topolo_feed.sources.create --data @payload.json --json
topolo actions plan app_topolo_feed.sources.create --resource-type workspace --resource-id "$FEED_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_feed.sources.create --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.create",
    "input": {
      "name": "Partner",
      "endpointUrl": "https://partner.example/feed.json"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>",
    "confirm": true
  }
}

Captured local response · HTTP 201:

{
  "source": {
    "id": "source_0f815beb-1299-409a-a199-4372e699da4c",
    "name": "Partner",
    "endpointUrl": "https://partner.example/feed.json",
    "createdAt": "2026-10-04T04:12:42.927Z"
  }
}

HTTP 201. Retain source.id and compare name and endpointUrl. Read sources.list in the same workspace to inspect the registered snake_case record. Before retrying an uncertain creation, discover an exact matching source; repeated calls do not provide idempotency.

Another supported 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: successful source sync consumes content and persists only terminal sync state.

Input · payload.json:

{
  "name": "Partner",
  "endpointUrl": "https://partner.example/feed.json"
}

CLI:

topolo actions validate app_topolo_feed.sources.create --data @payload.json --json
topolo actions plan app_topolo_feed.sources.create --resource-type workspace --resource-id "$FEED_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_feed.sources.create --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.create",
    "input": {
      "name": "Partner",
      "endpointUrl": "https://partner.example/feed.json"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>",
    "confirm": true
  }
}

Captured local response · HTTP 201:

{
  "source": {
    "id": "source_0b15b4ee-87ae-4cbb-abcd-a47e1aebe379",
    "name": "Partner",
    "endpointUrl": "https://partner.example/feed.json",
    "createdAt": "2026-10-04T04:12:42.930Z"
  }
}

HTTP 201. Retain source.id and compare name and endpointUrl. Read sources.list in the same workspace to inspect the registered snake_case record. Before retrying an uncertain creation, discover an exact matching source; repeated calls do not provide idempotency.

Verify the result

  • Retain source.id and compare name and endpointUrl. Read sources.list in the same workspace to inspect the registered snake_case record.
  • Before retrying an uncertain creation, discover an exact matching source; repeated calls do not provide idempotency.

Errors and recovery

  • invalid_source_url (HTTP 400): Inspect the exact handler refusal and correct the target, window, URL or confirmation before preparing another authorized request.

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 narrow source update or deletion action is published. Retain an unwanted source and avoid selecting it; do not use organization erasure as routine compensation.

  • List registered Feed sources: 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.
  • 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.