Topolo Docs Topolo Platform
Open workspace

Read file content

Read bounded authenticated object bytes in the verified workspace and organization or private scope.

Outcome

Read bounded authenticated object bytes in the verified workspace and organization or private scope.

Before you start

  • Verify identity, pin environment and organization, and discover a granted Bytes workspace before choosing file keys.
  • The action requires files:read. Select a verified workspace resource separately from action input; a body field cannot supply a workspace grant.
  • Use only org or private as scope for this action. Org uses the verified workspace shared root; private uses the caller’s private subtree. The published action schema accepts neither all nor a bucket selector; these values cannot grant broader storage access.

Discover the target

topolo whoami --json
topolo actions get app_topolo_bytes.files.content.get --detail --json
topolo resources topolo-bytes --json
topolo workspaces list topolo-bytes --json
  • File keys are paths returned by files.list/search in the selected workspace and scope. Discover the granted workspace id; do not derive access from fixture ids.

Request

GET /api/file/content

Save action input as payload.json. The reviewed plan separates path identifiers, query fields and the HTTP body. Set BYTES_WORKSPACE_ID from granted resource discovery.

Inspect and test this action in the signed action console. A test response still requires the verification below.

Input fields

FieldRequiredTypeConstraints
keyRequiredstring{"minLength":1}
scopeOptionalstring{"enum":["org","private"]}
offsetOptionalinteger{"minimum":0,"maximum":9007199254740991}
lengthOptionalinteger{"minimum":1,"maximum":4194304}

Exact input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "key": {
      "type": "string",
      "minLength": 1
    },
    "scope": {
      "type": "string",
      "enum": [
        "org",
        "private"
      ]
    },
    "offset": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "length": {
      "type": "integer",
      "minimum": 1,
      "maximum": 4194304
    }
  },
  "required": [
    "key"
  ],
  "additionalProperties": false
}

Effects

  • Reads at most 4 MiB of one object inside the verified workspace and private or organization scope. No signed URLs or credentials are returned.

Interpret the response

The response identifier path is $.key for file. An empty list does not discover a target.

Decode contentBase64 and check length. Fetch subsequent offsets to size only when the full file is needed. Require the same etag and size across every chunk; verify the complete SHA-256 against the uploaded bytes.

The success response has exactly the fields in the declared schema. Refusal examples retain the exact historical local captures below; current authentication, input-validation and resource middleware may refuse before the content handler. They do not establish a new run or deployed response.

Success schema:

{
  "type": "object",
  "required": [
    "success",
    "key",
    "size",
    "offset",
    "length",
    "contentBase64",
    "contentType",
    "etag"
  ],
  "properties": {
    "success": {
      "type": "boolean",
      "const": true
    },
    "key": {
      "type": "string"
    },
    "size": {
      "type": "integer",
      "minimum": 0
    },
    "offset": {
      "type": "integer",
      "minimum": 0
    },
    "length": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4194304
    },
    "contentBase64": {
      "type": "string"
    },
    "contentType": {
      "type": "string"
    },
    "etag": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

Worked examples

Actual exported Worker handlers with local Miniflare R2/KV. Auth, workspace grants, R2 multipart, notification, usage and semantic integrations are simulated at their configured test boundaries. Synthetic ids, timestamps and signed URLs confer no live access. No deployed provider outcome, external delivery or live grant is established. Upload-session credential values are explicitly redacted; binary responses use the tested SDK transport envelope. Replace synthetic identifiers through credential-scoped discovery. Refused scenarios document failure boundaries; they are not successful workflows.

Successful request

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "length": 5
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_bytes.files.content.get",
    "input": {
      "key": "brief.txt",
      "length": 5
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "success": true,
  "key": "brief.txt",
  "size": 11,
  "offset": 0,
  "length": 5,
  "contentBase64": "aGVsbG8=",
  "contentType": "text/plain",
  "etag": "5eb63bbbe01eeed093cb22bb8f5acdc3"
}

HTTP 200. Decode contentBase64 and check length. Fetch subsequent offsets to size only when the full file is needed. Require the same etag and size across every chunk; verify the complete SHA-256 against the uploaded bytes.

Another supported request

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "offset": 5
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_bytes.files.content.get",
    "input": {
      "key": "brief.txt",
      "offset": 5
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "success": true,
  "key": "brief.txt",
  "size": 11,
  "offset": 5,
  "length": 6,
  "contentBase64": "IHdvcmxk",
  "contentType": "text/plain",
  "etag": "5eb63bbbe01eeed093cb22bb8f5acdc3"
}

HTTP 200. Decode contentBase64 and check length. Fetch subsequent offsets to size only when the full file is needed. Require the same etag and size across every chunk; verify the complete SHA-256 against the uploaded bytes.

Refused request · HTTP 404

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 404:

{
  "success": false,
  "error": {
    "code": "file_not_found"
  }
}

HTTP 404. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 403

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 403:

{
  "error": "workspace_forbidden"
}

HTTP 403. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 403

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 403:

{
  "error": "Forbidden",
  "message": "Insufficient permissions",
  "required": [
    "files:read",
    "folders:read",
    "sharing:read",
    "storage:read"
  ],
  "available": [
    "files:write"
  ]
}

HTTP 403. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 400

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "success": false,
  "error": {
    "code": "invalid_input"
  }
}

HTTP 400. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 400

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "offset": "-1"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "success": false,
  "error": {
    "code": "invalid_input"
  }
}

HTTP 400. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 400

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "length": "0"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "success": false,
  "error": {
    "code": "invalid_input"
  }
}

HTTP 400. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 400

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "length": "4194305"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "success": false,
  "error": {
    "code": "invalid_input"
  }
}

HTTP 400. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 400

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "offset": "1.5"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 400:

{
  "success": false,
  "error": {
    "code": "invalid_input"
  }
}

HTTP 400. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 416

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "brief.txt",
  "offset": 5
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 416:

{
  "success": false,
  "error": {
    "code": "range_not_satisfiable"
  }
}

HTTP 416. This request was refused; preserve the exact response and correct its cause before retrying.

Refused request · HTTP 404

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "absent"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

Captured local response · HTTP 404:

{
  "success": false,
  "error": {
    "code": "file_not_found"
  }
}

HTTP 404. This request was refused; preserve the exact response and correct its cause before retrying.

Another supported request

Actual worker response with local Miniflare R2/KV and simulated Auth, workspace grants and outbound integration boundaries. No authorization header is captured.

Input · payload.json:

{
  "key": "empty.txt"
}

CLI:

topolo actions validate app_topolo_bytes.files.content.get --data @payload.json --json
topolo actions plan app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_bytes.files.content.get --resource-type workspace --resource-id "$BYTES_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_bytes.files.content.get",
    "input": {
      "key": "empty.txt"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "success": true,
  "key": "empty.txt",
  "size": 0,
  "offset": 0,
  "length": 0,
  "contentBase64": "",
  "contentType": "application/octet-stream",
  "etag": "d41d8cd98f00b204e9800998ecf8427e"
}

HTTP 200. Decode contentBase64 and check length. Fetch subsequent offsets to size only when the full file is needed. Require the same etag and size across every chunk; verify the complete SHA-256 against the uploaded bytes.

Verify the result

  • Decode contentBase64 and check length. Fetch subsequent offsets to size only when the full file is needed. Require the same etag and size across every chunk; verify the complete SHA-256 against the uploaded bytes.

Errors and recovery

  • workspace_required (HTTP 403): Resolve and pass an accessible Bytes workspace in the current credential context.
  • file_not_found (HTTP 404): Resolve the artifact key in the bound workspace and scope.
  • file_changed (HTTP 409): Discard partial bytes and re-read the object from offset zero before accepting a checksum.
  • range_not_satisfiable (HTTP 416): Read the current object size and request a valid offset.

Authentication, the action-input validator or resource middleware can refuse a request before this handler. Preserve the exact request id, error and selected credential context. The fixtures establish no live credentials or configured provider.

Recovery boundary

No service state changes.

Evidence

Actual exported Worker handlers with local Miniflare R2/KV. Auth, workspace grants, R2 multipart, notification, usage and semantic integrations are simulated at their configured test boundaries. Synthetic ids, timestamps and signed URLs confer no live access. No deployed provider outcome, external delivery or live grant is established. Upload-session credential values are explicitly redacted; binary responses use the tested SDK transport envelope. Capture digests and test scenarios are retained in the source fixture records.

Documentation history

2026-10-18: Clarified org/private-only action input and retained-capture applicability; no examples or service behavior changed.

These are retained local captures with fixture baseline 4ad0e5240932053f49deddc58885beaf0186437c. The production-declared action contract is source 396ebed4d5443c9c3598f25c65859d204c2076ba; its content handler, storage-scope helper, bucket selector and action contracts are byte-identical at documentation source 973f855618d73f44f006f44e9111c7bd46fff13e. The capture execution tree and current deployed worker version are not established by this review; examples are source-compatible retained evidence, not newly executed results.