Topolo Docs Topolo Platform
Open workspace

Download brand asset content

Download authenticated content for a ready Brand asset.

Outcome

Download authenticated content for a ready Brand asset.

Before you start

  • Verify whoami and the pinned credential context, then inspect the exact discovered action before preparing input.
  • Discover a granted Brand workspace. Pass its resourceType/workspace identifier separately from input; a copied fixture identifier grants no access.
  • The declared permission is brand:read. The active credential, application scope, resource binding and runtime authority must all authorize the request.

Discover the target

topolo whoami --json
topolo actions get app_topolo_brand.brand_assets.download --detail --json
topolo resources topolo-brand --json
topolo workspaces list topolo-brand --json

Request

GET /api/brand-assets/{assetId}/content

Resource context is the selected Brand workspace. CLI/SDK action input includes path identifiers; direct HTTP JSON bodies exclude path parameters. Read the reviewed plan for the exact request.

Input fields

FieldRequiredMeaning
assetIdYesRegistered Brand asset identifier. Upload accepts pending or ready assets; download requires stored ready content.

Exact published input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "assetId": {
      "type": "string",
      "minLength": 1,
      "description": "Registered Brand asset identifier. Upload accepts pending or ready assets; download requires stored ready content."
    }
  },
  "required": [
    "assetId"
  ],
  "additionalProperties": false
}

Effects

Reads registered original asset bytes without changing records. Allowed service consumers remain subject to their verified service and Brand scope.

Interpret the response

HTTP returns bytes with the registered MIME type and private,no-store caching. CLI/SDK serialize binary content as contentType, contentLength and contentBase64. responseSha256 in the fixture evidence is independently computed and is not a response field. A public published URL is a separate immutable-version route.

Response identifier contract:

{
  "kind": "brand_assets_download",
  "identifierSource": "none",
  "explanation": "HTTP returns bytes with the registered MIME type and private,no-store caching. CLI/SDK serialize binary content as contentType, contentLength and contentBase64. responseSha256 in the fixture evidence is independently computed and is not a response field. A public published URL is a separate immutable-version route."
}

Worked examples

These complete synthetic responses were captured from the local worker over canonical SQL migrations. Auth and R2 dependencies are simulated; notification delivery is not exercised. Set BRAND_WORKSPACE_ID from granted workspace discovery. Save reviewed input as payload.json, validate and inspect the unchanged plan. The final mutation command and MCP confirm flag assume the intended effect has already been authorized.

Minimal example

Input · payload.json:

{
  "assetId": "brand_asset_dd192c95-76da-4c2e-a61c-8b164686806b"
}

CLI:

topolo actions validate app_topolo_brand.brand_assets.download --data @payload.json --json
topolo actions plan app_topolo_brand.brand_assets.download --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_brand.brand_assets.download --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_brand.brand_assets.download",
    "input": {
      "assetId": "brand_asset_dd192c95-76da-4c2e-a61c-8b164686806b"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "contentType": "image/svg+xml",
  "contentLength": 99,
  "contentBase64": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHJlY3Qgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+PC9zdmc+"
}

HTTP returns bytes with the registered MIME type and private,no-store caching. CLI/SDK serialize binary content as contentType, contentLength and contentBase64. responseSha256 in the fixture evidence is independently computed and is not a response field. A public published URL is a separate immutable-version route.

Workflow example

Input · payload.json:

{
  "assetId": "brand_asset_87bffee4-7249-419b-b4c1-8edeeb732d55"
}

CLI:

topolo actions validate app_topolo_brand.brand_assets.download --data @payload.json --json
topolo actions plan app_topolo_brand.brand_assets.download --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_brand.brand_assets.download --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_brand.brand_assets.download",
    "input": {
      "assetId": "brand_asset_87bffee4-7249-419b-b4c1-8edeeb732d55"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "contentType": "image/svg+xml",
  "contentLength": 99,
  "contentBase64": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHJlY3Qgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+PC9zdmc+"
}

HTTP returns bytes with the registered MIME type and private,no-store caching. CLI/SDK serialize binary content as contentType, contentLength and contentBase64. responseSha256 in the fixture evidence is independently computed and is not a response field. A public published URL is a separate immutable-version route.

Verify the result

Decode base64, confirm its byte length equals contentLength and compare expected content or your own hash. Preserve exact version/public URL provenance separately.

Errors and recovery

refused · HTTP 404

{
  "input": {
    "assetId": "missing-asset"
  },
  "response": {
    "error": "brand_asset_not_found"
  }
}

asset not ready · HTTP 404

{
  "input": {
    "assetId": "brand_asset_24d8ac1c-77dd-466e-94f0-8cd0178d9314"
  },
  "response": {
    "error": "brand_asset_not_found"
  }
}
  • auth_error (HTTP 401): CLI/SDK authentication classification when Auth returns a non-code message: restore the authorized credential, then verify whoami and context. Preserve the exact service message.

  • permission_denied (HTTP 403): Use the exact permission and granted resource required by the reviewed action; organization membership alone is insufficient.

  • workspace_required (HTTP 400): Discover and select a granted Brand workspace before preparing the request.

  • brand_storage_unavailable (HTTP 503): The Brand storage bindings are unavailable. Preserve the request identifier and report the service fault; do not retry an unverified mutation.

  • brand_asset_not_found (HTTP 404): Discover the exact parent/resource again and inspect its lifecycle status. Missing, inaccessible or immutable resources can share this refusal.

Recovery boundary

This read or validation does not change Brand service state.

  • app_topolo_brand.brand_assets.list: List registered asset records for a kit.

Evidence

Four real local SQLite stores use all canonical migrations; Auth identity/grants and archival plus R2 object storage are explicitly simulated. Notifications are disabled in fixtures. No notification delivery, live mutation, gateway credential parity or deployed environment proof is claimed. Fixture identifiers and timestamps are synthetic and must be replaced by exact authorized resource discovery.