Topolo Docs Topolo Platform
Open workspace

List issued codes — Campaigns

Lists code records in the bound organization/workspace, optionally filtered by campaignId; results are ordered newest creation first.

List issued codes

Lists code records in the bound organization/workspace, optionally filtered by campaignId; results are ordered newest creation first.

Outcome and boundaries

Lists code records in the bound organization/workspace, optionally filtered by campaignId; results are ordered newest creation first.

Before you start

  • Confirm the intended environment and current credential organization using whoami; discover the exact application/action before any call.
  • Required application permission: app_topolo_campaigns.codes:read. Catalog discoverability is not permission to execute.
  • Discover an authorized canonical workspace and bind resourceType workspace/resourceId separately from action input.
  • All worked cases in this guide are hypothetical source-reviewed illustrations; no business action, live fixture, customer data or provider request was executed.
  • Canonical workspace minimum access is read in addition to the application permission. After grant verification, the first request may create an app-local identity/recipient mirror even before the later app-permission check; this is not campaign-domain completion.

Discover the intended identifiers

  • Discover a granted workspace. Read campaigns.list/get before applying campaignId; code.id and code.code are distinct.

Action: app_topolo_campaigns.codes.list · GET /api/codes.

Input fields

FieldRequiredMeaning and validation
campaignIdNoOptional campaign filter resolved through campaigns.list/get in this workspace. Empty results do not prove campaign existence. string

Safe call sequence

Write the reviewed input to payload.json; fixture identifiers below are unusable examples. Validate before planning, bind the discovered resource separately, and execute only within actual authority.

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

A published read can use topolo actions call with the same discovered resource and input. This guide does not invoke it.

Worked cases

Every response below is synthetic and source-reviewed, not captured. HTTP status and body are explained independently; a structurally valid body alone never proves successful execution. Middleware may add a different error envelope.

Code present · HTTP 200

Input:

{
  "campaignId": "campaign_example"
}

Illustrative response:

{
  "codes": [
    {
      "id": "code_example",
      "campaignId": "campaign_example",
      "batchId": null,
      "code": "EXAMPLE-20",
      "ownerRef": null,
      "quroSlug": null,
      "status": "active",
      "createdAt": "2026-10-20T00:00:00.000Z"
    }
  ]
}

No matching codes · HTTP 200

Input:

{
  "campaignId": "campaign_absent"
}

Illustrative response:

{
  "codes": []
}

Workspace refusal · HTTP 403

Input:

{}

Illustrative response:

{
  "error": "workspace_forbidden"
}

Verify the outcome

  • Inspect codes[].campaignId, status, batchId and code. An empty list alone does not establish campaign existence or deletion.

Refusals and recovery

  • HTTP 403 forbidden: Raw handler permission refusal. SDKs can normalize it to permission_denied. Keep the same intended resource; do not widen access.
  • HTTP 403 workspace_forbidden: The canonical workspace grant refused the selected resource. Resolve it with the access owner, not a guessed workspace.

No campaign-domain rollback is needed for this read. Preserve authentication, permission and resource refusals; do not switch organization or widen a grant to bypass them.

Exact schemas and provenance

Input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "campaignId": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

Output schema:

{
  "title": "List codes response",
  "description": "Collection response returned by codes.list. The service may return the collection directly or in an envelope.",
  "oneOf": [
    {
      "type": "array",
      "items": {
        "type": "object",
        "title": "code record",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable identifier when the code exposes one."
          }
        },
        "additionalProperties": true
      }
    },
    {
      "type": "object",
      "properties": {
        "data": {
          "oneOf": [
            {
              "type": "array",
              "items": {
                "type": "object",
                "title": "code record",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Stable identifier when the code exposes one."
                  }
                },
                "additionalProperties": true
              }
            },
            {
              "type": "object",
              "additionalProperties": true
            }
          ]
        },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "title": "code record",
            "properties": {
              "id": {
                "type": "string",
                "description": "Stable identifier when the code exposes one."
              }
            },
            "additionalProperties": true
          }
        },
        "codes": {
          "type": "array",
          "items": {
            "type": "object",
            "title": "code record",
            "properties": {
              "id": {
                "type": "string",
                "description": "Stable identifier when the code exposes one."
              }
            },
            "additionalProperties": true
          }
        },
        "count": {
          "type": "integer",
          "minimum": 0
        },
        "nextCursor": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "additionalProperties": true
    }
  ],
  "x-topolo-contract-source": "derived-action-metadata",
  "x-topolo-contract-precision": "structural"
}

Reviewed immutable source: TopoloCampaigns@cacbb8b12b4e19a662cf82d03a927aef3c3a35e8, apps/api/src/campaigns-store.ts. 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.

  • 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.
  • Check code eligibility — Campaigns: Evaluates a code and returns HTTP 200 with valid:true or valid:false and a reason. This read does not consume redemption capacity.
  • Enable, disable or associate a code — Campaigns: Updates active/disabled status, optional batchId and stored quroSlug for one code string in this workspace. It does not change a label, call Quro, or prove a physical placement.

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.

{
  "campaignId": "campaign_example",
  "__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 accepts an empty object, a partial success marker, a partial data object and a refusal body. It therefore establishes only broad structure. Require the documented HTTP/domain result and source-shaped fields; missing fields or a schema-valid error are not success. The current oneOf array/object branches have disjoint types, including the nested data branches; no oneOf ambiguity was observed. Their missing required collection fields still permit empty or partial objects.

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