Topolo Docs Topolo Platform
Open workspace

List campaign placements — Campaigns

Lists stored physical-code placement metadata. Recorded status and timestamps do not establish the current physical location of an asset. An absent campaign can return an empty list.

Retained immutable local-fixture guide, refreshed against current production catalog metadata. No examples were rerun by this author; no production action was invoked.

List campaign placements

Outcome

Lists stored physical-code placement metadata. Recorded status and timestamps do not establish the current physical location of an asset. An absent campaign can return an empty list.

After authentication and the canonical workspace grant succeed, a first workspace request may initialize the app-local identity mirror and recipient setting before the application permission check. These reads do not modify campaign-domain records or execute notifications.

Before you start

  • Verify the intended environment, authenticated identity and organization before discovery.
  • Discover the published campaigns:read application permission and inspect the credential-scoped action contract.
  • Discover and bind the granted canonical Campaigns 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-campaigns --json
topolo actions get app_topolo_campaigns.placements.list --json
  • Read app_topolo_campaigns.campaigns.list in this same authorized context and select campaigns[].id. Do not derive ids from display names.
  • Inspect app_topolo_campaigns.campaigns.get in the same credential and resource context before reading it.
  • Inspect app_topolo_campaigns.journey_events.list in the same credential and resource context before reading it.

Request

GET /api/campaigns/{id}/placements

Input fields

FieldRequiredMeaning and constraints
idYesCampaign identifier returned by campaigns.list in the same authorized organization and workspace. Type: string. minLength: 1

Worked examples

populated resource · HTTP 200

Input · payload.json:

{
  "id": "campaign_docs_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "placements": [
    {
      "id": "placement_docs_fixture",
      "codeId": "code_docs_fixture",
      "label": "Fixture venue",
      "venueRef": null,
      "status": "placed",
      "placedAt": "2026-10-07T00:00:00.000Z",
      "endedAt": null,
      "metadata": {},
      "createdAt": "2026-10-07T00:00:00.000Z",
      "updatedAt": "2026-10-07T00:00:00.000Z"
    }
  ]
}

populated resource: HTTP 200.

empty workspace · HTTP 200

Input · payload.json:

{
  "id": "campaign_docs_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "placements": []
}

empty workspace: HTTP 200.

campaign absent · HTTP 200

Input · payload.json:

{
  "id": "campaign_unknown_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_unknown_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 200:

{
  "placements": []
}

campaign absent: HTTP 200.

workspace grant denied · HTTP 403

Input · payload.json:

{
  "id": "campaign_docs_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 403:

{
  "error": "workspace_forbidden"
}

workspace grant denied: HTTP 403; SDK code permission_denied.

permission denied · HTTP 403

Input · payload.json:

{
  "id": "campaign_docs_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 403:

{
  "error": "forbidden"
}

permission denied: HTTP 403; SDK code permission_denied.

authentication missing · HTTP 401

Input · payload.json:

{
  "id": "campaign_docs_fixture"
}

CLI:

topolo actions validate app_topolo_campaigns.placements.list --data @payload.json --json
topolo actions plan app_topolo_campaigns.placements.list --resource-type workspace --resource-id "$CAMPAIGNS_WORKSPACE_ID" --data @payload.json --json

MCP tool and arguments:

{
  "tool": "topolo_prepare_action",
  "arguments": {
    "actionId": "app_topolo_campaigns.placements.list",
    "input": {
      "id": "campaign_docs_fixture"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by granted resource discovery>"
  }
}

Captured local response · HTTP 401:

{
  "error": "Authentication required"
}

authentication missing: HTTP 401; SDK code auth_error.

Verify the result

  • Verify campaigns.get, retain placements[].id and codeId, and inspect label, venueRef, status, placedAt and endedAt before preparing an update.

Errors and recovery

  • permission_denied (HTTP 403): Preserve the refusal. Verify the exact application permission and canonical workspace grant, or the organization boundary for export. Do not widen context or retry with a different resource to evade a denial.
  • auth_error (HTTP 401): Authenticate again in the intended environment and pinned organization, then repeat identity and resource discovery.

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

Recovery boundary

These reads do not change campaign-domain records and require no domain rollback. A permission or privacy refusal is authoritative; preserve its context and request id.

  • Get campaign — Campaigns: Reads one non-deleted campaign in the bound organization and workspace. An absent or differently scoped campaign returns HTTP 404 campaign_not_found.
  • List campaign journey events — Campaigns: Lists stored journey events for the campaign, newest occurrence first. Subject and external references are stored attribution, not executed follow-ups. An absent campaign can return an empty list.

Evidence

Actual Campaigns handleRequest, permission checks, store queries and replayed SQLite migrations. Credential verification and canonical workspace grants are simulated at the Auth package boundary; egress is sealed. No deployed/provider outcome, live redemption, outbound communication or live access is demonstrated.

Current field meanings and contract

FieldRequiredMeaning and validation
idYesCampaign identifier from campaigns[].id; scoped to the selected organization/workspace. It is not a batch/code/placement id. string; minLength=1

Exact schemas and provenance

Input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false
}

Output schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "placements": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "codeId": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "venueRef": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string"
          },
          "placedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "endedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/$defs/__schema0"
            }
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "codeId",
          "label",
          "venueRef",
          "status",
          "placedAt",
          "endedAt",
          "metadata",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "placements"
  ],
  "additionalProperties": false,
  "$defs": {
    "__schema0": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        },
        {
          "type": "boolean"
        },
        {
          "type": "null"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/__schema0"
          }
        },
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "$ref": "#/$defs/__schema0"
          }
        }
      ]
    }
  }
}

Reviewed immutable source: TopoloCampaigns@cacbb8b12b4e19a662cf82d03a927aef3c3a35e8, docs/action-read-records.json. Fresh production catalog was read on 2026-10-20. Its publication metadata is not proof that this source is loaded. Output examples are not widened or rewritten to force schema success; the accompanying validation record classifies exact success, refusal, no-body and structural-schema limits.

  • app_topolo_campaigns.campaigns.get: Read one campaign with its offer, codes, status and redemption totals.
  • app_topolo_campaigns.journey_events.list: List the journey events recorded against a campaign, the trail of what a recipient did.

Local input rejection example

This deliberately invalid input belongs to a pure schema check; it is never a planned or executed request. The closed action input schema must reject the extra field. It has no HTTP status or server response.

{
  "id": "campaign_docs_fixture",
  "__unsupported_field": true
}

The hidden companion labels this as ILLUSTRATIVE_LOCAL_SCHEMA_CHECK; its validation representation is not an action output.

Published output validation limits

Current published output qualification: the output schema rejects the empty-object, partial-success-marker, partial-data-object and refusal-body probes. A schema-valid success body still does not establish execution, live permission, selected context or a provider outcome.

These observations come from pure checks of the exact published schema; they are not server responses or production captures.