Topolo Docs Topolo Platform
Open workspace

Erase organization-owned Campaigns data — Campaigns

After exact organization authorization and literal ERASE confirmation, checks active campaigns, active batches and placed assets; blockers return 409 without proceeding.

Erase organization-owned Campaigns data

After exact organization authorization and literal ERASE confirmation, checks active campaigns, active batches and placed assets; blockers return 409 without proceeding.

Outcome and boundaries

After exact organization authorization and literal ERASE confirmation, checks active campaigns, active batches and placed assets; blockers return 409 without proceeding.

Deletes the listed Campaigns stores across that organization and verifies row counts. This is a multi-step erasure, not a cross-store atomic rollback contract. Delivered Notify records, Auth identity and backups remain separately owned.

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.privacy:write. Catalog discoverability is not permission to execute.
  • Organization scope for privacy input; no workspace alias is required by this handler.
  • All worked cases in this guide are hypothetical source-reviewed illustrations; no business action, live fixture, customer data or provider request was executed.

Discover the intended identifiers

  • Confirm the intended credential organization; organizationId must equal the verified caller organization. This is an organization-wide privacy operation, not a workspace delete.
  • Read the matching organizations.data.export and its exclusions only under separately authorized privacy access.

Action: app_topolo_campaigns.organizations.data.erase · DELETE /api/organizations/{organizationId}/data.

Input fields

FieldRequiredMeaning and validation
organizationIdYesExact verified caller organization. It selects all included Campaigns stores across that organization; do not pass it as an invented resource alias. string; minLength=1
confirmationYesLiteral ERASE. Schema validation and a written example are not approval to erase real data. string; const="ERASE"

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.organizations.data.erase --data @payload.json --json
topolo actions plan app_topolo_campaigns.organizations.data.erase --data @payload.json --json

The published action requires confirmation. Only after the exact mutation is authorized, use that same payload/context with --confirm on plan/call; no operation in this guide has been executed.

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.

Qualified illustrative erase result · HTTP 200

Input:

{
  "organizationId": "org_example",
  "confirmation": "ERASE"
}

Illustrative response:

{
  "success": true,
  "data": {
    "organization_id": "org_example",
    "erased": true,
    "verification": {
      "campaigns_redemptions": 0,
      "campaigns_journey_events": 0,
      "campaigns_placements": 0,
      "campaigns_redemption_failures": 0,
      "campaigns_batch_failures": 0,
      "campaigns_completions": 0,
      "campaigns_codes": 0,
      "campaigns_integrations": 0,
      "campaigns_batches": 0,
      "campaigns_campaigns": 0,
      "campaigns_offers": 0,
      "campaigns_workspaces": 0,
      "campaigns_notification_deliveries": 0
    },
    "retained": {
      "topolo_auth_identity": true,
      "delivered_notifications_under_notify_policy": true,
      "encrypted_backups_until_retention_expiry": true
    }
  }
}

Active work blocks erasure · HTTP 409

Input:

{
  "organizationId": "org_example",
  "confirmation": "ERASE"
}

Illustrative response:

{
  "success": false,
  "error": "active_campaign_work_blocks_erasure",
  "data": {
    "active_campaigns": 1,
    "active_batches": 0,
    "placed_campaign_assets": 0
  }
}

Wrong organization · HTTP 403

Input:

{
  "organizationId": "org_other",
  "confirmation": "ERASE"
}

Illustrative response:

{
  "error": "organization_forbidden"
}

Verify the outcome

  • Require success:true, data.erased:true, matching organization_id and all listed verification counts zero. A 500 erasure_verification_failed can follow partial deletion; reconcile with the owning privacy process.

Refusals and recovery

  • HTTP 400 erase_confirmation_required: Correct the named input or retain the authoritative refusal in the same context.
  • HTTP 409 active_campaign_work_blocks_erasure: Correct the named input or retain the authoritative refusal in the same context.
  • HTTP 500 erasure_verification_failed: Correct the named input or retain the authoritative refusal in the same context.
  • HTTP 403 organization_forbidden: Correct the named input or retain the authoritative refusal in the same context.
  • 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.

Erasure has no published restore action. An earlier export is not an executable rollback. A partial failure needs evidence-led reconciliation by the existing privacy owner; do not repeatedly erase to manufacture a success.

Source and catalog limits

The reviewed organization store list omits campaigns_workspace_settings. Do not promise that this action clears every app-local recipient setting or delivered Notify record. Source execution and privacy completion are not established by these examples.

Exact schemas and provenance

Input schema:

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

Output schema:

{
  "type": "object",
  "title": "Erase organization data response",
  "description": "Operation result returned by organizations.data.erase.",
  "properties": {
    "success": {
      "type": "boolean"
    },
    "id": {
      "type": "string"
    },
    "data": {
      "anyOf": [
        {
          "type": "object",
          "title": "organization record",
          "properties": {
            "id": {
              "type": "string",
              "description": "Stable identifier when the organization exposes one."
            }
          },
          "additionalProperties": true
        },
        {
          "type": "object",
          "additionalProperties": true
        }
      ]
    },
    "result": {
      "type": "object",
      "additionalProperties": true
    },
    "message": {
      "type": "string"
    }
  },
  "additionalProperties": true,
  "x-topolo-contract-source": "derived-action-metadata",
  "x-topolo-contract-precision": "structural"
}

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

  • Export Campaigns organization data — Campaigns: Exports the explicitly authorized organization across Campaigns stores, with secret-like fields redacted. It excludes canonical platform identity, delivered Notify records, provider credentials and backups. Workspace recipient settings are not included in this export. It does not erase records.

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.

{
  "organizationId": "org_example",
  "confirmation": "ERASE",
  "__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.

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