teardown_synthetic_org

Tear down a test org

act entity tenant-private since 2026-10-01

Deletes a test org and its test twin at once: a synthetic org staff created in a synthetic account. Its rows go and its tombstone and audit trail stay. There is no countdown and no second approval, because a test org holds no customer's data. A customer, demo or internal org is never torn down here. Trade HQ staff only, with a reason.

Contract

shape
entity
authority
act
evidence
none
subscription
false
permission
any one of: staff.ops (the staff role staff_ops held in the Internal org, tradehq_role.staff_role); a deactivated caller is refused first
idempotency
natural
emits
org.torn_down
MCP tool
teardown_synthetic_org
decision_set
approve, reject, escalate
REST
POST https://api.containertradehq.com/v1/cap/teardown_synthetic_org

Through MCP this call returns an approval request first; see Approvals.

Idempotency: keyed by the contract's own inputs: the same inputs replay the first call's result

Inputs

nametyperequiredvalidation
org_idorg_idrequiredtradehq-org-id; 1 to 20 characters
The test org.
reasontextrequired1 to 500 characters
Why it is torn down, for the audit log.

Response

  • org_id · string · The org torn down.
  • twin_id · stringnull · Its test twin, torn down with it; null when it had none.
  • name · string · The name its tombstone keeps.
  • account_id · string · The test account it belonged to.
  • rows · integer · How many rows were deleted, both orgs together.
Full JSON Schema
{
  "type": "object",
  "properties": {
    "org_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-org-id",
      "description": "The org torn down.",
      "x-data-class": "operational"
    },
    "twin_id": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-org-id",
      "description": "Its test twin, torn down with it; null when it had none.",
      "x-data-class": "operational"
    },
    "name": {
      "type": "string",
      "description": "The name its tombstone keeps.",
      "x-data-class": "operational"
    },
    "account_id": {
      "type": "string",
      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
      "format": "tradehq-account-id",
      "description": "The test account it belonged to.",
      "x-data-class": "operational"
    },
    "rows": {
      "type": "integer",
      "description": "How many rows were deleted, both orgs together.",
      "x-data-class": "operational"
    }
  },
  "required": [
    "org_id",
    "twin_id",
    "name",
    "account_id",
    "rows"
  ],
  "additionalProperties": false
}

Refusals

  • org_not_synthetic · 422 · the org is not a synthetic org in a synthetic account; a customer org is deleted only by schedule_org_deletion's countdown and purge_org
  • org_is_declared · 422 · db/tradehq/orgs.json declares the org, or it is the public sandbox; neither is torn down here
  • org_is_twin · 422 · a test twin is torn down with its live org
  • org_purged · 422 · the org is already torn down; only its tombstone is left
  • synthetic_holds_external_data · 422 · the org holds something from outside the estate, or another org's row names it
  • teardown_blocked · 422 · a row of the org is referenced by one teardown does not delete; nothing was deleted
  • synthetic_org_not_found · 422 · the org has no type row

The platform refusals apply to every call: version, authentication, authority, validation and rate limits, each in the same envelope.

Surfaces

DesktopF
MobileD5
APIF
MCPF*
VoiceD2
PushF
OneBoxN
OutboundN
  • Mobile: degraded: composition
  • MCP: approval required
  • Voice: degraded: confirmation
  • OneBox: no document originates a test org's teardown
  • Outbound: crosses to no counterparty

Events

Related

break_glass_access, impersonate_user, request_staff_grant, suspend_org