Topolo Docs Topolo Platform
Open workspace

Transfer Insights source

Move a registered source into another administered workspace, optionally merging into its existing source.

Outcome

Move a registered source into another administered workspace, optionally merging into its existing source.

Before you start

  • Verify the exact identity, environment and approved organization with topolo whoami before discovering this action.
  • Inspect the credential-scoped action and canonical resource discovery. Examples use synthetic resources; replace their handles only with separately verified targets.
  • Validate the complete input and review the action plan. Mutation and organization-inventory actions require explicit confirmation; a successful shape check does not prove a runtime grant.
  • Select a granted workspace through topolo resources. The CLI/MCP supplies canonical resource headers; workspace identity is not an arbitrary payload field.

Discover the target

topolo whoami --json
topolo apps get topolo-insights --json
topolo actions get app_topolo_insights.sources.transfer --detail --json
topolo resources topolo-insights --json

Request

POST /api/sources/{sourceId}/transfer · permission workspace:write · confirmation required.

Inspect schemas and test this action in the signed action console. The complete field schema is also available through CLI/MCP action discovery.

Effects and scope

  • Requires admin access to both source and target workspace. Same-workspace, missing-target-source merge and occupied-target non-merge requests are refused.
  • The D1 batch moves collectors, activity, receipts, rollups and rejections, and copies subject tokens. It does not move event definitions, dashboards, saved queries, alerts, reports or workspace settings; raw R2 archives remain under their old keys.
  • A merge adopts the target source identity. data.sourceId and sourceKey still describe the original source, whose row is deleted. Re-discover the target; the response is not the surviving source handle.
  • Merged rollup counters are added, including unique-subject counters; this is not a union of distinct visitors. A merge cannot be separated by simply transferring back.
  • Already queued envelopes keep their old organization/workspace values. Coordinate ingestion and queue processing before transfer; this operation does not rewrite pending queue messages. Configured Notify delivery is best-effort and is not proven by these fixtures.

Interpret the response

  • Compare fromWorkspaceId, toWorkspaceId and moved table counters against the reviewed plan.
  • Read sources.list, collection_sites.list and analytics.overview in the target context. For a merge retain the surviving target id/key discovered there.
  • Check original workspace definitions and dashboards separately. Database movement does not prove archive relocation, queue drain or notification delivery.

Worked requests and responses

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Successful and refused captures below are separate examples. A refused response is a boundary, not a successful task.

workflow · refusal 1 · HTTP 404

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "source_missing",
  "targetWorkspaceId": "ws_insights_target"
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "error": "source_not_found"
}

HTTP 404. Discover the active source id/key in the selected workspace; organization ids and display names are not source handles.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

workflow · refusal 2 · HTTP 409

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_workflow"
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "error": "same_workspace"
}

HTTP 409. Source and target are the same workspace. Read the current source location and review the intended destination.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

workflow · refusal 3 · HTTP 403

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_ungranted"
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "error": "target_workspace_forbidden"
}

HTTP 403. The target is not an active administered workspace for this credential. Do not substitute a guessed target or broaden context.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

workflow · refusal 4 · HTTP 409

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_target",
  "merge": true
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "error": "target_source_missing"
}

HTTP 409. Merge requires an existing target source. Discover the destination and review a non-merge transfer only when it is empty and intended.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

workflow · success 5 · HTTP 200

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_target",
  "merge": false
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json
topolo actions call app_topolo_insights.sources.transfer --data @payload.json --confirm --detail --json

MCP tool and arguments:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_insights.sources.transfer",
    "input": {
      "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
      "targetWorkspaceId": "ws_insights_target",
      "merge": false
    },
    "confirm": true
  }
}

Captured raw Worker result

{
  "data": {
    "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
    "sourceKey": "marketing-site",
    "fromWorkspaceId": "ws_insights_workflow",
    "toWorkspaceId": "ws_insights_target",
    "moved": {
      "collectionSites": 2,
      "activity": 2,
      "receipts": 2,
      "rollups": 1,
      "rejections": 5,
      "subjectTokens": 1
    }
  }
}

HTTP 200. Compare fromWorkspaceId, toWorkspaceId and moved table counters against the reviewed plan. Read sources.list, collection_sites.list and analytics.overview in the target context. For a merge retain the surviving target id/key discovered there. Check original workspace definitions and dashboards separately. Database movement does not prove archive relocation, queue drain or notification delivery.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

transferred · success 6 · HTTP 200

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_target. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_workflow"
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json
topolo actions call app_topolo_insights.sources.transfer --data @payload.json --confirm --detail --json

MCP tool and arguments:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_insights.sources.transfer",
    "input": {
      "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
      "targetWorkspaceId": "ws_insights_workflow"
    },
    "confirm": true
  }
}

Captured raw Worker result

{
  "data": {
    "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
    "sourceKey": "marketing-site",
    "fromWorkspaceId": "ws_insights_target",
    "toWorkspaceId": "ws_insights_workflow",
    "moved": {
      "collectionSites": 2,
      "activity": 2,
      "receipts": 2,
      "rollups": 1,
      "rejections": 5,
      "subjectTokens": 1
    }
  }
}

HTTP 200. Compare fromWorkspaceId, toWorkspaceId and moved table counters against the reviewed plan. Read sources.list, collection_sites.list and analytics.overview in the target context. For a merge retain the surviving target id/key discovered there. Check original workspace definitions and dashboards separately. Database movement does not prove archive relocation, queue drain or notification delivery.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

merge · refusal 7 · HTTP 409

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_merge"
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "error": "target_source_exists"
}

HTTP 409. A non-merge transfer found a target source. Merge is irreversible; review its identity and combined-data consequence separately.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

merge · success 8 · HTTP 200

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_workflow. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
  "targetWorkspaceId": "ws_insights_merge",
  "merge": true
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json
topolo actions call app_topolo_insights.sources.transfer --data @payload.json --confirm --detail --json

MCP tool and arguments:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_insights.sources.transfer",
    "input": {
      "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
      "targetWorkspaceId": "ws_insights_merge",
      "merge": true
    },
    "confirm": true
  }
}

Captured raw Worker result

{
  "data": {
    "sourceId": "8e8a04e2-340c-4a28-8286-f94554943c78",
    "sourceKey": "marketing-site",
    "fromWorkspaceId": "ws_insights_workflow",
    "toWorkspaceId": "ws_insights_merge",
    "moved": {
      "collectionSites": 2,
      "activity": 2,
      "receipts": 2,
      "rollups": 1,
      "rejections": 5,
      "subjectTokens": 1
    }
  }
}

HTTP 200. Compare fromWorkspaceId, toWorkspaceId and moved table counters against the reviewed plan. Read sources.list, collection_sites.list and analytics.overview in the target context. For a merge retain the surviving target id/key discovered there. Check original workspace definitions and dashboards separately. Database movement does not prove archive relocation, queue drain or notification delivery.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

permission-refusals · refusal 9 · HTTP 403

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested. Selected synthetic workspace: ws_insights_merge. Fixture handles authorize no live request.

Input · payload.json:

{
  "sourceId": "source_example",
  "targetWorkspaceId": "ws_example",
  "merge": false
}

CLI:

topolo actions validate app_topolo_insights.sources.transfer --data @payload.json --json
topolo actions plan app_topolo_insights.sources.transfer --data @payload.json --confirm --json

Captured raw Worker result

{
  "success": false,
  "error": {
    "code": "action_permission_required",
    "message": "Action \"sources.transfer\" requires permission \"workspace:write\".",
    "action": "sources.transfer"
  }
}

HTTP 403. The credential lacks the declared action permission. Inspect credential-scoped discovery in the same approved context; workspace role does not replace the permission.

CLI/MCP adds its transport envelope; CLI --detail retains the full action result.

Verify the outcome

  • Compare fromWorkspaceId, toWorkspaceId and moved table counters against the reviewed plan.
  • Read sources.list, collection_sites.list and analytics.overview in the target context. For a merge retain the surviving target id/key discovered there.
  • Check original workspace definitions and dashboards separately. Database movement does not prove archive relocation, queue drain or notification delivery.

Errors and recovery

  • source_not_found (HTTP 404): Discover the active source id/key in the selected workspace; organization ids and display names are not source handles.
  • same_workspace (HTTP 409): Source and target are the same workspace. Read the current source location and review the intended destination.
  • target_workspace_forbidden (HTTP 403): The target is not an active administered workspace for this credential. Do not substitute a guessed target or broaden context.
  • target_source_missing (HTTP 409): Merge requires an existing target source. Discover the destination and review a non-merge transfer only when it is empty and intended.
  • target_source_exists (HTTP 409): A non-merge transfer found a target source. Merge is irreversible; review its identity and combined-data consequence separately.
  • action_permission_required (HTTP 403): The credential lacks the declared action permission. Inspect credential-scoped discovery in the same approved context; workspace role does not replace the permission.

Only observed refusals are listed. This does not promise that external dependencies or every invalid payload have been exhaustively exercised.

Recovery boundary

There is no safe generic inverse, especially after merge. A non-merge transfer back is a new operation requiring both workspace admin grants and a newly reviewed destination state; it does not relocate R2 archives or recover queue envelopes. Do not promise restoration of the original source identity or separability of merged rows.

Evidence and limits

Actual exported Insights worker, all nine migrated D1 scripts and isolated local R2. Auth identity/grants/archive transport, queue delivery and Analytics Engine sink are synthetic; local queue processing is called explicitly. Notify and Nexus are disabled. No live website, provider, paid usage or deployed data erasure is tested.