{
  "openapi": "3.1.0",
  "info": {
    "title": "Journey HXP API",
    "version": "1.1.0",
    "description": "Organization-scoped operations for trusted systems integrating with Journey HXP. Journey Core remains the system-of-record API for core hospitality data."
  },
  "servers": [
    {
      "url": "https://v3.hxp.journey.com/api/external/v1"
    }
  ],
  "security": [
    {
      "workosApiKey": []
    }
  ],
  "paths": {
    "/brands": {
      "get": {
        "operationId": "listBrands",
        "summary": "List brands and their associated venues",
        "description": "Requires hxp:api:brands:read. The API key determines the organization; callers cannot select a tenant in the path or query.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of brands",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          },
          "500": {
            "$ref": "#/components/responses/Problem"
          },
          "502": {
            "$ref": "#/components/responses/Problem"
          },
          "503": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/messaging": {
      "get": {
        "operationId": "readMessaging",
        "summary": "Read scoped conversations, Actions or change events",
        "description": "Requires an active HXP messaging grant created in Settings and the matching WorkOS permission: threads:read for thread, actions:read for actions, events:read for events (all prefixed hxp:api:). Events additionally require permission to read the underlying resource. Pages scan up to 100 records before audience filtering, so an empty page may have a continuation cursor. Sensitive/deleted/source-derived messages and private AI history are excluded. Events are polling notifications, not a deletion-complete replication log. Availability requires operator activation; disabled deployments return 503.",
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 180,
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
            },
            "description": "Exact workspace ID granted to this key. Organization is derived from the credential, never supplied by the caller."
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "thread",
                "actions",
                "events"
              ],
              "default": "actions"
            },
            "description": ""
          },
          {
            "name": "guest",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 180,
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
            },
            "description": "Required for view=thread; canonical guest ID already known by your system."
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 180,
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
            },
            "description": "Optional single Action ID for view=actions."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 180,
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
            },
            "description": "Opaque nextCursor from the previous thread/actions page."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Persist the event cursor separately for each integration and scope."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized HXP-owned records",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessagingRead"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "404": {
            "$ref": "#/components/responses/Problem"
          },
          "409": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          },
          "500": {
            "$ref": "#/components/responses/Problem"
          },
          "503": {
            "$ref": "#/components/responses/Problem"
          }
        }
      },
      "post": {
        "operationId": "transitionAction",
        "summary": "Claim, complete or cancel an Action as an integration",
        "description": "claim requires hxp:api:actions:claim; finish requires hxp:api:actions:complete; cancel_action requires hxp:api:actions:cancel. Claim only unowned Actions; finish/cancel only Actions owned by this integration. Changes use optimistic concurrency and durable idempotency. Refresh the Action after success to obtain its new version. No guest delivery or canonical fulfillment is triggered.",
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 180,
              "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
            },
            "description": "Exact workspace ID granted to this key. Organization is derived from the credential, never supplied by the caller."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 180,
              "pattern": "^[A-Za-z0-9_:-]+$"
            },
            "description": "Reuse the same key and identical body after an uncertain result. Use a new key for a new transition."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActionCommand"
              },
              "examples": {
                "claim": {
                  "value": {
                    "type": "claim",
                    "id": "action_example",
                    "expectedVersion": 1
                  }
                },
                "complete": {
                  "value": {
                    "type": "finish",
                    "id": "action_example",
                    "expectedVersion": 2,
                    "evidence": "Synthetic test task completed."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Persisted transition and receipt, or the original result on replay",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "404": {
            "$ref": "#/components/responses/Problem"
          },
          "409": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          },
          "500": {
            "$ref": "#/components/responses/Problem"
          },
          "503": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "workosApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An organization-owned API key created in HXP Settings. Send only in the Authorization header."
      }
    },
    "parameters": {
      "RequestId": {
        "name": "X-Request-ID",
        "in": "header",
        "required": false,
        "description": "Optional caller correlation ID (8-128 safe characters). HXP creates one when omitted or invalid.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128,
          "pattern": "^[a-zA-Z0-9._:-]+$"
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Request correlation ID",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitLimit": {
        "description": "Requests allowed in the current one-minute window",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Requests remaining in the current window",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Unix timestamp when the current window resets",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitPolicy": {
        "description": "Current IETF HTTPAPI draft quota policy metadata",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit": {
        "description": "Current IETF HTTPAPI draft remaining-quota metadata",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds before a retry is advised",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "Authenticate": {
        "description": "Bearer authentication error or required permission",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "Problem details",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/RequestId"
          },
          "WWW-Authenticate": {
            "$ref": "#/components/headers/Authenticate"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "title",
          "status",
          "code",
          "request_id",
          "retryable"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "code": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "retryable": {
            "type": "boolean"
          }
        }
      },
      "BrandList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "data",
          "organization",
          "page"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Brand"
            }
          },
          "organization": {
            "$ref": "#/components/schemas/Organization"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        }
      },
      "Organization": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "name"
        ],
        "properties": {
          "object": {
            "const": "organization"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Brand": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "name",
          "description",
          "website_url",
          "logo_url",
          "logo_light_url",
          "logo_dark_url",
          "venue_count",
          "venues"
        ],
        "properties": {
          "object": {
            "const": "brand"
          },
          "id": {
            "type": "string",
            "description": "Stable external BrandID"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "website_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "logo_light_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "logo_dark_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "venue_count": {
            "type": "integer",
            "minimum": 0
          },
          "venues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Venue"
            }
          }
        }
      },
      "Venue": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "object",
          "id",
          "brand_id",
          "name",
          "type",
          "city",
          "state",
          "country",
          "website_url",
          "hero_image_url",
          "hero_video_url"
        ],
        "properties": {
          "object": {
            "const": "venue"
          },
          "id": {
            "type": "string",
            "description": "Stable external VenueID"
          },
          "brand_id": {
            "type": "string",
            "description": "Stable external BrandID"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "website_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "hero_image_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "hero_video_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        }
      },
      "Page": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "limit",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Audience": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "staff"
              }
            },
            "required": [
              "type"
            ]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "team"
              },
              "teamId": {
                "type": "string",
                "minLength": 1,
                "maxLength": 180,
                "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
              }
            },
            "required": [
              "type",
              "teamId"
            ]
          }
        ]
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "organizationId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "scopeId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "guestId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "stayId": {
            "type": [
              "string",
              "null"
            ]
          },
          "audience": {
            "$ref": "#/components/schemas/Audience"
          },
          "parentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "actorId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "authorName": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "sensitive": {
            "const": false
          },
          "deleted": {
            "const": false
          },
          "kind": {
            "const": "comment"
          },
          "version": {
            "type": "integer"
          },
          "pinned": {
            "type": "boolean"
          },
          "pinExpiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "mentions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "enum": [
                    "person",
                    "team"
                  ]
                },
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 180,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
                }
              },
              "required": [
                "type",
                "id"
              ]
            }
          },
          "references": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "enum": [
                    "guest",
                    "room"
                  ]
                },
                "guestId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 180,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
                },
                "stayId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "label": {
                  "type": "string"
                }
              },
              "required": [
                "type",
                "guestId",
                "stayId",
                "label"
              ]
            }
          },
          "reactions": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "organizationId",
          "scopeId",
          "guestId",
          "stayId",
          "audience",
          "parentId",
          "actorId",
          "authorName",
          "body",
          "sensitive",
          "deleted",
          "kind",
          "version",
          "pinned",
          "mentions",
          "reactions",
          "createdAt",
          "updatedAt"
        ]
      },
      "Action": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "organizationId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "scopeId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "guestId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "stayId": {
            "type": [
              "string",
              "null"
            ]
          },
          "audience": {
            "$ref": "#/components/schemas/Audience"
          },
          "sourceMessageId": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "teamId": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownerId": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdBy": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "state": {
            "enum": [
              "suggestion",
              "waiting_for_teammate",
              "working",
              "complete",
              "canceled"
            ]
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "evidence": {
            "type": [
              "string",
              "null"
            ]
          },
          "receiptId": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "organizationId",
          "scopeId",
          "guestId",
          "stayId",
          "audience",
          "sourceMessageId",
          "title",
          "teamId",
          "ownerId",
          "ownerName",
          "createdBy",
          "state",
          "dueAt",
          "evidence",
          "receiptId",
          "version",
          "createdAt",
          "updatedAt"
        ]
      },
      "CollaborationEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "sequence": {
            "type": "integer",
            "minimum": 1
          },
          "type": {
            "type": "string"
          },
          "resourceId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "actorId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 180,
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sequence",
          "type",
          "resourceId",
          "actorId",
          "createdAt"
        ]
      },
      "ThreadPage": {
        "type": "object",
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "messages",
          "nextCursor"
        ]
      },
      "ActionPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Action"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "nextCursor"
        ]
      },
      "EventPage": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CollaborationEvent"
            }
          },
          "cursor": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "events",
          "cursor"
        ]
      },
      "MessagingRead": {
        "type": "object",
        "properties": {
          "data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ThreadPage"
              },
              {
                "$ref": "#/components/schemas/ActionPage"
              },
              {
                "$ref": "#/components/schemas/EventPage"
              }
            ]
          }
        },
        "required": [
          "data"
        ]
      },
      "ActionCommand": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "claim"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 180,
                "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              }
            },
            "required": [
              "type",
              "id",
              "expectedVersion"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "finish"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 180,
                "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              },
              "evidence": {
                "type": "string",
                "minLength": 8,
                "maxLength": 2000,
                "description": "Human-readable completion evidence; do not send secrets."
              }
            },
            "required": [
              "type",
              "id",
              "expectedVersion",
              "evidence"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "cancel_action"
              },
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 180,
                "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
              },
              "expectedVersion": {
                "type": "integer",
                "minimum": 1
              }
            },
            "required": [
              "type",
              "id",
              "expectedVersion"
            ],
            "additionalProperties": false
          }
        ]
      },
      "ActionResult": {
        "type": "object",
        "properties": {
          "result": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 180,
                "pattern": "^[a-zA-Z0-9][a-zA-Z0-9:._-]*$"
              },
              "kind": {
                "const": "action"
              },
              "receiptId": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "kind",
              "receiptId"
            ]
          }
        },
        "required": [
          "result"
        ]
      }
    }
  }
}
