create_access_review

Start an access review

act entity tenant-private since 2026-10-01

Starts an access review of an org: a list of everyone and everything that holds access to it now, of the kinds chosen (members, guests, service_accounts, api_keys, staff_grants), for its admins to decide one by one with decide_access_review_item: keep it, change a member's role, or revoke it. The review is due at the end of due_on (UTC); an open review past due is raised to the account owner. It closes with close_access_review once every item is decided.

Contract

shape
entity
authority
act
evidence
none
subscription
false
permission
any one of: org.admin (carried by the caller's role template in the org `org_id`); account.owner (account role owner or higher in the account of the org `org_id`); a deactivated caller is refused first
idempotency
keyed
emits
access_review.created
MCP tool
create_access_review
decision_set
approve, reject
REST
POST https://api.containertradehq.com/v1/cap/create_access_review

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

Idempotency: keyed by the caller's Idempotency-Key, which is required: the same key and inputs replay the first result, the same key with other inputs is 409 idempotency_key_reused

Inputs

nametyperequiredvalidation
org_idorg_idrequiredtradehq-org-id; 1 to 20 characters
The org whose access to review.
nametextrequired1 to 120 characters
What the review is called, such as Q4 2026 access review.
due_ondaterequireddate, YYYY-MM-DD
The day the review is due (YYYY-MM-DD); it is due at that day's end, UTC.
membersbooleanoptional
Review the org's members. False by default.
guestsbooleanoptional
Review the org's guests. False by default.
service_accountsbooleanoptional
Review the org's service accounts. False by default.
api_keysbooleanoptional
Review the org's API keys. False by default.
staff_grantsbooleanoptional
Review the Trade HQ staff grants active in the org. False by default.

Response

  • review_id · string · The review's id.
  • org_id · string · The org whose access it reviews.
  • name · string · What it is called.
  • covers · string[] · What it covers, of members, guests, service_accounts, api_keys and staff_grants, in that order.
  • due_at · string · When it is due: the end (UTC) of its due date.
  • status · string · open; overdue, an open review past due; or closed.
  • total · integer · How many items it asks about.
  • decided · integer · How many of them are decided.
  • created_by · string · Who started it.
  • created_at · string · When it was started.
  • closed_by · stringnull · Who closed it.
  • closed_at · stringnull · When it was closed.
  • evidence_document_id · stringnull · The evidence document closing it wrote: who decided what, and when.
  • items · arraynull · Its items, when one review is asked for (review_id); null otherwise.
Full JSON Schema
{
  "type": "object",
  "properties": {
    "review_id": {
      "type": "string",
      "description": "The review's id.",
      "x-data-class": "operational"
    },
    "org_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-org-id",
      "description": "The org whose access it reviews.",
      "x-data-class": "operational"
    },
    "name": {
      "type": "string",
      "description": "What it is called.",
      "x-data-class": "operational"
    },
    "covers": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "What it covers, of members, guests, service_accounts, api_keys and staff_grants, in that order.",
      "x-data-class": "operational"
    },
    "due_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it is due: the end (UTC) of its due date.",
      "x-data-class": "operational"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "overdue",
        "closed"
      ],
      "description": "open; overdue, an open review past due; or closed.",
      "x-data-class": "operational"
    },
    "total": {
      "type": "integer",
      "minimum": 0,
      "description": "How many items it asks about.",
      "x-data-class": "operational"
    },
    "decided": {
      "type": "integer",
      "minimum": 0,
      "description": "How many of them are decided.",
      "x-data-class": "operational"
    },
    "created_by": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-user-id",
      "description": "Who started it.",
      "x-data-class": "operational"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it was started.",
      "x-data-class": "operational"
    },
    "closed_by": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-user-id",
      "description": "Who closed it.",
      "x-data-class": "operational"
    },
    "closed_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When it was closed.",
      "x-data-class": "operational"
    },
    "evidence_document_id": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
      "format": "uuid",
      "description": "The evidence document closing it wrote: who decided what, and when.",
      "x-data-class": "operational"
    },
    "items": {
      "type": [
        "array",
        "null"
      ],
      "items": {
        "type": "object",
        "properties": {
          "item_id": {
            "type": "string",
            "pattern": "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
            "format": "uuid",
            "description": "The item's id.",
            "x-data-class": "operational"
          },
          "review_id": {
            "type": "string",
            "description": "The review it belongs to.",
            "x-data-class": "operational"
          },
          "kind": {
            "type": "string",
            "enum": [
              "member",
              "guest",
              "service_account",
              "api_key",
              "staff_grant"
            ],
            "description": "member, guest, service_account, api_key or staff_grant.",
            "x-data-class": "operational"
          },
          "subject_id": {
            "type": "string",
            "description": "Whose access: a user id, a service account id, a key id or a staff grant's id.",
            "x-data-class": "operational"
          },
          "subject_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "const": "•••",
                "description": "Masked by the caller's data policy."
              },
              {
                "type": "null",
                "description": "Denied by the caller's data policy."
              }
            ],
            "description": "What a reviewer reads for it: an email, or a service account's or key's name.",
            "x-data-class": "personal"
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "description": "The access it held when the review began: a role template, a key's service account, or a staff grant's level.",
            "x-data-class": "operational"
          },
          "last_active_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was last seen acting before the review began, where known.",
            "x-data-class": "operational"
          },
          "decision": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "keep",
              "change_role",
              "revoke",
              null
            ],
            "description": "keep, change_role or revoke; null until decided.",
            "x-data-class": "operational"
          },
          "new_role_template_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The role template a change_role decision gave the member.",
            "x-data-class": "operational"
          },
          "decided_by": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 20,
            "pattern": "^[A-Za-z0-9_-]{1,20}$",
            "format": "tradehq-user-id",
            "description": "Who decided it.",
            "x-data-class": "operational"
          },
          "decided_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was decided.",
            "x-data-class": "operational"
          },
          "own": {
            "type": "boolean",
            "description": "Whether it is the caller's own row, which another admin decides.",
            "x-data-class": "operational"
          }
        },
        "required": [
          "item_id",
          "review_id",
          "kind",
          "subject_id",
          "subject_label",
          "own"
        ],
        "additionalProperties": false
      },
      "description": "Its items, when one review is asked for (review_id); null otherwise.",
      "x-data-class": "operational"
    }
  },
  "required": [
    "review_id",
    "org_id",
    "name",
    "covers",
    "due_at",
    "status",
    "total",
    "decided",
    "created_by",
    "created_at",
    "closed_by",
    "closed_at",
    "evidence_document_id",
    "items"
  ],
  "additionalProperties": false
}

Refusals

  • nothing_to_review · 422 · none of members, guests, service_accounts, api_keys and staff_grants is true
  • due_date_passed · 422 · the due date is before today (UTC)
  • idempotency_key_reused · 409 · this Idempotency-Key already started an access review with different inputs
  • retry_key_mismatch · 409 · the Idempotency-Key was already used with different inputs
  • retry_key_in_flight · 409 · a request with this Idempotency-Key is still running
  • retry_key_lost · 409 · another request took over this Idempotency-Key first; no review was started

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

Surfaces

DesktopF
MobileD5
APIF
MCPF*
VoiceD5
PushF
OneBoxN
OutboundN
  • Mobile: degraded: composition
  • MCP: approval required
  • Voice: degraded: composition
  • OneBox: no document originates an access review
  • Outbound: crosses to no counterparty

Events

Related

create_sso_connection, invite_user, update_sso_connection