Topolo Docs Topolo Platform
Open workspace

Download thread attachment

Reads the stored file for an attachment on a caller-owned thread in the bound workspace. Resource identity is the request attachmentId; the file response does not contain an attachment identifier. Raw HTTP returns bytes with inline Content-Disposition and private caching. SDK, CLI and MCP representation depends on the media type: text is a string, JSON is parsed JSON, and other media is a contentType/contentLength/contentBase64 envelope.

Download thread attachment

Outcome

Reads the stored file for an attachment on a caller-owned thread in the bound workspace. Resource identity is the request attachmentId; the file response does not contain an attachment identifier. Raw HTTP returns bytes with inline Content-Disposition and private caching. SDK, CLI and MCP representation depends on the media type: text is a string, JSON is parsed JSON, and other media is a contentType/contentLength/contentBase64 envelope.

Before you start

  • Verify the intended environment, authenticated identity and organization before discovery.
  • Discover the published workspace:read application permission and inspect the credential-scoped action contract.
  • Discover and bind the granted canonical Agent workspace separately from the action input.
  • Fixture identifiers and simulated responses confer no live access. Replace identifiers through granted resource discovery.

Discover the target

  • topolo whoami --json
  • topolo workspaces list topolo-agent --json
  • topolo actions get app_topolo_agent.threads.attachments.download --detail --json
  • Read app_topolo_agent.threads.attachments.list in this same authorized context and select the returned identifier. Do not derive ids from display names.
  • Inspect app_topolo_agent.threads.attachments.list in the same credential and resource context before reading it.

Request

GET /api/threads/{id}/attachments/{attachmentId}/download

Input fields

FieldRequiredMeaning and constraints
idYesThread identifier used to discover this attachment; keep it paired with attachmentId. Type: string. minLength: 1
attachmentIdYesAttachment identifier returned by threads.attachments.list for the same thread. Type: string. minLength: 1

Worked examples

Worked response 1 · HTTP 200

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local SDK representation · HTTP 200:

"Fixture brief"

text attachment: HTTP 200. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 2 · HTTP 200

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_binary_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_binary_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local SDK representation · HTTP 200:

{
  "contentType": "application/octet-stream",
  "contentLength": 4,
  "contentBase64": "AP8BgA=="
}

binary attachment: HTTP 200. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 3 · HTTP 200

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_json_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_json_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local SDK representation · HTTP 200:

{
  "fixture": true
}

JSON attachment: HTTP 200. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 4 · HTTP 401

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 401:

{
  "success": false,
  "error": "Organization context required"
}

organization context missing: HTTP 401; SDK code auth_error. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 5 · HTTP 403

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 403:

{
  "success": false,
  "error": "Topolo Agent workspace read permission required"
}

permission denied: HTTP 403; SDK code permission_denied. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 6 · HTTP 404

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_unknown_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_unknown_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 404:

{
  "success": false,
  "error": "Attachment not found"
}

attachment absent: HTTP 404; SDK code http_error. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 7 · HTTP 404

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 404:

{
  "success": false,
  "error": "Attachment file not found"
}

stored object absent: HTTP 404; SDK code http_error. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 8 · HTTP 404

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 404:

{
  "success": false,
  "error": "Thread not found"
}

private thread hidden: HTTP 404; SDK code http_error. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Worked response 9 · HTTP 503

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.

Input · payload.json:

{
  "id": "thread_docs_fixture",
  "attachmentId": "attachment_docs_fixture"
}

CLI:

topolo actions validate app_topolo_agent.threads.attachments.download --data @payload.json --json
topolo actions plan app_topolo_agent.threads.attachments.download --resource-type workspace --resource-id "$AGENT_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_agent.threads.attachments.download",
    "input": {
      "id": "thread_docs_fixture",
      "attachmentId": "attachment_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 503:

{
  "success": false,
  "error": "Attachment storage is not configured"
}

storage unconfigured: HTTP 503; SDK code http_error. Successful raw HTTP returns file bytes with inline Content-Disposition; outputExample is the actual installed SDK representation. Local R2 fixtures confer no live access.

Verify the result

  • Confirm the attachmentId was discovered from threads.attachments.list for this thread. For binary envelopes, decode contentBase64 and compare contentLength to the actual bytes; for text and JSON, inspect the returned content according to contentType. A metadata read alone does not prove the object exists.

Errors and recovery

  • auth_error (HTTP 401): For an unstructured HTTP 401 response, authenticate and verify the intended organization and workspace before retrying.
  • permission_denied (HTTP 403): For an unstructured HTTP 403 response, use the published application permission and required resource-level access. Do not retry with broader context.
  • http_error (HTTP 404): For an unstructured HTTP 404 response, refresh the corresponding resource listing in the same context. Private resources can be deliberately hidden from this caller.
  • http_error (HTTP 503): Attachment storage is not configured. Preserve the refusal and request operational repair; do not treat metadata as downloaded content.

Authentication, input validation or resource middleware can refuse a request before these handlers. Preserve the actual refusal and request id.

Recovery boundary

This read does not change service state. Re-discover the target in the same authorized organization and workspace after a missing or hidden-resource refusal; do not guess identifiers or widen context.

  • List thread attachments: List the files attached to one thread, with their names and types but not their contents.

Evidence

Actual exported read handlers and replayed SQLite migrations. Auth directory, service-token, R2 object storage and Durable Object storage boundaries are simulated; session response serialization executes the actual AgentSession.onRequest method. Egress is sealed. No deployed/provider outcome or live access is demonstrated.