{
  "openapi": "3.1.1",
  "info": {
    "title": "WhooshBang API",
    "version": "3.2.0",
    "description": "The V1 contract for human organization/project administration, project-scoped\nsubscription links, and asynchronous text messages. A Clerk session selects\none organization for administration. A project credential selects one organization,\nproject, and `test` or `live` environment for product operations; request\nbodies cannot override either authenticated scope.\n\nA person's OAuth grant selects one organization and carries scopes, but no\nproject. It names the project and environment it acts in through the URL\npath, on the environment-scoped form of each operation; the service checks\nthat path against the granting person's membership on every call. The flat\nforms remain credential-only and are unchanged.\n\nResource identifiers are opaque and are not authorization. Reads outside the\ncredential scope return the same `404` shape as absent resources. Provider\ncredentials, raw Telegram identity, and protected provider responses are\nnever part of this API.\n",
    "termsOfService": "https://flowxo.com/terms",
    "contact": {
      "name": "WhooshBang Support",
      "url": "https://flowxo.com/contact"
    },
    "license": { "name": "Proprietary", "url": "https://flowxo.com/terms" }
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    {
      "url": "https://api.whooshbang.com",
      "description": "Environment is selected by the bearer credential, not the URL or body."
    }
  ],
  "security": [{ "bearerCredential": [] }],
  "tags": [
    {
      "name": "Organization",
      "description": "The current Clerk organization projected as a WhooshBang organization."
    },
    {
      "name": "Teammates",
      "description": "The people in an organization, their roles and the projects each can see."
    },
    {
      "name": "Projects",
      "description": "Organization-scoped applications with transactionally bootstrapped test/live environments."
    },
    {
      "name": "API credentials",
      "description": "Human-administered, environment-scoped bearer credentials with one-time secret reveal."
    },
    {
      "name": "Organization credentials",
      "description": "Human-administered, organization-scoped bearer credentials that name their project and environment per call."
    },
    {
      "name": "Provider installations",
      "description": "Organization-owned provider authority established through credential-free browser handoffs."
    },
    {
      "name": "Subscription links",
      "description": "Single-use, expiring Telegram authorization links."
    },
    {
      "name": "Messages",
      "description": "Asynchronous logical messages and their highest proven outcomes."
    },
    {
      "name": "Message categories",
      "description": "Project categories and subscriber choices for those categories."
    },
    {
      "name": "Machine clients",
      "description": "Project-administered, destination-bound local-client identities and one-way credential metadata."
    },
    {
      "name": "Machine events",
      "description": "Durable per-machine long polling and contiguous acknowledgement."
    },
    {
      "name": "Capabilities",
      "description": "Provider-neutral rendering and evidence capabilities."
    },
    {
      "name": "Customer endpoints",
      "description": "Verified signed-event destinations with one-time secret lifecycle and content-free diagnostics."
    },
    {
      "name": "Channel connections",
      "description": "One environment's selection of a provider identity, with credential custody held internally and never exposed."
    },
    {
      "name": "Recipient experience",
      "description": "Constrained project brand, exact environment browser policy, and attenuated recipient sessions."
    },
    {
      "name": "Subscribers",
      "description": "Application-owned subscriber identity and transactional initial static-group membership."
    },
    {
      "name": "Subscriber groups",
      "description": "Environment-scoped static groups and monotonic membership generations."
    },
    {
      "name": "Operators",
      "description": "Current teammates, personal notification preferences and membership-derived service email."
    },
    {
      "name": "Group broadcasts",
      "description": "Durable group acceptance and aggregate projection over ordinary child messages."
    }
  ],
  "paths": {
    "/v1/projects/{project_id}/message-categories": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "get": {
        "operationId": "listMessageCategories",
        "summary": "List project message categories",
        "tags": ["Message categories"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "responses": {
          "200": {
            "description": "Categories in this project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageCategoryCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createMessageCategory",
        "summary": "Add a project message category",
        "tags": ["Message categories"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMessageCategoryRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Category added.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MessageCategory" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/message-categories/{category_key}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        {
          "name": "category_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/MessageCategoryKey" }
        }
      ],
      "put": {
        "operationId": "updateMessageCategory",
        "summary": "Change a project's message category",
        "tags": ["Message categories"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMessageCategoryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Category updated.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MessageCategory" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      },
      "delete": {
        "operationId": "deleteMessageCategory",
        "summary": "Remove an unused message category",
        "tags": ["Message categories"],
        "description": "The default category and a category still used by queued messages cannot be removed.",
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "responses": {
          "204": { "description": "Category removed." },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences/categories": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "getOwnCategoryPreferences",
        "summary": "Read my message category switches",
        "tags": ["Message categories"],
        "security": [{ "clerkSession": [] }],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Category choices for the signed-in person.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCategoryPreferenceCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences/categories/{category_key}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "category_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/MessageCategoryKey" }
        }
      ],
      "put": {
        "operationId": "setOwnCategoryPreference",
        "summary": "Switch one of my message categories on or off",
        "tags": ["Message categories"],
        "security": [{ "clerkSession": [] }],
        "x-required-scopes": ["messages:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSubscriberCategoryPreferenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated category choice.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCategoryPreference"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/whoami": {
      "get": {
        "operationId": "whoAmI",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "Identify the authenticated caller",
        "description": "Personal login identifies me without a recipient question. Shared or service credentials report their actual principal and require an explicit recipient. No account owner or credential creator is inferred.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerOrganizationCredential": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] },
          { "machineCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" }
        ],
        "responses": {
          "200": {
            "description": "Actual principal and safe authorized messaging context.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WhoAmI" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/operators": {
      "get": {
        "operationId": "listOperators",
        "x-notification-scopes": ["notifications:team"],
        "summary": "listOperators",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorCollection" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/operators/resolve": {
      "get": {
        "operationId": "resolveOperator",
        "x-notification-scopes": ["notifications:team"],
        "summary": "resolveOperator",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          {
            "name": "recipient",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorResolution" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/operator-messages": {
      "post": {
        "operationId": "sendOperatorMessage",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "sendOperatorMessage",
        "description": "Message a current teammate by name or operator ID. Personal callers may omit recipient or use me. Shared credentials must name a recipient. Runtime machine credentials report recipient_required for omitted or me; named operator sends are forbidden because runtime authority remains subscriber-bound.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerOrganizationCredential": [] },
          { "machineCredential": [] },
          { "bearerGrant": ["messages:write"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:write"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOperatorMessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OperatorMessageResult"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/operators/broadcasts": {
      "post": {
        "operationId": "broadcastOperators",
        "x-notification-scopes": ["notifications:team"],
        "summary": "broadcastOperators",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:write"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:write"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGroupBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorBroadcast" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/operators/broadcasts/{broadcast_id}": {
      "get": {
        "operationId": "getOperatorBroadcast",
        "x-notification-scopes": ["notifications:team"],
        "summary": "getOperatorBroadcast",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          {
            "name": "broadcast_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorBroadcast" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences": {
      "get": {
        "operationId": "getOperatorPreferences",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "getOperatorPreferences",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorPreferences" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences/preferred-binding": {
      "put": {
        "operationId": "setOperatorPreferredBinding",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "setOperatorPreferredBinding",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:write"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:write"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPreferredBindingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorPreferences" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences/bindings/{binding_id}/resume": {
      "post": {
        "operationId": "resumeOperatorBinding",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "resumeOperatorBinding",
        "description": "Resumes one of the authenticated person's own paused channels. Only the authenticated human can manage personal preferences; this never establishes consent or revives a revoked binding.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:write"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:write"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          {
            "in": "path",
            "name": "binding_id",
            "required": true,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorPreferences" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-preferences/connect": {
      "post": {
        "operationId": "connectOperatorChannel",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "connectOperatorChannel",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": ["messages:write"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] }
        ],
        "x-required-scopes": ["messages:write"],
        "parameters": [
          { "$ref": "#/components/parameters/ProjectId" },
          { "$ref": "#/components/parameters/EnvironmentId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OperatorConnectRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionLink" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/billing/project-slots": {
      "get": {
        "operationId": "getBillingProjectSlots",
        "summary": "Read reusable project slot assignments",
        "description": "Current organization administrators can read current capacity and requested/active project assignments.",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Current reusable project assignments.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingProjectSlots" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "put": {
        "operationId": "assignBillingProjectSlots",
        "summary": "Reassign reusable project slots",
        "description": "Current organization administrators can choose owned active projects within the current paid capacity. Unassigned projects retain data, accepted delivery and answers. Reuse the same idempotency key after an uncertain response.",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignBillingProjectSlotsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current reusable project assignments.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingProjectSlots" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/billing/promotions": {
      "get": {
        "operationId": "getBillingPromotions",
        "summary": "Read the organization's promotions",
        "description": "Organization administrators can read every promotion the organization holds: rewards WhooshBang gave it\nand promotion codes it redeemed, with what remains and when each ends. Promotional value has no cash\nvalue, is never refunded and cannot move to another organization.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "The organization's promotions, newest first.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingPromotions" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/billing/promotions/redeem": {
      "post": {
        "operationId": "redeemBillingPromotion",
        "summary": "Redeem a promotion code",
        "description": "Organization administrators can redeem a promotion code for their own organization. Nothing is charged.\nEvery code that cannot be redeemed (mistyped, ended, fully used, not offered to this organization, or not\ncombinable with a promotion it already holds) receives the same `resource_not_found` answer. Repeated\nrefusals are rate limited per organization; wait for `Retry-After`. Reuse the same idempotency key after\nan uncertain response: it can never redeem twice.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RedeemBillingPromotionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The same promotion, replayed for a repeated idempotency key.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingPromotion" }
              }
            }
          },
          "201": {
            "description": "The promotion the code gave the organization.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingPromotion" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/billing/auto-top-up": {
      "get": {
        "operationId": "getAutoTopUpSettings",
        "summary": "Read automatic top-up settings",
        "description": "Requires an organization administrator and human billing consent. Automatic top-up is off by default.\nThe selected gross monthly cap counts pending and paid purchases initiated in each UTC calendar month.\nRefunds do not restore that cap. Disable stops future purchases; an authorized processing purchase may finish.\nPurchases use the organization's one default card. Only verified payments fund credit.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Read automatic top-up settings.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AutoTopUpSettings" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      },
      "put": {
        "operationId": "updateAutoTopUpSettings",
        "summary": "Confirm automatic top-up settings",
        "description": "Requires an organization administrator and human billing consent. Automatic top-up is off by default.\nThe selected gross monthly cap counts pending and paid purchases initiated in each UTC calendar month.\nRefunds do not restore that cap. Disable stops future purchases; an authorized processing purchase may finish.\nPurchases use the organization's one default card. Only verified payments fund credit.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAutoTopUpSettingsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirm automatic top-up settings.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AutoTopUpSettings" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/entitlements": {
      "get": {
        "operationId": "getBillingEntitlements",
        "summary": "Read paid account entitlements",
        "description": "Requires current organization membership. Financial purchases and preference writes require an administrator.\nPrices and paid entitlements come from server-approved offers and verified captured payments.\nAttribution expiry restores the platform mark while retaining sender identity, consent,\nunsubscribe and answer controls. payment_issue reports a recurring charge the card did not pay.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Read paid account entitlements.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingEntitlements" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/subscription-changes": {
      "post": {
        "operationId": "createSubscriptionChange",
        "description": "Quote a new recurring selection without charging. Upgrades keep renewal and charge the new plan or additional add-on units for the remaining period, without unused-time credits or offsets. Paid dropped extras remain available through their original expiry and do not renew. Requires an administrator in the current organization. Without a current plan or add-on the change starts one. Confirmation matches the saved exact cash amount and charges the default card. Uncertain outcomes recover the same owned change.",
        "summary": "Quote an approved recurring change",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SubscriptionSelection" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Quote an approved recurring change.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionChange" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/subscription-changes/{changeId}": {
      "get": {
        "operationId": "getSubscriptionChange",
        "summary": "Recover an owned recurring change Requires an administrator in the current organization. Without a current plan or add-on the change starts one. Confirmation matches the saved exact cash amount and charges the default card. Uncertain outcomes recover the same owned change.",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "changeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^subscription_change_[a-f0-9]{32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recover an owned recurring change.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionChange" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/subscription-changes/{changeId}/confirm": {
      "post": {
        "operationId": "confirmSubscriptionChange",
        "summary": "Confirm the quoted card charge or scheduled reduction Requires an administrator in the current organization. Without a current plan or add-on the change starts one. Confirmation matches the saved exact cash amount and charges the default card. Uncertain outcomes recover the same owned change.",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "changeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^subscription_change_[a-f0-9]{32}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmSubscriptionChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirm the quoted card charge or scheduled reduction.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionChange" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/subscription-changes/{changeId}/cancel": {
      "post": {
        "operationId": "cancelSubscriptionChange",
        "summary": "Discard a quote or undo a scheduled change",
        "description": "Requires an administrator in the current organization. Discards a reserved quote before anything is charged, or undoes a change scheduled for the end of the paid month before it takes effect; the plan and add-ons then stay exactly as they are. A change already being charged cannot be discarded. Repeating the request reports the same expired change.",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "changeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^subscription_change_[a-f0-9]{32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The discarded quote or undone scheduled change, now expired.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionChange" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/projects/{projectId}/attribution": {
      "get": {
        "operationId": "getProjectAttribution",
        "summary": "Read project attribution preference and entitlement",
        "description": "Requires current organization membership. Financial purchases and preference writes require an administrator.\nPrices and paid entitlements come from server-approved offers and verified captured payments.\nAttribution expiry restores the platform mark while retaining sender identity, consent,\nunsubscribe and answer controls. payment_issue reports a recurring charge the card did not pay.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Read project attribution preference and entitlement.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProjectAttribution" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      },
      "put": {
        "operationId": "updateProjectAttribution",
        "summary": "Update project attribution preference",
        "description": "Requires current organization membership. Financial purchases and preference writes require an administrator.\nPrices and paid entitlements come from server-approved offers and verified captured payments.\nAttribution expiry restores the platform mark while retaining sender identity, consent,\nunsubscribe and answer controls. payment_issue reports a recurring charge the card did not pay.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectAttributionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Update project attribution preference.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProjectAttribution" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/card-setups": {
      "post": {
        "operationId": "createCardSetup",
        "summary": "Open a card form session",
        "description": "Requires a current organization administrator. A person enters the card in the\nembeddable payment form; card numbers never pass through WhooshBang. A complete\nsetup makes the card the organization's one default card for credit, automatic\ntop-up, plans and add-ons. Opening a setup does not charge anything.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "201": {
            "description": "Open a card form session.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CardSetup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/card-setups/{setupId}/reconcile": {
      "post": {
        "operationId": "reconcileCardSetup",
        "summary": "Save a confirmed card as the default",
        "description": "Requires a current organization administrator. A person enters the card in the\nembeddable payment form; card numbers never pass through WhooshBang. A complete\nsetup makes the card the organization's one default card for credit, automatic\ntop-up, plans and add-ons. Opening a setup does not charge anything.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "setupId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^card_setup_[a-f0-9]{32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Save a confirmed card as the default.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CardSetup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/credit-purchases": {
      "post": {
        "operationId": "createCreditPurchase",
        "summary": "Buy a credit pack with the default card",
        "description": "Requires a current organization administrator. Charges the default card for one\ncredit pack; the pack amount is the explicit approval. Without a default card the\nrequest is refused with billing_card_required. Retrying with the same\nIdempotency-Key returns the same purchase and never charges twice. Credit is\ngranted only after the payment is verified.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditPurchaseRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Buy a credit pack with the default card.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CreditPurchase" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/credit-purchases/{purchaseId}/reconcile": {
      "post": {
        "operationId": "reconcileCreditPurchase",
        "summary": "Refresh a credit purchase",
        "description": "Requires a current organization administrator. Charges the default card for one\ncredit pack; the pack amount is the explicit approval. Without a default card the\nrequest is refused with billing_card_required. Retrying with the same\nIdempotency-Key returns the same purchase and never charges twice. Credit is\ngranted only after the payment is verified.\nReconcile after the customer confirms the charge in the payment form.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "purchaseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^credit_purchase_[a-f0-9]{32}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Refresh a credit purchase.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CreditPurchase" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/invoices": {
      "get": {
        "operationId": "listBillingInvoices",
        "summary": "List invoices and receipts",
        "description": "Requires a current organization administrator. Returns the most recent\ncredit purchases, automatic top-ups, recurring invoices and the welcome credit,\nnewest first, each with its downloadable invoice or receipt where one exists.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "List invoices and receipts.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingInvoiceCollection"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing/receipt-email": {
      "put": {
        "operationId": "updateBillingReceiptEmail",
        "summary": "Choose where receipts are emailed",
        "description": "Requires a current organization administrator. Receipts and invoices for\nevery charge go to this address. Null stops them.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBillingReceiptEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Choose where receipts are emailed.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingAccount" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/billing": {
      "get": {
        "operationId": "getBillingAccount",
        "summary": "Read account delivery credit",
        "description": "Requires a current organization administrator. Bundle bonus funds core sends only.\nShared email uses purchased or starter credit at $1 per 1,000.\nCredit is granted only after a verified payment. card is the one default card;\nreceipt_email is where receipts go.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["billing:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Read account delivery credit.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BillingAccount" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" }
        }
      }
    },
    "/v1/organization": {
      "get": {
        "operationId": "getOrganization",
        "summary": "Read the current organization projection",
        "description": "Returns the WhooshBang organization selected by the verified Clerk\norganization session and the caller's projected role. Clerk organization\nand user identifiers are never public response fields.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "The current organization projection.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationProjection"
                },
                "examples": {
                  "projectedOrganization": {
                    "value": {
                      "id": "organization_synthetic_001",
                      "name": "Synthetic Organization",
                      "status": "active",
                      "membership": { "role": "admin" },
                      "created_at": "2026-07-28T12:00:00Z",
                      "updated_at": "2026-07-28T12:00:00Z",
                      "diagnostic_id": "diag_organization_synthetic_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/close": {
      "post": {
        "operationId": "closeOrganization",
        "summary": "Close the current customer organization",
        "description": "Terminally closes the organization selected by the verified Clerk\norganization session. Only an administrator may close it. OAuth grants\nand API credentials are deliberately excluded: delegated authority must\nnot be able to erase the organization that granted it.\n\nThe request requires the exact confirmation `close-organization`. Repeating a\ncompleted closure is safe and returns the original `closed_at`. The\nresult names provider-owned resources the administrator must still retire\noutside WhooshBang, such as revoking a customer-managed Telegram bot token\nin BotFather; no provider credential is returned.\n",
        "tags": ["Organization"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseOrganizationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The organization is closed, with any manual provider retirement still required.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationClosureResult"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/teammates": {
      "get": {
        "operationId": "listTeammates",
        "summary": "List the organization's teammates and open invitations",
        "description": "Returns every person in the organization with their role, the projects\nthey can see and whether they have joined, plus every invitation not yet\naccepted. Any teammate may read it; only an admin may change it.\n",
        "tags": ["Teammates"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["teammates:read"] }
        ],
        "x-required-scopes": ["teammates:read"],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "The organization's teammates.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TeammateCollection" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "inviteTeammate",
        "summary": "Invite a teammate",
        "description": "Emails one invitation carrying the chosen role and, for a member or\nmessenger, the projects they will see. Nothing else is needed after they\naccept. Inviting an address that is already invited or already a\nteammate is refused rather than repeated.\n",
        "tags": ["Teammates"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["teammates:write"] }
        ],
        "x-required-scopes": ["teammates:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/InviteTeammateRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The invitation.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Teammate" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/teammates/{teammate_id}": {
      "parameters": [
        {
          "name": "teammate_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "delete": {
        "operationId": "removeTeammate",
        "summary": "Remove a teammate or revoke an invitation",
        "description": "Removes an active teammate from the organization, or revokes an\ninvitation. Removal applies to their next request, including requests\nfrom MCP connections they authorized. The last admin cannot be removed.\n",
        "tags": ["Teammates"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["teammates:write"] }
        ],
        "x-required-scopes": ["teammates:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "204": {
            "description": "The teammate was removed or the invitation revoked.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/teammates/{teammate_id}/access": {
      "parameters": [
        {
          "name": "teammate_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "put": {
        "operationId": "setTeammateAccess",
        "summary": "Change a teammate's role and projects",
        "description": "Replaces the role and, for a member or messenger, the projects of an\nactive teammate or an open invitation. Narrowed access applies to their\nnext request. The last admin cannot be demoted.\n",
        "tags": ["Teammates"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["teammates:write"] }
        ],
        "x-required-scopes": ["teammates:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/TeammateAccessRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The teammate with their new access.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Teammate" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/teammates/{teammate_id}/resend": {
      "parameters": [
        {
          "name": "teammate_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "post": {
        "operationId": "resendTeammateInvitation",
        "summary": "Resend an invitation",
        "description": "Replaces an open invitation with a fresh one carrying the same role and\nprojects, and emails it again. The earlier link stops working.\n",
        "tags": ["Teammates"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["teammates:write"] }
        ],
        "x-required-scopes": ["teammates:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "200": {
            "description": "The renewed invitation.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Teammate" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/provider-installations": {
      "get": {
        "operationId": "listProviderInstallations",
        "summary": "List customer-owned email provider installations",
        "description": "Returns only safe WhooshBang lifecycle, health, deployment authorization availability and resumable authorization progress for the current organization. Provider team identity, grants and credentials are absent.",
        "tags": ["Provider installations"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:read"] }
        ],
        "x-required-scopes": ["connections:read"],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "The current organization's email provider installations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderInstallationCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "post": {
        "operationId": "createProviderInstallation",
        "summary": "Connect a customer-owned Resend team",
        "description": "Starts one short-lived OAuth authorization for an organization administrator. The returned installation contains the first-party browser handoff and no provider credential.",
        "tags": ["Provider installations"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProviderInstallationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The pending installation and resumable authorization handoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderInstallation"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/provider-installations/{provider_installation_id}": {
      "parameters": [
        {
          "name": "provider_installation_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getProviderInstallation",
        "summary": "Read one customer-owned email provider installation",
        "tags": ["Provider installations"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:read"] }
        ],
        "x-required-scopes": ["connections:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Safe installation lifecycle and authorization progress.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderInstallation"
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "operationId": "disconnectProviderInstallation",
        "summary": "Disconnect a customer-owned email provider installation",
        "description": "Removes local authority first, deletes only WhooshBang's owned webhook while authorization remains, revokes the newest refresh authority, retires dependent edges, and then destroys credential custody.",
        "tags": ["Provider installations"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "204": {
            "description": "The installation is disconnected or was already absent."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/provider-installations/{provider_installation_id}/reconnect": {
      "post": {
        "operationId": "reconnectProviderInstallation",
        "summary": "Reauthorize one customer-owned email provider installation",
        "description": "Starts a new short-lived OAuth handoff. Completion succeeds only when the signature-verified access token identifies the same Resend team as the existing installation.",
        "tags": ["Provider installations"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "parameters": [
          {
            "name": "provider_installation_id",
            "in": "path",
            "required": true,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        ],
        "responses": {
          "201": {
            "description": "The installation with a resumable reauthorization handoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderInstallation"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/email-domains": {
      "get": {
        "operationId": "listEmailDomains",
        "summary": "List account-owned email domains",
        "description": "Returns one page of the resumable lifecycle, separate sending and receiving readiness, exact DNS records, safe failures, and exact connection assignments for domains in the current organization.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:read"] }
        ],
        "x-required-scopes": ["connections:read"],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "The organization's customer-owned email domains.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailDomainCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "post": {
        "operationId": "createEmailDomain",
        "summary": "Create or safely adopt a dedicated sending subdomain",
        "description": "Canonicalizes the IDNA domain, reconciles the connected team before creating, enables sending and receiving with tracking off, and begins the durable guided-DNS lifecycle. Repeating the same organization, installation and domain returns the existing lifecycle.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailDomainRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new resumable domain lifecycle.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/email-domains/{email_domain_id}": {
      "parameters": [
        {
          "name": "email_domain_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getEmailDomain",
        "summary": "Read one resumable email-domain checklist",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:read"] }
        ],
        "x-required-scopes": ["connections:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Current domain, DNS, capability and assignment state.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "operationId": "deleteEmailDomain",
        "summary": "Remove an unassigned customer email domain",
        "description": "Revokes DNS-administrator links immediately and queues deletion of the exact provider domain. Active connection assignments must be removed first. A completed deletion can be created again later.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "202": {
            "description": "Provider deletion is queued or already complete.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/email-domains/{email_domain_id}/verify": {
      "post": {
        "operationId": "verifyEmailDomain",
        "summary": "Confirm that DNS is ready for verification",
        "description": "Requests a distinct destructive provider verification attempt. After the first attempt, a request is admitted only after ten minutes and only when no DNS-record status has moved since the prior trigger; otherwise it safely returns the unchanged lifecycle.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "parameters": [
          {
            "name": "email_domain_id",
            "in": "path",
            "required": true,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        ],
        "responses": {
          "200": {
            "description": "The current lifecycle; repeated early requests do not reset provider verification.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/email-domains/{email_domain_id}/retry": {
      "post": {
        "operationId": "retryEmailDomain",
        "summary": "Resume a provider-action-required domain",
        "description": "Reconciles by canonical name when creation has no provider reference, resumes deletion when cleanup was interrupted, or starts a fresh bounded roundtrip generation after the customer resolves the provider-side condition.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "parameters": [
          {
            "name": "email_domain_id",
            "in": "path",
            "required": true,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        ],
        "responses": {
          "200": {
            "description": "Current domain after the corrective workflow is resumed.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/email-domains/{email_domain_id}/guide-link": {
      "parameters": [
        {
          "name": "email_domain_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "post": {
        "operationId": "createEmailDomainGuideLink",
        "summary": "Create a short-lived secret-free DNS administrator link",
        "description": "Revokes the prior link and returns the domain with a new 24-hour instruction URL. The page contains only the domain, exact DNS records, statuses, and reviewed manual guidance.",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "201": {
            "description": "The domain carrying the one-time visible instruction URL.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EmailDomain" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "delete": {
        "operationId": "revokeEmailDomainGuideLink",
        "summary": "Revoke every live DNS administrator link for a domain",
        "tags": ["Email domains"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["connections:write"] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-organization-membership": "required",
        "x-required-membership-role": "admin",
        "responses": {
          "204": { "description": "Live links are revoked, or none existed." },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/email-domain-guides/{token}": {
      "get": {
        "operationId": "readEmailDomainGuide",
        "summary": "Read a short-lived secret-free DNS guide",
        "description": "Public bearer link for a DNS administrator. It carries no WhooshBang session, OAuth grant, provider identifier, or credential and is unavailable after expiry or revocation.",
        "tags": ["Email domains"],
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "pattern": "^[A-Za-z0-9_-]{43}$" }
          }
        ],
        "responses": {
          "200": {
            "description": "A complete manual DNS checklist.",
            "content": { "text/html": { "schema": { "type": "string" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/organization/credentials": {
      "get": {
        "operationId": "listOrganizationCredentials",
        "summary": "List safe organization credential metadata",
        "description": "Returns only credentials owned by the organization selected by the verified\nClerk organization session. Secrets and digest material are never\nreturned.\n",
        "tags": ["Organization credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ApiCredentialAfterCursor" },
          { "$ref": "#/components/parameters/ApiCredentialPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "A stable page of safe organization credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationCredentialCollection"
                },
                "examples": {
                  "organizationCredentials": {
                    "value": {
                      "items": [
                        {
                          "id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
                          "prefix": "wb_oc1.ocred_AAAAAAAA",
                          "label": "Synthetic release automation",
                          "scopes": [
                            "organization:read",
                            "messages:write",
                            "messages:read"
                          ],
                          "created_by": "member_synthetic_001",
                          "created_at": "2026-07-25T17:45:00Z",
                          "last_used_at": "2026-07-25T17:50:00Z",
                          "status": "active"
                        }
                      ],
                      "page": 1,
                      "page_size": 50,
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "createOrganizationCredential",
        "summary": "Create an organization-scoped API credential",
        "description": "Creates one credential against the whole organization. It names no project\nand no environment: a request names them in its path, and the\ncredential's authority on that path is the intersection of its scopes\nwith the project-credential vocabulary, so it is never wider than a\nproject credential would have been for the same project environment.\nThe complete bearer secret appears only in this creation response. It\ncannot be read later and is never replayed from an idempotency cache.\n",
        "tags": ["Organization credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrganizationCredentialRequest"
              },
              "examples": {
                "createOrganizationCredential": {
                  "value": {
                    "label": "Release automation",
                    "scopes": [
                      "organization:read",
                      "messages:write",
                      "messages:read"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creation-only secret reveal and safe credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationCredentialSecretReveal"
                },
                "examples": {
                  "createdOrganizationCredential": {
                    "value": {
                      "credential": {
                        "id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
                        "prefix": "wb_oc1.ocred_AAAAAAAA",
                        "label": "Synthetic release automation",
                        "scopes": [
                          "organization:read",
                          "messages:write",
                          "messages:read"
                        ],
                        "created_by": "member_synthetic_001",
                        "created_at": "2026-07-25T17:45:00Z",
                        "status": "active"
                      },
                      "secret": "wb_oc1.ocred_AAAAAAAAAAAAAAAAAAAAAA.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/credentials/{organization_credential_id}/rotate": {
      "parameters": [
        { "$ref": "#/components/parameters/OrganizationCredentialId" }
      ],
      "post": {
        "operationId": "rotateOrganizationCredential",
        "summary": "Rotate an organization-scoped API credential",
        "description": "Creates one replacement with the same label and scopes. The complete new\nbearer secret appears only in this response. The replaced credential\nremains active for the explicitly declared overlap, from zero through\n86400 seconds, then becomes terminally revoked. A revoked credential\ncannot be rotated. Missing and out-of-organization credentials use the same\nnon-enumerating `404`.\n",
        "tags": ["Organization credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateOrganizationCredentialRequest"
              },
              "examples": {
                "rotateOrganizationCredential": {
                  "value": { "overlap_seconds": 3600 }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creation-only replacement secret and safe metadata for both credentials.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationCredentialRotation"
                },
                "examples": {
                  "rotatedOrganizationCredential": {
                    "value": {
                      "credential": {
                        "credential": {
                          "id": "ocred_BBBBBBBBBBBBBBBBBBBBBA",
                          "prefix": "wb_oc1.ocred_BBBBBBBB",
                          "label": "Synthetic release automation",
                          "scopes": [
                            "organization:read",
                            "messages:write",
                            "messages:read"
                          ],
                          "created_by": "member_synthetic_001",
                          "created_at": "2026-07-25T17:45:00Z",
                          "status": "active"
                        },
                        "secret": "wb_oc1.ocred_BBBBBBBBBBBBBBBBBBBBBA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBA"
                      },
                      "replaced_credential": {
                        "id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
                        "prefix": "wb_oc1.ocred_AAAAAAAA",
                        "label": "Synthetic release automation",
                        "scopes": [
                          "organization:read",
                          "messages:write",
                          "messages:read"
                        ],
                        "created_by": "member_synthetic_001",
                        "created_at": "2026-07-25T17:45:00Z",
                        "last_used_at": "2026-07-25T17:50:00Z",
                        "scheduled_revocation_at": "2026-07-25T18:45:00Z",
                        "status": "active"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/organization/credentials/{organization_credential_id}/revoke": {
      "parameters": [
        { "$ref": "#/components/parameters/OrganizationCredentialId" }
      ],
      "post": {
        "operationId": "revokeOrganizationCredential",
        "summary": "Revoke an organization-scoped API credential",
        "description": "Immediately and terminally revokes the selected credential. Repeating\nthe request for the same visible credential is safe and returns the\nsame revoked metadata without revealing secret or digest material.\nMissing and out-of-organization credentials use the same non-enumerating\n`404`.\n",
        "tags": ["Organization credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "200": {
            "description": "Safe terminal credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationCredential"
                },
                "examples": {
                  "revokedOrganizationCredential": {
                    "value": {
                      "id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
                      "prefix": "wb_oc1.ocred_AAAAAAAA",
                      "label": "Synthetic release automation",
                      "scopes": [
                        "organization:read",
                        "messages:write",
                        "messages:read"
                      ],
                      "created_by": "member_synthetic_001",
                      "created_at": "2026-07-25T17:45:00Z",
                      "last_used_at": "2026-07-25T17:50:00Z",
                      "status": "revoked",
                      "revoked_at": "2026-07-25T17:55:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects": {
      "get": {
        "operationId": "listProjects",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "List projects in the current organization",
        "description": "Returns only projects owned by the organization selected by the verified\nClerk organization session. Every project includes its complete test/live\nenvironment and default-notifier bootstrap.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ProjectAfterCursor" },
          { "$ref": "#/components/parameters/ProjectPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "A stable page of projects in the current organization.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProjectCollection" },
                "examples": {
                  "projects": {
                    "value": {
                      "items": [
                        {
                          "id": "project_synthetic_001",
                          "organization_id": "organization_synthetic_001",
                          "name": "Synthetic Alerts",
                          "slug": "synthetic-alerts",
                          "status": "active",
                          "default_locale": "es",
                          "environments": [
                            {
                              "id": "environment_synthetic_test_001",
                              "project_id": "project_synthetic_001",
                              "kind": "test",
                              "status": "active",
                              "default_notifier": {
                                "id": "notifier_synthetic_test_default_001",
                                "environment_id": "environment_synthetic_test_001",
                                "display_name": "Default",
                                "status": "active",
                                "is_default": true
                              }
                            },
                            {
                              "id": "environment_synthetic_live_001",
                              "project_id": "project_synthetic_001",
                              "kind": "live",
                              "status": "active",
                              "default_notifier": {
                                "id": "notifier_synthetic_live_default_001",
                                "environment_id": "environment_synthetic_live_001",
                                "display_name": "Default",
                                "status": "active",
                                "is_default": true
                              }
                            }
                          ],
                          "created_at": "2026-07-28T12:05:00Z",
                          "updated_at": "2026-07-28T12:05:00Z",
                          "diagnostic_id": "diag_project_synthetic_001",
                          "privacy_mode": "minimal"
                        }
                      ],
                      "page": 1,
                      "page_size": 50,
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "createProject",
        "summary": "Create a project and its default environments",
        "description": "Creates one project inside the authenticated organization. The project, its\n`test` and `live` environments, and one `Default` notifier per\nenvironment are one atomic logical resource. Equivalent replay returns\nthe original `201` response without extending idempotency retention.\n",
        "tags": ["Projects"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_organization", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateProjectRequest" },
              "examples": {
                "createProject": {
                  "value": {
                    "name": "Synthetic Alerts",
                    "slug": "synthetic-alerts",
                    "default_locale": "es"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The complete atomic project bootstrap, or the original resource on equivalent replay.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Project" },
                "examples": {
                  "createdProject": {
                    "value": {
                      "id": "project_synthetic_001",
                      "organization_id": "organization_synthetic_001",
                      "name": "Synthetic Alerts",
                      "slug": "synthetic-alerts",
                      "status": "active",
                      "default_locale": "es",
                      "environments": [
                        {
                          "id": "environment_synthetic_test_001",
                          "project_id": "project_synthetic_001",
                          "kind": "test",
                          "status": "active",
                          "default_notifier": {
                            "id": "notifier_synthetic_test_default_001",
                            "environment_id": "environment_synthetic_test_001",
                            "display_name": "Default",
                            "status": "active",
                            "is_default": true
                          }
                        },
                        {
                          "id": "environment_synthetic_live_001",
                          "project_id": "project_synthetic_001",
                          "kind": "live",
                          "status": "active",
                          "default_notifier": {
                            "id": "notifier_synthetic_live_default_001",
                            "environment_id": "environment_synthetic_live_001",
                            "display_name": "Default",
                            "status": "active",
                            "is_default": true
                          }
                        }
                      ],
                      "created_at": "2026-07-28T12:05:00Z",
                      "updated_at": "2026-07-28T12:05:00Z",
                      "diagnostic_id": "diag_project_synthetic_001",
                      "privacy_mode": "minimal"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "get": {
        "operationId": "getProject",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "Read one project in the current organization",
        "description": "Returns the complete project bootstrap. An absent project and a project\noutside the authenticated organization use the same non-enumerating `404`.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "The current project and its two environments.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Project" },
                "examples": {
                  "project": {
                    "value": {
                      "id": "project_synthetic_001",
                      "organization_id": "organization_synthetic_001",
                      "name": "Synthetic Alerts",
                      "slug": "synthetic-alerts",
                      "status": "active",
                      "default_locale": "es",
                      "environments": [
                        {
                          "id": "environment_synthetic_test_001",
                          "project_id": "project_synthetic_001",
                          "kind": "test",
                          "status": "active",
                          "default_notifier": {
                            "id": "notifier_synthetic_test_default_001",
                            "environment_id": "environment_synthetic_test_001",
                            "display_name": "Default",
                            "status": "active",
                            "is_default": true
                          }
                        },
                        {
                          "id": "environment_synthetic_live_001",
                          "project_id": "project_synthetic_001",
                          "kind": "live",
                          "status": "active",
                          "default_notifier": {
                            "id": "notifier_synthetic_live_default_001",
                            "environment_id": "environment_synthetic_live_001",
                            "display_name": "Default",
                            "status": "active",
                            "is_default": true
                          }
                        }
                      ],
                      "created_at": "2026-07-28T12:05:00Z",
                      "updated_at": "2026-07-28T12:05:00Z",
                      "diagnostic_id": "diag_project_synthetic_001",
                      "privacy_mode": "minimal"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "patch": {
        "operationId": "updateProject",
        "summary": "Set a project's privacy policy and optional connect advisory",
        "description": "Changes profile collection for both project environments. standard is the\ndefault for new projects. standard permits messenger profiles, including\nthe name a subscriber's channel gives; minimal keeps recipient language only; private keeps delivery routing and\nthe customer-supplied subscriber identifier, with no profile data.\nMoving standard to minimal erases existing identifying profile fields.\nMoving to private also erases recipient language. Increasing collection\ndoes not restore erased data. data_collection_advisory_enabled is off by\ndefault and displays a customizable data-collection notice on connect and\nconfirmation only while privacy is standard. Omitting it preserves the\nstored setting. Dashboard-session writes require an administrator.\nThe operation is naturally idempotent.\nAn absent project and one outside the organization return the same 404.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/UpdateProjectRequest" },
              "examples": {
                "updateProject": { "value": { "privacy_mode": "private" } }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The project after changing its privacy policy and clearing disallowed profile fields.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Project" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/recipient-copy-overrides": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "get": {
        "operationId": "listRecipientCopyOverrides",
        "summary": "List sparse recipient-copy overrides for one project",
        "description": "Returns only customer-authored overrides for the project in the\nauthenticated organization. Missing values are intentionally absent and use\nWhooshBang's complete shipped catalog at render time. An optional\ncanonical language filter preserves the project + language + string\naddress without applying locale negotiation.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": { "$ref": "#/components/schemas/RecipientLanguage" }
          },
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Sparse overrides ordered by language and key.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientCopyOverrideCollection"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/recipient-copy-overrides/{language}/{key}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        {
          "name": "language",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/RecipientLanguage" }
        },
        {
          "name": "key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/RecipientCopyKey" }
        }
      ],
      "put": {
        "operationId": "updateRecipientCopyOverride",
        "summary": "Customize one recipient text without changing its control action",
        "description": "Replaces the customer-authored plain-text value at one exact project +\nlanguage + string address. Key-specific safety validation rejects\nmarkup, links, controls, impersonation, blank text, and oversized text.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRecipientCopyOverrideRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored override.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientCopyOverride"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "operationId": "resetRecipientCopyOverride",
        "summary": "Reset one project recipient-copy override",
        "description": "Deletes the sparse value at one exact address. Repeating the reset is\nsafe; the shipped catalog is effective immediately whether or not an\noverride existed.\n",
        "tags": ["Projects"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "responses": {
          "204": {
            "description": "The shipped catalog value is effective at this address."
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/credentials": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listApiCredentials",
        "summary": "List safe API credential metadata",
        "description": "Returns only credentials in the selected project environment owned by\nthe organization selected by the verified Clerk organization session.\nSecrets and digest material are never returned. An absent or\nout-of-organization project or environment uses the same non-enumerating\n`404`.\n",
        "tags": ["API credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "parameters": [
          { "$ref": "#/components/parameters/ApiCredentialAfterCursor" },
          { "$ref": "#/components/parameters/ApiCredentialPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "A stable page of safe credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiCredentialCollection"
                },
                "examples": {
                  "credentials": {
                    "value": {
                      "items": [
                        {
                          "id": "pcred_AAAAAAAAAAAAAAAAAAAAAA",
                          "project_id": "project_synthetic_001",
                          "environment_id": "environment_live_synthetic_001",
                          "environment": "live",
                          "prefix": "wb_pc1.pcred_AAAAAAAA",
                          "label": "Synthetic production integration",
                          "scopes": [
                            "messages:write",
                            "messages:read",
                            "subscriptions:write",
                            "subscriptions:read"
                          ],
                          "created_by": "member_synthetic_001",
                          "created_at": "2026-07-25T17:45:00Z",
                          "last_used_at": "2026-07-25T17:50:00Z",
                          "status": "active"
                        }
                      ],
                      "page": 1,
                      "page_size": 50,
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "createApiCredential",
        "summary": "Create an environment-scoped API credential",
        "description": "Creates one credential in the selected project environment. The complete\nbearer secret appears only in this creation response. It cannot be read\nlater and is never replayed from an idempotency cache. If a client loses\nthis response, it lists safe metadata and creates then revokes a\nreplacement.\n",
        "tags": ["API credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiCredentialRequest"
              },
              "examples": {
                "createCredential": {
                  "value": {
                    "label": "Production integration",
                    "scopes": [
                      "messages:write",
                      "messages:read",
                      "subscriptions:write",
                      "subscriptions:read"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creation-only secret reveal and safe credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiCredentialSecretReveal"
                },
                "examples": {
                  "createdCredential": {
                    "value": {
                      "credential": {
                        "id": "pcred_AAAAAAAAAAAAAAAAAAAAAA",
                        "project_id": "project_synthetic_001",
                        "environment_id": "environment_live_synthetic_001",
                        "environment": "live",
                        "prefix": "wb_pc1.pcred_AAAAAAAA",
                        "label": "Synthetic production integration",
                        "scopes": [
                          "messages:write",
                          "messages:read",
                          "subscriptions:write",
                          "subscriptions:read"
                        ],
                        "created_by": "member_synthetic_001",
                        "created_at": "2026-07-25T17:45:00Z",
                        "status": "active"
                      },
                      "secret": "wb_pc1.pcred_AAAAAAAAAAAAAAAAAAAAAA.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/credentials/{credential_id}/rotate": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ApiCredentialId" }
      ],
      "post": {
        "operationId": "rotateApiCredential",
        "summary": "Rotate an environment-scoped API credential",
        "description": "Creates one replacement with the same label and scopes. The complete new\nbearer secret appears only in this response. The replaced credential\nremains active for the explicitly declared overlap, from zero through\n86400 seconds, then becomes terminally revoked. A revoked credential\ncannot be rotated. Missing and out-of-scope credentials use the same\nnon-enumerating `404`.\n",
        "tags": ["API credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateApiCredentialRequest"
              },
              "examples": {
                "rotateCredential": { "value": { "overlap_seconds": 3600 } }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creation-only replacement secret and safe metadata for both credentials.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiCredentialRotation"
                },
                "examples": {
                  "rotatedCredential": {
                    "value": {
                      "credential": {
                        "credential": {
                          "id": "pcred_BBBBBBBBBBBBBBBBBBBBBA",
                          "project_id": "project_synthetic_001",
                          "environment_id": "environment_live_synthetic_001",
                          "environment": "live",
                          "prefix": "wb_pc1.pcred_BBBBBBBB",
                          "label": "Synthetic production integration",
                          "scopes": [
                            "messages:write",
                            "messages:read",
                            "subscriptions:write",
                            "subscriptions:read"
                          ],
                          "created_by": "member_synthetic_001",
                          "created_at": "2026-07-25T17:45:00Z",
                          "status": "active"
                        },
                        "secret": "wb_pc1.pcred_BBBBBBBBBBBBBBBBBBBBBA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBA"
                      },
                      "replaced_credential": {
                        "id": "pcred_AAAAAAAAAAAAAAAAAAAAAA",
                        "project_id": "project_synthetic_001",
                        "environment_id": "environment_live_synthetic_001",
                        "environment": "live",
                        "prefix": "wb_pc1.pcred_AAAAAAAA",
                        "label": "Synthetic production integration",
                        "scopes": [
                          "messages:write",
                          "messages:read",
                          "subscriptions:write",
                          "subscriptions:read"
                        ],
                        "created_by": "member_synthetic_001",
                        "created_at": "2026-07-25T17:45:00Z",
                        "last_used_at": "2026-07-25T17:50:00Z",
                        "scheduled_revocation_at": "2026-07-25T18:45:00Z",
                        "status": "active"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/credentials/{credential_id}/revoke": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ApiCredentialId" }
      ],
      "post": {
        "operationId": "revokeApiCredential",
        "summary": "Revoke an environment-scoped API credential",
        "description": "Immediately and terminally revokes the selected credential. Repeating\nthe request for the same visible credential is safe and returns the\nsame revoked metadata without revealing secret or digest material.\nMissing and out-of-scope credentials use the same non-enumerating `404`.\n",
        "tags": ["API credentials"],
        "security": [{ "clerkSession": [] }],
        "x-organization-membership": "required",
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "200": {
            "description": "Safe terminal credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiCredential" },
                "examples": {
                  "revokedCredential": {
                    "value": {
                      "id": "pcred_AAAAAAAAAAAAAAAAAAAAAA",
                      "project_id": "project_synthetic_001",
                      "environment_id": "environment_live_synthetic_001",
                      "environment": "live",
                      "prefix": "wb_pc1.pcred_AAAAAAAA",
                      "label": "Synthetic production integration",
                      "scopes": [
                        "messages:write",
                        "messages:read",
                        "subscriptions:write",
                        "subscriptions:read"
                      ],
                      "created_by": "member_synthetic_001",
                      "created_at": "2026-07-25T17:45:00Z",
                      "last_used_at": "2026-07-25T17:50:00Z",
                      "status": "revoked",
                      "revoked_at": "2026-07-25T17:55:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/subscription-links": {
      "post": {
        "operationId": "createSubscriptionLink",
        "summary": "Create a subscription link",
        "description": "Creates one single-use authorization link inside the authenticated\nproject and environment. Links default to 12 hours (43200 seconds);\n`expires_in_seconds` accepts 60 through 604800 seconds (7 days).\nEquivalent replay returns the original `201`\nresponse and logical resource without extending idempotency retention.\nA pending Telegram resource returns the selected bot's native `t.me`\nlink directly; it does not route a new authorization through a hosted\nWhooshBang page.\n",
        "tags": ["Subscription links"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriptionLinkRequest"
              },
              "examples": {
                "defaultTelegram": {
                  "value": {
                    "subscriber_id": "customer_123",
                    "channels": ["telegram"],
                    "connection_id": "connection_synthetic_telegram_001",
                    "recipient_language": "es",
                    "return_url": "https://example.test/settings/notifications"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A new link, or the original link and original status on equivalent replay.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionLink" },
                "examples": {
                  "pending": {
                    "value": {
                      "id": "slink_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "channels": ["telegram"],
                      "recipient_language": "es",
                      "connection": {
                        "id": "connection_synthetic_telegram_001",
                        "mode": "whooshbang_shared",
                        "display_name": "WhooshBang",
                        "identity": {
                          "handle": "WhooshBangSyntheticBot",
                          "provider": "telegram"
                        }
                      },
                      "status": "pending",
                      "authorization_url": "https://t.me/WhooshBangSyntheticBot?start=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                      "created_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "diagnostic_id": "diag_link_pending_001"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/subscription-links/{subscription_link_id}": {
      "parameters": [{ "$ref": "#/components/parameters/SubscriptionLinkId" }],
      "get": {
        "operationId": "getSubscriptionLink",
        "summary": "Inspect a subscription link",
        "description": "Returns the current link state. An activated or revoked link exposes an\nopaque binding summary, never a Telegram chat or user identifier.\nCross-project and cross-environment identifiers return `404`.\n",
        "tags": ["Subscription links"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Current link state.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionLink" },
                "examples": {
                  "activated": {
                    "value": {
                      "id": "slink_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "channels": ["telegram"],
                      "recipient_language": "es",
                      "connection": {
                        "id": "connection_synthetic_telegram_001",
                        "mode": "whooshbang_shared",
                        "display_name": "WhooshBang",
                        "identity": {
                          "handle": "WhooshBangSyntheticBot",
                          "provider": "telegram"
                        }
                      },
                      "status": "activated",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "connection_id": "connection_synthetic_telegram_001",
                        "status": "active"
                      },
                      "created_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:47:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "diagnostic_id": "diag_link_active_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/subscription-links/{subscription_link_id}/cancel": {
      "parameters": [{ "$ref": "#/components/parameters/SubscriptionLinkId" }],
      "post": {
        "operationId": "cancelSubscriptionLink",
        "summary": "Cancel a pending subscription link",
        "description": "Cancels a pending link. Equivalent replay returns the original result.\nConsumption of a cancelled or expired link never creates a binding.\n",
        "tags": ["Subscription links"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "200": {
            "description": "Current link state and whether cancellation took effect.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/SubscriptionLink" },
                    { "type": "object", "required": ["cancellation_effective"] }
                  ]
                },
                "examples": {
                  "cancelled": {
                    "value": {
                      "id": "slink_synthetic_002",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_456",
                      "notifier_id": "default",
                      "channels": ["telegram"],
                      "recipient_language": "es",
                      "connection": {
                        "id": "connection_synthetic_telegram_001",
                        "mode": "whooshbang_shared",
                        "display_name": "WhooshBang",
                        "identity": {
                          "handle": "WhooshBangSyntheticBot",
                          "provider": "telegram"
                        }
                      },
                      "status": "cancelled",
                      "created_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:46:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "diagnostic_id": "diag_link_cancel_001",
                      "cancellation_effective": true
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-image-assets": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "post": {
        "operationId": "uploadNotificationImageAsset",
        "summary": "Normalize and retain one environment-owned notification image",
        "description": "Accepts one bounded raw PNG, validates and re-encodes it as canonical\nRGBA PNG bytes, and retains the immutable asset for a 30-day admission\nwindow. The service never fetches a customer URL. An equivalent replay\nreturns the original asset with `200`; a new asset returns `201`.\n",
        "tags": ["Messages"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "canonical_rgba_png_after_validation",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary",
                "maxLength": 524288
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The original immutable asset returned on equivalent idempotent replay.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationImageAsset"
                }
              }
            }
          },
          "201": {
            "description": "A newly retained immutable canonical PNG asset.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationImageAsset"
                },
                "examples": {
                  "uploaded": {
                    "value": {
                      "id": "asset_11111111111111111111111111111111",
                      "content_type": "image/png",
                      "byte_size": 70,
                      "width": 1,
                      "height": 1,
                      "sha256": "1111111111111111111111111111111111111111111111111111111111111111",
                      "created_at": "2026-07-25T17:45:00.000Z",
                      "expires_at": "2026-08-24T17:45:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notification-image-assets/{asset_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/NotificationImageAssetId" }
      ],
      "delete": {
        "operationId": "deleteNotificationImageAsset",
        "summary": "Delete one environment-owned notification image",
        "description": "Immediately prevents new notification references. Repeating deletion\nof an asset already deleted in this exact scope remains successful;\nunknown and foreign identifiers return the same non-enumerating `404`.\nAccepted notifications retain their existing delivery lease.\n",
        "tags": ["Messages"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "204": {
            "description": "The owned asset is deleted or was already deleted."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create an asynchronous message",
        "description": "Durably accepts one logical text message for one subscriber and one\nresolved channel binding. `202` proves API acceptance only; it does not\nclaim provider acceptance or end-device delivery.\nThe reserved `test:` subscriber prefix and `delivery_target: simulator`\nare test-environment-only. Live sends are refused before acceptance or\nidempotent replay with `400 request_invalid`; reserved subscriber IDs\ncarry a field error at `/to/subscriber_id`.\n\n`connection_id` sends through one of the subscriber's connected\nchannels. Without it, the service uses the subscriber's preferred\nchannel, else the default connection when the subscriber is connected\nthere, else the connection they connected through most recently, and\nrefuses with `422 subscriber_unbound` only when no connected channel can\ntake the message. A named connection the subscriber has not connected\nthrough is refused with `422 subscriber_not_connected` when they are\nconnected through another one, and as an unchosen send would be when\nnone can take the message. A named connection that is not in this\nenvironment, or cannot send, is refused with `400 request_invalid` at\n`/connection_id`.\n",
        "tags": ["Messages"],
        "security": [{ "bearerCredential": [] }, { "machineCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-machine-required-scopes": ["machine-messages:write"],
        "x-machine-binding-enforcement": [
          "authenticated_project",
          "authenticated_environment",
          "bound_notifier",
          "bound_subscriber"
        ],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateMessageRequest" },
              "examples": {
                "text": {
                  "value": {
                    "to": { "subscriber_id": "customer_123" },
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "Your export is ready."
                    },
                    "expires_at": "2026-07-25T18:00:00Z",
                    "correlation_id": "export_987",
                    "metadata": { "job": "export_987" }
                  }
                },
                "confirm": {
                  "value": {
                    "to": { "subscriber_id": "agent_relay_operator" },
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "A deployment is waiting for your decision."
                    },
                    "interaction": {
                      "type": "confirm",
                      "prompt": "Approve the synthetic deployment?",
                      "confirm_label": "Approve",
                      "deny_label": "Deny",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_confirm_001"
                    }
                  }
                },
                "select": {
                  "value": {
                    "to": { "subscriber_id": "agent_relay_operator" },
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "Choose a synthetic environment."
                    },
                    "interaction": {
                      "type": "select",
                      "prompt": "Choose an environment",
                      "options": [
                        { "value": "staging", "label": "Staging" },
                        { "value": "production", "label": "Production" }
                      ],
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_select_001"
                    }
                  }
                },
                "input": {
                  "value": {
                    "to": { "subscriber_id": "agent_relay_operator" },
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "A bounded response is required."
                    },
                    "interaction": {
                      "type": "input",
                      "prompt": "What should happen next?",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_input_001"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "A newly accepted message, or the original message and status on equivalent replay.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Message" },
                "examples": {
                  "accepted": {
                    "value": {
                      "id": "msg_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 0,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_accept_001",
                      "correlation_id": "export_987",
                      "metadata": { "job": "export_987" }
                    }
                  },
                  "interactionOpen": {
                    "value": {
                      "id": "msg_interactive_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "agent_relay_operator",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_relay",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "agent_relay_operator",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "delivery": {
                        "attempt_count": 0,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_interactive_message_001",
                      "interaction": {
                        "id": "interaction_synthetic_001",
                        "type": "select",
                        "state": "open",
                        "expires_at": "2026-07-25T18:00:00Z",
                        "correlation_id": "request_select_001"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/messages/{message_id}": {
      "parameters": [{ "$ref": "#/components/parameters/MessageId" }],
      "get": {
        "operationId": "getMessage",
        "summary": "Inspect a message",
        "description": "Returns the canonical logical state and highest proven provider state.\n`outcome_unknown` is distinct from retryable and terminal failure and\nnever has an automatic retry scheduled.\n\nWhen the message has an open interaction, the optional bounded `wait`\nholds this read for its canonical terminal state. A wait timeout is a\nsuccessful current-state read, not an error. Terminal interactions and\nmessages without an interaction return immediately. Inspection never\nacknowledges, consumes, retries, replays, or changes delivery.\n",
        "parameters": [
          { "$ref": "#/components/parameters/ResponseInspectionWait" }
        ],
        "tags": ["Messages"],
        "security": [{ "bearerCredential": [] }, { "machineCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "x-machine-required-scopes": ["machine-messages:read"],
        "x-machine-binding-enforcement": [
          "authenticated_project",
          "authenticated_environment",
          "owning_machine_client"
        ],
        "responses": {
          "200": {
            "description": "Current message and safe delivery-attempt summary.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Message" },
                "examples": {
                  "providerAccepted": {
                    "value": {
                      "id": "msg_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "provider_accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:02Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 1,
                        "highest_proven_provider_state": "provider_accepted",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_provider_001",
                      "correlation_id": "export_987",
                      "metadata": { "job": "export_987" }
                    }
                  },
                  "outcomeUnknown": {
                    "value": {
                      "id": "msg_synthetic_002",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_456",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_002",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_456",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "outcome_unknown",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:03Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 1,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false,
                        "classified_error": {
                          "code": "provider_outcome_unknown",
                          "retryable": false,
                          "detail": "The provider may have accepted the request, but no trustworthy result is available.",
                          "diagnostic_id": "diag_provider_unknown_001"
                        }
                      },
                      "diagnostic_id": "diag_message_unknown_001",
                      "outcome_guidance": "Delivery may have been accepted by the provider. No automatic retry is scheduled; create a new message explicitly if another attempt is appropriate."
                    }
                  },
                  "interactionOpen": {
                    "value": {
                      "id": "msg_interactive_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "agent_relay_operator",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_relay",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "agent_relay_operator",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "delivery": {
                        "attempt_count": 0,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_interactive_message_001",
                      "interaction": {
                        "id": "interaction_synthetic_001",
                        "type": "select",
                        "state": "open",
                        "expires_at": "2026-07-25T18:00:00Z",
                        "correlation_id": "request_select_001"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/interactions/{interaction_id}": {
      "parameters": [{ "$ref": "#/components/parameters/InteractionId" }],
      "get": {
        "operationId": "getInteraction",
        "summary": "Inspect an interaction response",
        "description": "Returns the same canonical first-terminal-writer interaction summary\nused by message status, signed customer events, and machine events.\nAn answered interaction always retains `answered` and `answered_at`;\n`answer_retained` says whether the typed answer is still present.\n\nThe optional bounded `wait` holds an open interaction read for a\nterminal state. Expiry without resolution returns the current `open`\nsummary successfully and can be immediately re-polled. Inspection is\nread-only and has no effect on any delivery or retention lifecycle.\n",
        "parameters": [
          { "$ref": "#/components/parameters/ResponseInspectionWait" }
        ],
        "tags": ["Messages"],
        "security": [{ "bearerCredential": [] }, { "machineCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "x-machine-required-scopes": ["machine-messages:read"],
        "x-machine-binding-enforcement": [
          "authenticated_project",
          "authenticated_environment",
          "owning_machine_client"
        ],
        "responses": {
          "200": {
            "description": "Current canonical interaction state and retained answer.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/InteractionSummary" },
                "examples": {
                  "open": {
                    "value": {
                      "id": "interaction_synthetic_001",
                      "type": "select",
                      "state": "open",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_select_001"
                    }
                  },
                  "answeredConfirm": {
                    "value": {
                      "id": "interaction_synthetic_confirm",
                      "type": "confirm",
                      "state": "answered",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_confirm_001",
                      "answered_at": "2026-07-25T17:47:00Z",
                      "answer_retained": true,
                      "answer": true
                    }
                  },
                  "answeredSelect": {
                    "value": {
                      "id": "interaction_synthetic_select",
                      "type": "select",
                      "state": "answered",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_select_001",
                      "answered_at": "2026-07-25T17:47:00Z",
                      "answer_retained": true,
                      "answer": "approve_opaque"
                    }
                  },
                  "answeredInput": {
                    "value": {
                      "id": "interaction_synthetic_input",
                      "type": "input",
                      "state": "answered",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_input_001",
                      "answered_at": "2026-07-25T17:47:00Z",
                      "answer_retained": true,
                      "answer": "Operator supplied context"
                    }
                  },
                  "answeredRedacted": {
                    "value": {
                      "id": "interaction_synthetic_confirm",
                      "type": "confirm",
                      "state": "answered",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "answered_at": "2026-07-25T17:47:00Z",
                      "answer_retained": false
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/messages/{message_id}/cancel": {
      "parameters": [{ "$ref": "#/components/parameters/MessageId" }],
      "post": {
        "operationId": "cancelMessage",
        "summary": "Cancel a message before provider-call ownership",
        "description": "Cancellation is effective only before a worker owns the provider call.\nA race at `sending`, `provider_accepted`, or `outcome_unknown` returns\nthe current state with `cancellation_effective: false` and never claims\nprovider-side deletion.\n",
        "tags": ["Messages"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "200": {
            "description": "Current message state and whether cancellation took effect.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/Message" },
                    { "type": "object", "required": ["cancellation_effective"] }
                  ]
                },
                "examples": {
                  "cancelled": {
                    "value": {
                      "id": "msg_synthetic_003",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_789",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_003",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_789",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "cancelled",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:01Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 0,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_cancel_001",
                      "cancellation_effective": true
                    }
                  },
                  "tooLate": {
                    "value": {
                      "id": "msg_synthetic_004",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_999",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_004",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_999",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "sending",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:02Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 1,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_race_001",
                      "cancellation_effective": false
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-clients": {
      "post": {
        "operationId": "createMachineClient",
        "summary": "Create a destination-bound machine client",
        "description": "Creates one machine client in the project/environment selected by the\nproject credential. The notifier, subscriber, and active binding become\nimmutable authorization bounds. The response never contains a readable\nsecret or digest.\nLive environments reject the reserved `test:` subscriber prefix with\n`400 request_invalid` and a field error at `/subscriber_id` before creation.\n",
        "tags": ["Machine clients"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMachineClientRequest"
              },
              "examples": {
                "localClient": {
                  "value": {
                    "machine_id": "machine_synthetic_a",
                    "notifier_id": "default",
                    "subscriber_id": "agent_relay_operator",
                    "display_name": "Synthetic local machine"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A new provisioning client or the original client on equivalent replay.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineClient" },
                "examples": {
                  "provisioning": {
                    "value": {
                      "id": "machine_client_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "machine_id": "machine_synthetic_a",
                      "notifier_id": "default",
                      "subscriber_id": "agent_relay_operator",
                      "binding_id": "binding_synthetic_relay",
                      "display_name": "Synthetic local machine",
                      "status": "provisioning",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:40:00Z",
                      "updated_at": "2026-07-25T17:40:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-clients/{machine_client_id}": {
      "parameters": [{ "$ref": "#/components/parameters/MachineClientId" }],
      "get": {
        "operationId": "getMachineClient",
        "summary": "Inspect machine-client metadata",
        "description": "Returns only safe metadata inside the authenticated project/environment.\nA client outside that scope is indistinguishable from an absent client.\n",
        "tags": ["Machine clients"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["machine-clients:read"],
        "responses": {
          "200": {
            "description": "Current machine-client metadata and fixed scope summary.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineClient" },
                "examples": {
                  "active": {
                    "value": {
                      "id": "machine_client_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "machine_id": "machine_synthetic_a",
                      "notifier_id": "default",
                      "subscriber_id": "agent_relay_operator",
                      "binding_id": "binding_synthetic_relay",
                      "display_name": "Synthetic local machine",
                      "status": "active",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:40:00Z",
                      "updated_at": "2026-07-25T17:42:00Z",
                      "last_used_at": "2026-07-25T17:43:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-clients/{machine_client_id}/credentials": {
      "parameters": [{ "$ref": "#/components/parameters/MachineClientId" }],
      "post": {
        "operationId": "registerMachineCredential",
        "summary": "Register a locally generated machine-credential digest",
        "description": "Registers only the credential ID and SHA-256 digest. The same ID and\ndigest returns existing safe metadata; the same ID with another digest\nconflicts. The first active credential activates a provisioning client.\n",
        "tags": ["Machine clients"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterMachineCredentialRequest"
              },
              "examples": {
                "digestOnly": {
                  "value": {
                    "credential_id": "mcred_AAECAwQFBgcICQoLDA0ODw",
                    "secret_sha256": "sha256:89c7460452eddff119fea0419e785c74de2ffb139dbe74323aca4a01e198a5dc"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing safe credential metadata on an equivalent registration replay; never secret or digest.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineCredential" },
                "examples": {
                  "existing": {
                    "value": {
                      "credential_id": "mcred_AAECAwQFBgcICQoLDA0ODw",
                      "machine_client_id": "machine_client_synthetic_001",
                      "status": "active",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:42:00Z",
                      "last_used_at": "2026-07-25T17:43:00Z"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Newly registered safe credential metadata; never secret or digest.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineCredential" },
                "examples": {
                  "active": {
                    "value": {
                      "credential_id": "mcred_AAECAwQFBgcICQoLDA0ODw",
                      "machine_client_id": "machine_client_synthetic_001",
                      "status": "active",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:42:00Z",
                      "last_used_at": "2026-07-25T17:43:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-clients/{machine_client_id}/credentials/{credential_id}/revoke": {
      "parameters": [
        { "$ref": "#/components/parameters/MachineClientId" },
        { "$ref": "#/components/parameters/MachineCredentialId" }
      ],
      "post": {
        "operationId": "revokeMachineCredential",
        "summary": "Revoke a machine credential",
        "description": "Idempotently ends new authorization by this credential. Rotation\nregisters and smoke-tests a replacement before this operation.\n",
        "tags": ["Machine clients"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "200": {
            "description": "Safe revoked credential metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineCredential" },
                "examples": {
                  "revoked": {
                    "value": {
                      "credential_id": "mcred_AAECAwQFBgcICQoLDA0ODw",
                      "machine_client_id": "machine_client_synthetic_001",
                      "status": "revoked",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:42:00Z",
                      "last_used_at": "2026-07-25T18:00:00Z",
                      "revoked_at": "2026-07-25T18:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-clients/{machine_client_id}/revoke": {
      "parameters": [{ "$ref": "#/components/parameters/MachineClientId" }],
      "post": {
        "operationId": "revokeMachineClient",
        "summary": "Revoke a machine client",
        "description": "Idempotently revokes the client and all new credential authorization.\nExisting messages and immutable events are retained under contract.\n",
        "tags": ["Machine clients"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": {
          "200": {
            "description": "Safe revoked client metadata.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineClient" },
                "examples": {
                  "revoked": {
                    "value": {
                      "id": "machine_client_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "machine_id": "machine_synthetic_a",
                      "notifier_id": "default",
                      "subscriber_id": "agent_relay_operator",
                      "binding_id": "binding_synthetic_relay",
                      "display_name": "Synthetic local machine",
                      "status": "revoked",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:40:00Z",
                      "updated_at": "2026-07-25T18:30:00Z",
                      "last_used_at": "2026-07-25T18:00:00Z",
                      "revoked_at": "2026-07-25T18:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-events": {
      "get": {
        "operationId": "pollMachineEvents",
        "summary": "Long-poll the authenticated machine stream",
        "description": "Polls only the stream selected by the machine credential. `after` is\nomitted only on the first poll and otherwise must equal the exact\natomically committed cursor returned for this stream. Any other cursor,\nincluding a known issued but uncommitted cursor, fails closed and never\nrewinds. Unacknowledged events may repeat with the same event ID and\ncursor.\n",
        "tags": ["Machine events"],
        "security": [{ "machineCredential": [] }],
        "x-required-scopes": ["machine-events:read"],
        "x-event-retention": {
          "minimum_seconds_after_creation": 604800,
          "extends_interaction_answer_authority": false
        },
        "parameters": [
          { "$ref": "#/components/parameters/MachineAfterCursor" },
          { "$ref": "#/components/parameters/MachinePollWait" },
          { "$ref": "#/components/parameters/MachinePollLimit" }
        ],
        "responses": {
          "200": {
            "description": "Stable ordered events and the atomically committed cursor.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineEventPollResponse"
                },
                "examples": {
                  "events": {
                    "value": {
                      "schema": "whooshbang.machine-events.v1",
                      "events": [
                        {
                          "schema": "whooshbang.interaction-event.v1",
                          "id": "event_interaction_confirm_001",
                          "cursor": "mcur_synthetic_001",
                          "type": "interaction.received",
                          "message_id": "msg_interactive_confirm_001",
                          "interaction_id": "interaction_synthetic_confirm",
                          "correlation_id": "request_confirm_001",
                          "answer_retained": true,
                          "response": { "type": "confirm", "value": true },
                          "channel_context": {
                            "binding_id": "binding_synthetic_relay",
                            "channel": "telegram",
                            "conversation_kind": "private_chat",
                            "display_name": "Synthetic operator"
                          },
                          "occurred_at": "2026-07-25T17:47:00Z",
                          "expires_at": "2026-07-25T18:00:00Z"
                        },
                        {
                          "schema": "whooshbang.interaction-event.v1",
                          "id": "event_interaction_select_001",
                          "cursor": "mcur_synthetic_002",
                          "type": "interaction.received",
                          "message_id": "msg_interactive_select_001",
                          "interaction_id": "interaction_synthetic_select",
                          "correlation_id": "request_select_001",
                          "answer_retained": true,
                          "response": { "type": "select", "value": "staging" },
                          "channel_context": {
                            "binding_id": "binding_synthetic_relay",
                            "channel": "telegram",
                            "conversation_kind": "private_chat",
                            "display_name": "Synthetic operator"
                          },
                          "occurred_at": "2026-07-25T17:48:00Z",
                          "expires_at": "2026-07-25T18:00:00Z"
                        }
                      ],
                      "committed_cursor": null,
                      "server_time": "2026-07-25T17:50:00Z"
                    }
                  },
                  "empty": {
                    "value": {
                      "schema": "whooshbang.machine-events.v1",
                      "events": [],
                      "committed_cursor": "mcur_synthetic_002",
                      "server_time": "2026-07-25T17:51:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/machine-events/{event_id}/ack": {
      "parameters": [{ "$ref": "#/components/parameters/MachineEventId" }],
      "post": {
        "operationId": "ackMachineEvent",
        "summary": "Record a per-event machine acknowledgement",
        "description": "Records processed or permitted quarantine disposition idempotently.\nThe committed cursor advances only across a contiguous acknowledged\nprefix. Authentication, stream identity, signature, and schema failures\ncannot be quarantined to skip work.\n",
        "tags": ["Machine events"],
        "security": [{ "machineCredential": [] }],
        "x-required-scopes": ["machine-events:ack"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MachineEventAckRequest"
              },
              "examples": {
                "processed": {
                  "value": {
                    "cursor": "mcur_synthetic_001",
                    "disposition": "processed",
                    "reason_code": null
                  }
                },
                "quarantined": {
                  "value": {
                    "cursor": "mcur_synthetic_002",
                    "disposition": "quarantined",
                    "reason_code": "consumer.unsupported_version"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New or existing acknowledgement and current committed position.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineEventAckResponse"
                },
                "examples": {
                  "processed": {
                    "value": {
                      "event_id": "event_interaction_confirm_001",
                      "cursor": "mcur_synthetic_001",
                      "disposition": "processed",
                      "acknowledgement_status": "recorded",
                      "committed_cursor": "mcur_synthetic_001",
                      "advanced": true
                    }
                  },
                  "outOfOrder": {
                    "value": {
                      "event_id": "event_interaction_select_001",
                      "cursor": "mcur_synthetic_002",
                      "disposition": "processed",
                      "acknowledgement_status": "recorded",
                      "committed_cursor": null,
                      "advanced": false
                    }
                  },
                  "quarantined": {
                    "value": {
                      "event_id": "event_interaction_select_001",
                      "cursor": "mcur_synthetic_002",
                      "disposition": "quarantined",
                      "reason_code": "consumer.unsupported_version",
                      "acknowledgement_status": "recorded",
                      "committed_cursor": "mcur_synthetic_002",
                      "advanced": true
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listCustomerEndpoints",
        "summary": "List safe customer-endpoint health metadata",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Safe endpoint lifecycle and health metadata without URLs or protected content.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointCollection"
                },
                "examples": {
                  "endpoints": {
                    "value": {
                      "items": [
                        {
                          "id": "endpoint_11111111111111111111111111111111",
                          "project_id": "project_synthetic_alpha",
                          "environment_id": "environment_test_synthetic_alpha",
                          "environment": "test",
                          "status": "active",
                          "verification_status": "verified",
                          "event_types": [
                            "interaction.received",
                            "message.delivered"
                          ],
                          "secret_version": 2,
                          "health": "failing",
                          "created_at": "2026-08-06T12:00:00.000Z",
                          "updated_at": "2026-08-06T14:00:00.000Z",
                          "verification_attempted_at": "2026-08-06T12:05:00.000Z",
                          "verified_at": "2026-08-06T12:05:00.000Z",
                          "rotated_at": "2026-08-06T13:00:00.000Z",
                          "last_success_at": "2026-08-06T13:30:00.000Z",
                          "last_failure": {
                            "at": "2026-08-06T14:00:00.000Z",
                            "category": "network_failure"
                          },
                          "diagnostic_id": "diag_endpoint_list_001"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createCustomerEndpoint",
        "summary": "Create an active customer endpoint and reveal its signing secret once",
        "description": "Validates the final normalized public HTTPS destination before storing it.\nThe initial response includes the new signing secret. An equivalent\nidempotent replay returns the same logical endpoint without the secret;\ndifferent input for the same key returns `idempotency_conflict`.\n",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "final_normalized_url_and_validated_request",
          "replay_retention_extends": false
        },
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerEndpointRequest"
              },
              "examples": {
                "createEndpoint": {
                  "value": {
                    "url": "https://events.example.com/whooshbang",
                    "event_types": [
                      "interaction.received",
                      "message.delivered"
                    ],
                    "local_test": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Equivalent replay returning safe endpoint metadata without the secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "replayed": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "unverified",
                        "verification_status": "pending",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 1,
                        "health": "never_delivered",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T12:00:00.000Z",
                        "diagnostic_id": "diag_endpoint_replay_001"
                      }
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Newly active endpoint, recorded signed ping result, and its one-time signing secret.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "created": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "unverified",
                        "verification_status": "pending",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 1,
                        "health": "never_delivered",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T12:00:00.000Z",
                        "diagnostic_id": "diag_endpoint_create_001"
                      },
                      "secret": "whsec_AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/CustomerEndpointId" }
      ],
      "get": {
        "operationId": "getCustomerEndpoint",
        "summary": "Read safe lifecycle and health metadata for one endpoint",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Safe endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/verify": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/CustomerEndpointId" }
      ],
      "post": {
        "operationId": "verifyCustomerEndpoint",
        "summary": "Send a signed test ping and record whether the receiver returns 2xx",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "responses": {
          "200": {
            "description": "Verified active endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "502": { "$ref": "#/components/responses/ProviderTerminal" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/rotate": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/CustomerEndpointId" }
      ],
      "post": {
        "operationId": "rotateCustomerEndpoint",
        "summary": "Create a new signing version with bounded old/new overlap",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "endpoint_and_validated_request",
          "replay_retention_extends": false
        },
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateCustomerEndpointRequest"
              },
              "examples": { "rotate": { "value": { "overlap_seconds": 3600 } } }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Equivalent replay without another secret reveal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                }
              }
            }
          },
          "201": {
            "description": "Rotated endpoint and one-time new secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "rotated": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "active",
                        "verification_status": "verified",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 2,
                        "health": "healthy",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T13:00:00.000Z",
                        "verification_attempted_at": "2026-08-06T12:05:00.000Z",
                        "verified_at": "2026-08-06T12:05:00.000Z",
                        "rotated_at": "2026-08-06T13:00:00.000Z",
                        "last_success_at": "2026-08-06T12:30:00.000Z",
                        "diagnostic_id": "diag_endpoint_rotate_001"
                      },
                      "secret": "whsec_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/EndpointRotationConflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/{action}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/CustomerEndpointId" },
        {
          "name": "action",
          "in": "path",
          "required": true,
          "schema": { "type": "string", "enum": ["pause", "resume", "disable"] }
        }
      ],
      "post": {
        "operationId": "transitionCustomerEndpoint",
        "summary": "Pause, resume, or terminally disable an endpoint",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "200": {
            "description": "Updated safe endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/attempts": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/CustomerEndpointId" }
      ],
      "get": {
        "operationId": "listCustomerEndpointAttempts",
        "summary": "Inspect protected content-free delivery diagnostics",
        "tags": ["Customer endpoints"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Safe status, timing, and failure categories only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointAttemptCollection"
                },
                "examples": {
                  "attempts": {
                    "value": {
                      "endpoint_id": "endpoint_11111111111111111111111111111111",
                      "attempts": [
                        {
                          "id": "ceattempt_11111111111111111111111111111111",
                          "event_id": "evt_interaction_received_synthetic",
                          "attempt": 1,
                          "status": "terminal_failed",
                          "diagnostic_code": "network_failure",
                          "started_at": "2026-08-06T14:00:00.000Z",
                          "completed_at": "2026-08-06T14:00:01.000Z",
                          "created_at": "2026-08-06T14:00:00.000Z"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/connection-providers": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listConnectionProviders",
        "summary": "List providers, setup modes, and selectable WhooshBang identities",
        "description": "What a project can connect to and how. `shared_identities` lists the\nWhooshBang-owned identities an environment may select; WhooshBang\noperates their credentials, and no reference to one appears anywhere in\nthis API.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "responses": {
          "200": {
            "description": "Supported providers with their setup modes and lifecycle operations.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionProviderCollection"
                },
                "examples": {
                  "providers": {
                    "value": {
                      "items": [
                        {
                          "provider": "telegram",
                          "display_name": "Telegram",
                          "setup_modes": [
                            "whooshbang_shared",
                            "customer_managed",
                            "customer_byok"
                          ],
                          "lifecycle_operations": [
                            "validate",
                            "provision",
                            "repair",
                            "health",
                            "rotate",
                            "disable",
                            "deprovision",
                            "purge"
                          ],
                          "shared_installation_supported": true,
                          "shared_identities": [
                            {
                              "id": "prvinst_11111111111111111111111111111111",
                              "display_name": "WhooshBang",
                              "health": "healthy"
                            }
                          ]
                        }
                      ],
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listChannelConnections",
        "summary": "List this environment's channel connections",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Connections owned by exactly this organization, project, and environment.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelConnectionCollection"
                },
                "examples": {
                  "connections": {
                    "value": {
                      "items": [
                        {
                          "id": "chcon_11111111111111111111111111111111",
                          "project_id": "project_synthetic_alpha",
                          "environment_id": "environment_test_synthetic_alpha",
                          "environment": "test",
                          "provider": "telegram",
                          "mode": "whooshbang_shared",
                          "display_name": "Test sender",
                          "status": "active",
                          "health": "healthy",
                          "identity": {
                            "provider": "telegram",
                            "handle": "WhooshBang"
                          },
                          "row_version": 2,
                          "created_at": "2026-08-12T12:00:00.000Z",
                          "updated_at": "2026-08-12T12:05:00.000Z",
                          "health_checked_at": "2026-08-12T12:05:00.000Z",
                          "last_transition_at": "2026-08-12T12:05:00.000Z",
                          "last_transition_reason": "provisioned",
                          "diagnostic_id": "diag_connection_list_001"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createChannelConnection",
        "summary": "Select a provider identity for this environment",
        "description": "Creates a connection in `pending`. An equivalent idempotent replay\nreturns the same connection; different input for the same key returns\n`idempotency_conflict`.\n\n`whooshbang_shared` names a disclosed WhooshBang-owned identity.\n`customer_byok` supplies the customer's own provider credential and\ncarries no identity field: `provider_identity_digest` is unique across\nevery tenant, so an endpoint that digested a client-supplied identity\nwould answer \"already claimed\" for a bot the caller does not own — an\noracle for whether any given bot is connected to WhooshBang by anyone.\nThe identity is derived server-side from a provider-validated `getMe`\non the submitted credential instead.\n\n`customer_managed` supplies no credential at all. Telegram creates a\nbrand new bot on the administrator's own Telegram account and hands WhooshBang\nits token server to server, so the token never reaches a browser, a\nclipboard, this request, or any response. The connection is returned\n`pending` with a `setup` carrying the link the administrator opens and\nthe moment it stops working; poll the connection, or read\n`setup.status`, to follow the attempt. Creating a bot is a person-only\naction, so a connection whose administrator never returns simply\nexpires — and a bot Telegram already created outlives it, because no\nprovider API can delete a bot.\n\nEverything that can go wrong in a managed setup after this call\nreturns is reported on `setup` rather than as a refusal here, because\nby then the connection exists and the failing party is a person this\nrequest has already answered. A lapsed link is `expired`; an attempt\nTelegram or WhooshBang could not complete is `failed` with a\n`failure_reason`. Both are recoverable through\n`restartChannelConnectionSetup` on the same connection.\n\nThe Problem vocabulary is closed, so each refusal reuses a published\ncode and is distinguished by `field_errors[].code`:\n\n- the provider answered and rejected the credential —\n  `request_invalid` 400, `provider_credential_invalid` at `/credential`;\n- the identity already has a webhook and `confirm_webhook_takeover` was\n  not sent — `request_invalid` 400, `webhook_takeover_required` at\n  `/confirm_webhook_takeover`. This is a warning, not a prohibition:\n  repeating the request with the confirmation connects the identity\n  whoever owns the endpoint it currently delivers to;\n- the webhook it already has belongs to another WhooshBang connection —\n  `request_invalid` 400, `whooshbang_connection_takeover_required` at\n  `/confirm_webhook_takeover`. Separate from the code above because the\n  consequence is separate: confirming this one **disables** the other\n  connection, which would otherwise go on reporting itself healthy while\n  receiving nothing;\n- the identity is already connected, by this organization or any other —\n  `idempotency_conflict` 409, `provider_identity_claimed` at `/`, which\n  reports only that the identity the submitted credential proves is in\n  use and never that some other identity is;\n- the provider could not be reached and the outcome is genuinely\n  unknown — `provider_outcome_unknown` 502, no automatic retry;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChannelConnectionRequest"
              },
              "examples": {
                "selectSharedIdentity": {
                  "value": {
                    "mode": "whooshbang_shared",
                    "display_name": "Live sender",
                    "shared_identity_id": "prvinst_11111111111111111111111111111111"
                  }
                },
                "bringYourOwnCredential": {
                  "value": {
                    "mode": "customer_byok",
                    "display_name": "Acme Support Bot",
                    "credential": "0000000000:synthetic-example.not-a-real-bot-token",
                    "confirm_webhook_takeover": true
                  }
                },
                "createBotThroughManagedSetup": {
                  "value": {
                    "mode": "customer_managed",
                    "display_name": "Acme Alerts Bot",
                    "suggested_bot_username": "acme_alerts_bot",
                    "suggested_bot_name": "Acme Alerts"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Equivalent replay returning the connection that already exists.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "replayed": {
                    "value": {
                      "id": "chcon_22222222222222222222222222222222",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "whooshbang_shared",
                      "display_name": "Live sender",
                      "status": "pending",
                      "health": "unknown",
                      "identity": {
                        "provider": "telegram",
                        "handle": "WhooshBang"
                      },
                      "row_version": 1,
                      "created_at": "2026-08-12T12:00:00.000Z",
                      "updated_at": "2026-08-12T12:00:00.000Z",
                      "last_transition_at": "2026-08-12T12:05:00.000Z",
                      "last_transition_reason": "created",
                      "diagnostic_id": "diag_connection_create_001"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "The newly selected connection.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "created": {
                    "value": {
                      "id": "chcon_22222222222222222222222222222222",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "whooshbang_shared",
                      "display_name": "Live sender",
                      "status": "pending",
                      "health": "unknown",
                      "identity": {
                        "provider": "telegram",
                        "handle": "WhooshBang"
                      },
                      "row_version": 1,
                      "created_at": "2026-08-12T12:00:00.000Z",
                      "updated_at": "2026-08-12T12:00:00.000Z",
                      "last_transition_at": "2026-08-12T12:05:00.000Z",
                      "last_transition_reason": "created",
                      "diagnostic_id": "diag_connection_create_001"
                    }
                  },
                  "createdFromCustomerCredential": {
                    "value": {
                      "id": "chcon_33333333333333333333333333333333",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_byok",
                      "display_name": "Acme Support Bot",
                      "status": "pending",
                      "health": "unknown",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_support_synthetic_bot"
                      },
                      "row_version": 1,
                      "created_at": "2026-08-12T14:00:00.000Z",
                      "updated_at": "2026-08-12T14:00:00.000Z",
                      "last_transition_at": "2026-08-12T14:00:00.000Z",
                      "last_transition_reason": "credential_validated",
                      "diagnostic_id": "diag_connection_byok_create_001"
                    }
                  },
                  "awaitingManagedSetup": {
                    "value": {
                      "id": "chcon_44444444444444444444444444444444",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_managed",
                      "display_name": "Acme Alerts Bot",
                      "status": "pending",
                      "health": "unknown",
                      "setup": {
                        "status": "awaiting_handoff",
                        "handoff_url": "https://t.me/whooshbang_setup_bot?start=synthetic-setup-handoff-0001",
                        "expires_at": "2026-08-12T15:15:00.000Z",
                        "suggested_bot_username": "acme_alerts_bot"
                      },
                      "row_version": 1,
                      "created_at": "2026-08-12T15:00:00.000Z",
                      "updated_at": "2026-08-12T15:00:00.000Z",
                      "last_transition_at": "2026-08-12T15:00:00.000Z",
                      "last_transition_reason": "managed_setup_started",
                      "diagnostic_id": "diag_connection_managed_create_001"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "get": {
        "operationId": "getChannelConnection",
        "summary": "Read one channel connection",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "responses": {
          "200": {
            "description": "The connection, without credential material or any reference to it.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "awaitingManagedSetup": {
                    "value": {
                      "id": "chcon_44444444444444444444444444444444",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_managed",
                      "display_name": "Acme Alerts Bot",
                      "status": "pending",
                      "health": "unknown",
                      "setup": {
                        "status": "awaiting_handoff",
                        "handoff_url": "https://t.me/whooshbang_setup_bot?start=synthetic-setup-handoff-0001",
                        "expires_at": "2026-08-12T15:15:00.000Z",
                        "suggested_bot_username": "acme_alerts_bot"
                      },
                      "row_version": 1,
                      "created_at": "2026-08-12T15:00:00.000Z",
                      "updated_at": "2026-08-12T15:00:00.000Z",
                      "last_transition_at": "2026-08-12T15:00:00.000Z",
                      "last_transition_reason": "managed_setup_started",
                      "diagnostic_id": "diag_connection_managed_create_001"
                    }
                  },
                  "managedSetupFailed": {
                    "value": {
                      "id": "chcon_44444444444444444444444444444444",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_managed",
                      "display_name": "Acme Alerts Bot",
                      "status": "pending",
                      "health": "unknown",
                      "setup": {
                        "status": "failed",
                        "handoff_url": "https://t.me/whooshbang_setup_bot?start=synthetic-setup-handoff-0001",
                        "expires_at": "2026-08-12T15:15:00.000Z",
                        "suggested_bot_username": "acme_alerts_bot",
                        "failure_reason": "A setup is already in progress on that Telegram account. Finish or abandon it, then start this one again."
                      },
                      "row_version": 2,
                      "created_at": "2026-08-12T15:00:00.000Z",
                      "updated_at": "2026-08-12T15:04:00.000Z",
                      "last_transition_at": "2026-08-12T15:04:00.000Z",
                      "last_transition_reason": "managed_setup_failed",
                      "diagnostic_id": "diag_connection_managed_failed_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "updateChannelConnection",
        "summary": "Rename or enable and disable a connection",
        "description": "Applies the edit only if `row_version` is still current, so a rename and\na disable made at the same time cannot silently undo each other.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChannelConnectionRequest"
              },
              "examples": {
                "rename": {
                  "value": {
                    "row_version": 2,
                    "display_name": "Renamed sender"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated connection with its advanced row version.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/email-remediation": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "acknowledgeEmailRemediation",
        "summary": "Acknowledge remediation of a shared email sending hold",
        "description": "Requires current organization administrator membership through a session\nor an OAuth grant with connections:write. Service credentials cannot\nacknowledge on behalf of an owner. Releases only this organization's\nexisting shared domain hold; revoked recipients and sender state are unchanged.\n",
        "tags": ["Channel connections"],
        "security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
        "x-required-scopes": ["connections:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcknowledgeEmailRemediationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The connection after acknowledgement.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/archive": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "archiveChannelConnection",
        "summary": "Retire a connection permanently",
        "description": "Archiving is terminal and removes the connection's notifier routing.\nReconnecting later is a new connection, so consent a subscriber gave to\nthe archived identity is never revived under it. A shared identity other\nenvironments still use is untouched.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "responses": {
          "200": {
            "description": "The archived connection.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "archived": {
                    "value": {
                      "id": "chcon_11111111111111111111111111111111",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_test_synthetic_alpha",
                      "environment": "test",
                      "provider": "telegram",
                      "mode": "whooshbang_shared",
                      "display_name": "Test sender",
                      "status": "archived",
                      "health": "healthy",
                      "identity": {
                        "provider": "telegram",
                        "handle": "WhooshBang"
                      },
                      "row_version": 3,
                      "created_at": "2026-08-12T12:00:00.000Z",
                      "updated_at": "2026-08-12T13:00:00.000Z",
                      "health_checked_at": "2026-08-12T12:05:00.000Z",
                      "last_transition_at": "2026-08-12T13:00:00.000Z",
                      "last_transition_reason": "owner_archived",
                      "diagnostic_id": "diag_connection_archive_001",
                      "archived_at": "2026-08-12T13:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/repair": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "repairChannelConnection",
        "summary": "Reprovision a connection that stopped receiving",
        "description": "Re-establishes the provider-side delivery path for a connection whose\nidentity is unchanged — most often a webhook that something else\noverwrote. The identity a subscriber consented to is never replaced, so\nrepair recovers a `degraded` connection without asking anyone to\nconsent again.\n\nRepair takes no body: the credential already in custody is what it\nreprovisions with. Supply a replacement credential through\n`rotateChannelConnectionCredential` instead.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the connection is archived, so there is nothing to reprovision —\n  `idempotency_conflict` 409, `invalid_connection_transition` at `/`;\n- the credential in custody no longer works — `request_invalid` 400,\n  `provider_credential_invalid` at `/credential`, which is a rotation,\n  not a repair;\n- the identity acquired a webhook belonging to somebody else and no\n  takeover was confirmed on this connection — `request_invalid` 400,\n  `webhook_takeover_required` at `/confirm_webhook_takeover`;\n- the provider could not be reached — `provider_outcome_unknown` 502;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "responses": {
          "200": {
            "description": "The reprovisioned connection with its advanced row version.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "repaired": {
                    "value": {
                      "id": "chcon_33333333333333333333333333333333",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_byok",
                      "display_name": "Acme Support Bot",
                      "status": "active",
                      "health": "healthy",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_support_synthetic_bot"
                      },
                      "row_version": 3,
                      "created_at": "2026-08-12T14:00:00.000Z",
                      "updated_at": "2026-08-12T14:20:00.000Z",
                      "health_checked_at": "2026-08-12T14:20:00.000Z",
                      "last_transition_at": "2026-08-12T14:20:00.000Z",
                      "last_transition_reason": "webhook_reprovisioned",
                      "diagnostic_id": "diag_connection_repair_001"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/reauthorize": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" },
        { "$ref": "#/components/parameters/IdempotencyKey" }
      ],
      "post": {
        "operationId": "reauthorizeChannelConnection",
        "summary": "Reinstall a hosted connection through its provider",
        "description": "Starts a fresh Slack OAuth installation for this exact hosted\nconnection. The returned resource carries durable authorization\nprogress in `authorization_setup`, so a caller can resume it after a\nreload or lost response. Completion is accepted only for the workspace\nalready bound to the connection; a different workspace fails closed.\n\nThe authorization code is exchanged by WhooshBang. It is never copied\ninto this request or returned by any API surface.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "selected_connection",
          "replay_retention_extends": false
        },
        "responses": {
          "200": {
            "description": "The equivalent durable authorization attempt already in progress.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" }
              }
            }
          },
          "201": {
            "description": "A new authorization attempt for the exact selected connection.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/restart-setup": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "restartChannelConnectionSetup",
        "summary": "Start a fresh setup on a connection that never finished one",
        "description": "Issues a new guided setup for a `customer_managed` connection whose\nsetup expired, failed, or was simply abandoned. Nothing was ever\nprovisioned under it, no identity was claimed, and no subscriber ever\nconsented to anything through it, so nothing is lost.\n\n**Telegram reuses the connection and answers `200`.** A fresh `setup`\nappears on the same resource.\n\n**Customer-owned Slack replaces the connection and answers `201`.** The\nabandoned connection is archived and a new one is returned, carrying a\nnew `app_setup` and a new creation link. The connection cannot be\nreused, because Slack bakes this deployment's request URLs into the app\nat the moment it is created and they are not ours to change afterwards:\na second setup on one connection would mean two Slack apps answering to\none address. **Read `id` on the response** — the connection you were\npolling is now archived. A Slack app the previous attempt already\ncreated is not withdrawn and cannot be; it is the customer's, and they\ndelete it in Slack when they are ready.\n\nEntering the three app-specific values again is not a restart, and does\nnot need one. `rotate-credential` replaces them on the connection that\nalready exists.\n\nRestart takes no body. The suggested identity recorded when the\nconnection was created is what the new attempt proposes again, so a\ncaller resuming a half-finished setup cannot accidentally rename a bot\nan administrator was already looking at. A different suggestion means\na different connection.\n\nRepeating the call is safe. A setup that is still live is returned as\nit stands rather than being replaced, so two dashboard tabs converge\non one session instead of racing to strand each other's link, and only\na session that can no longer be used is exchanged for a new one.\n\nA bot the previous attempt already created is not withdrawn and cannot\nbe: Telegram exposes no way to delete a bot. The administrator keeps it\nin their own Telegram account until they retire it in BotFather, and a restart\nwalks them through creating another rather than pretending the first\nnever happened.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the connection did not come from guided setup, so there is no setup\n  to restart — `idempotency_conflict` 409, `setup_not_managed` at `/`;\n- the connection already finished setup, or is archived, so restarting\n  would offer a second identity for something subscribers may already\n  be bound to — `idempotency_conflict` 409,\n  `invalid_connection_transition` at `/`;\n- the provider could not be reached, so whether a new session exists is\n  genuinely unknown — `provider_outcome_unknown` 502; read the\n  connection before calling again;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "200": {
            "description": "The connection carrying a usable setup and its advanced row version.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "setupRestarted": {
                    "value": {
                      "id": "chcon_44444444444444444444444444444444",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_managed",
                      "display_name": "Acme Alerts Bot",
                      "status": "pending",
                      "health": "unknown",
                      "setup": {
                        "status": "awaiting_handoff",
                        "handoff_url": "https://t.me/whooshbang_setup_bot?start=synthetic-setup-handoff-0002",
                        "expires_at": "2026-08-12T15:25:00.000Z",
                        "suggested_bot_username": "acme_alerts_bot"
                      },
                      "row_version": 3,
                      "created_at": "2026-08-12T15:00:00.000Z",
                      "updated_at": "2026-08-12T15:10:00.000Z",
                      "last_transition_at": "2026-08-12T15:10:00.000Z",
                      "last_transition_reason": "managed_setup_restarted",
                      "diagnostic_id": "diag_connection_managed_restart_001"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "A replacement connection carrying a fresh setup, for a\ncustomer-owned Slack app whose request URLs cannot be re-pointed.\nThe connection named in the request is now archived.\n",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "setupReplaced": {
                    "value": {
                      "id": "chcon_77777777777777777777777777777777",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_test_synthetic_alpha",
                      "environment": "test",
                      "provider": "slack",
                      "mode": "customer_managed",
                      "display_name": "Acme Slack",
                      "status": "pending",
                      "health": "unknown",
                      "installation": {
                        "display_name": "Slack app not yet created",
                        "health": "unknown",
                        "status": "pending"
                      },
                      "capabilities": [],
                      "recovery_action": "complete_authorization",
                      "app_setup": {
                        "status": "awaiting_authorities",
                        "creation_url": "https://api.slack.com/apps?new_app=1&manifest_json=%7B%22_metadata%22%3A%7B%22major_version%22%3A1%7D%7D",
                        "expires_at": "2026-09-01T12:30:00.000Z",
                        "app_name": "Acme Notifications",
                        "bot_display_name": "Acme Notify",
                        "outstanding_authorities": [
                          "application_identity",
                          "application_secret",
                          "ingress_secret"
                        ]
                      },
                      "row_version": 1,
                      "created_at": "2026-09-01T12:00:00.000Z",
                      "updated_at": "2026-09-01T12:00:00.000Z",
                      "last_transition_at": "2026-09-01T12:00:00.000Z",
                      "last_transition_reason": "slack_setup_awaiting_authorities",
                      "diagnostic_id": "diag_slack_customer_pending_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/rotate-credential": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "rotateChannelConnectionCredential",
        "summary": "Replace the credential behind a customer-owned connection",
        "description": "Seals a replacement credential and reprovisions delivery with it. The\nconnection keeps its provider identity, so every subscriber stays bound\nto the identity it consented to and only the secret changes.\n\nWhere the replacement comes from is decided by the connection, not by\nthe caller's preference. A `customer_byok` connection sends\n`credential`, because only its owner can produce a replacement. A\n`customer_managed` connection sends `{\"source\": \"provider_managed\"}`\nand nothing else, because only Telegram can issue one: asked to\nrotate, it revokes the bot's current token and hands the successor to\nthe manager that created it, so there is no customer-supplied\ncredential to send and no field here to send it in.\n\nA provider-managed rotation is one-shot. Once the replace call may have\nreached Telegram, an unconfirmed outcome is resolved by asking Telegram\nfor the bot's current token rather than by replacing again, because a\nsecond replace would revoke the token the first one issued. That is why\n`provider_outcome_unknown` on this operation is an instruction to read\nthe connection, never a hint to repeat the call.\n\nThe replacement must prove the same identity. A credential for a\ndifferent bot is a different identity and therefore a different\nconnection, which is why it is refused rather than silently\nre-pointing an existing connection — and the refusal names only the\nconnection's own identity, never anyone else's.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the provider answered and rejected the replacement —\n  `request_invalid` 400, `provider_credential_invalid` at `/credential`;\n- the arm does not match how this connection holds its credential —\n  `request_invalid` 400, `rotation_source_mismatch`, at `/credential`\n  when a `customer_managed` connection was sent a customer credential\n  and at `/source` when a `customer_byok` connection was asked for a\n  provider-issued one;\n- the replacement proves a different identity — `request_invalid` 400,\n  `provider_identity_mismatch` at `/credential`;\n- the connection is `whooshbang_shared`, whose credential WhooshBang\n  operates — `idempotency_conflict` 409,\n  `credential_not_customer_owned` at `/`;\n- the connection is archived — `idempotency_conflict` 409,\n  `invalid_connection_transition` at `/`;\n- the connection's own identity cannot be established, so no\n  replacement can be proved to belong to it — `idempotency_conflict`\n  409, `provider_identity_unverifiable` at `/`. Reachable only for a\n  connection that recorded no identity and whose stored credential no\n  longer validates; the remedy is to archive it and connect again,\n  because rotating without that proof is exactly the silent move of a\n  subscriber's consent this operation exists to prevent;\n- the provider could not be reached — `provider_outcome_unknown` 502,\n  so the caller must read the connection before retrying;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateChannelConnectionCredentialRequest"
              },
              "examples": {
                "rotate": {
                  "value": {
                    "credential": "0000000000:synthetic-example.rotated-not-a-real-bot-token"
                  }
                },
                "rotateProviderManaged": {
                  "value": { "source": "provider_managed" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The connection running on the replacement credential.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "rotated": {
                    "value": {
                      "id": "chcon_33333333333333333333333333333333",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_byok",
                      "display_name": "Acme Support Bot",
                      "status": "active",
                      "health": "healthy",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_support_synthetic_bot"
                      },
                      "row_version": 4,
                      "created_at": "2026-08-12T14:00:00.000Z",
                      "updated_at": "2026-08-12T14:30:00.000Z",
                      "health_checked_at": "2026-08-12T14:30:00.000Z",
                      "last_transition_at": "2026-08-12T14:30:00.000Z",
                      "last_transition_reason": "credential_rotated",
                      "diagnostic_id": "diag_connection_rotate_001"
                    }
                  },
                  "rotatedProviderManaged": {
                    "value": {
                      "id": "chcon_44444444444444444444444444444444",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_managed",
                      "display_name": "Acme Alerts Bot",
                      "status": "active",
                      "health": "healthy",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_alerts_bot"
                      },
                      "row_version": 6,
                      "created_at": "2026-08-12T15:00:00.000Z",
                      "updated_at": "2026-08-12T16:00:00.000Z",
                      "health_checked_at": "2026-08-12T16:00:00.000Z",
                      "last_transition_at": "2026-08-12T16:00:00.000Z",
                      "last_transition_reason": "credential_rotated",
                      "diagnostic_id": "diag_connection_managed_rotate_001"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/health-check": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "checkChannelConnectionHealth",
        "summary": "Re-check a connection against the provider now",
        "description": "Asks the provider about this connection and records the answer in\n`health` and `health_checked_at`. A connection whose delivery path\ndiverged becomes `degraded`, which still delivers: the identity a\nsubscriber consented to has not changed, only its last health check.\n\nThis is `connections:write` rather than `connections:read` on purpose.\nIt makes a live provider call and advances the connection's recorded\nhealth, so it is not a safe read: it is rate-limited by the provider,\nit can fail, and repeating it is not free. Read `health` from\n`getChannelConnection` when the last recorded answer is enough.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the connection is archived, so there is nothing left to check —\n  `idempotency_conflict` 409, `invalid_connection_transition` at `/`;\n- the provider could not be reached, so health is genuinely unknown\n  rather than bad — `provider_outcome_unknown` 502, and the recorded\n  health is left as it was;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "responses": {
          "200": {
            "description": "The connection carrying the health the provider just reported.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "healthChecked": {
                    "value": {
                      "id": "chcon_33333333333333333333333333333333",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_byok",
                      "display_name": "Acme Support Bot",
                      "status": "degraded",
                      "health": "degraded",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_support_synthetic_bot"
                      },
                      "row_version": 5,
                      "created_at": "2026-08-12T14:00:00.000Z",
                      "updated_at": "2026-08-12T14:40:00.000Z",
                      "health_checked_at": "2026-08-12T14:40:00.000Z",
                      "last_transition_at": "2026-08-12T14:40:00.000Z",
                      "last_transition_reason": "webhook_url_diverged",
                      "diagnostic_id": "diag_connection_health_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/purge": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "post": {
        "operationId": "purgeChannelConnection",
        "summary": "Destroy this connection's custody and hand the identity back",
        "description": "Releases the provider-side delivery path this connection installed and\ndestroys what it holds, then archives it. For `customer_byok` that is\nthe sealed customer credential, so the customer's bot is fully handed\nback and WhooshBang retains nothing that could act as it. A\n`whooshbang_shared` connection owns no credential, so purge releases\nonly its own routing and never touches the shared identity other\nenvironments still use.\n\nPurge is repeat-safe. Destroying something that is already destroyed\nreturns the same archived connection rather than a conflict, because a\ncaller that lost the response to the first attempt must be able to\nconfirm the outcome. Archiving first is not required, and archiving\nafterwards is refused because the connection is already archived.\n\nRefusals reuse the closed Problem vocabulary:\n\n- the provider could not be reached, so whether the delivery path was\n  released is genuinely unknown — `provider_outcome_unknown` 502, and\n  the connection is left as it was so the call can be repeated;\n- the provider rate-limited the call — `provider_retryable` 503 with\n  `retry_at`.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "responses": {
          "200": {
            "description": "The purged connection, archived and holding nothing.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" },
                "examples": {
                  "purged": {
                    "value": {
                      "id": "chcon_33333333333333333333333333333333",
                      "project_id": "project_synthetic_alpha",
                      "environment_id": "environment_live_synthetic_alpha",
                      "environment": "live",
                      "provider": "telegram",
                      "mode": "customer_byok",
                      "display_name": "Acme Support Bot",
                      "status": "archived",
                      "health": "unknown",
                      "identity": {
                        "provider": "telegram",
                        "handle": "acme_support_synthetic_bot"
                      },
                      "row_version": 6,
                      "created_at": "2026-08-12T14:00:00.000Z",
                      "updated_at": "2026-08-12T14:50:00.000Z",
                      "health_checked_at": "2026-08-12T14:40:00.000Z",
                      "last_transition_at": "2026-08-12T14:50:00.000Z",
                      "last_transition_reason": "owner_purged",
                      "diagnostic_id": "diag_connection_purge_001",
                      "archived_at": "2026-08-12T14:50:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "502": { "$ref": "#/components/responses/ProviderOutcomeUnknown" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/app-manifest": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "get": {
        "operationId": "getChannelConnectionAppManifest",
        "summary": "Read the generated application configuration a customer-owned setup will create",
        "description": "Returns the exact configuration WhooshBang generated for this setup of\nan application the customer creates and owns — the scopes it will ask\nfor, the request URLs it will point at, the literal configuration\ndocument in the provider's own format, and the same prefilled creation\nlink the setup already carries.\n\nIt exists so the owner can read what they are about to approve, and a\nreviewer can check it, without opening the provider or decoding a URL.\nIt carries configuration only: no organization, project, or\nenvironment, no credential, and no provider-native identifier.\n\nOnly a connection whose provider sets it up through an application the\ncustomer creates has one. Every other provider and mode answers `404`,\nbecause a manifest they do not have is not a manifest that is empty.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "responses": {
          "200": {
            "description": "The generated application configuration for exactly this setup.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerApplicationManifest"
                },
                "examples": {
                  "manifest": {
                    "value": {
                      "provider": "slack",
                      "creation_url": "https://api.slack.com/apps?new_app=1&manifest_json=%7B%22_metadata%22%3A%7B%22major_version%22%3A1%7D%7D",
                      "app_name": "Acme Notifications",
                      "bot_display_name": "Acme Notify",
                      "description": "Delivery notifications from Acme.",
                      "bot_scopes": ["chat:write"],
                      "user_scopes": ["openid"],
                      "request_urls": {
                        "events": "https://api.whooshbang.com/internal/webhooks/slack/apps/CTBQNURSpqxDgLcqvbEDcA/events",
                        "interactions": "https://api.whooshbang.com/internal/webhooks/slack/apps/CTBQNURSpqxDgLcqvbEDcA/interactions",
                        "installation_redirect": "https://api.whooshbang.com/v1/provider-authorizations/slack/apps/callback",
                        "recipient_redirect": "https://api.whooshbang.com/v1/provider-authorizations/slack/apps/recipient/callback"
                      },
                      "manifest": {
                        "_metadata": { "major_version": 1, "minor_version": 1 },
                        "display_information": {
                          "name": "Acme Notifications",
                          "description": "Delivery notifications from Acme."
                        },
                        "features": {
                          "app_home": {
                            "home_tab_enabled": true,
                            "messages_tab_enabled": true,
                            "messages_tab_read_only_enabled": true
                          },
                          "bot_user": {
                            "display_name": "Acme Notify",
                            "always_online": false
                          }
                        },
                        "oauth_config": {
                          "pkce_enabled": false,
                          "redirect_urls": [
                            "https://api.whooshbang.com/v1/provider-authorizations/slack/apps/callback",
                            "https://api.whooshbang.com/v1/provider-authorizations/slack/apps/recipient/callback"
                          ],
                          "scopes": {
                            "bot": ["chat:write"],
                            "user": ["openid"]
                          }
                        },
                        "settings": {
                          "event_subscriptions": {
                            "request_url": "https://api.whooshbang.com/internal/webhooks/slack/apps/CTBQNURSpqxDgLcqvbEDcA/events",
                            "bot_events": [
                              "app_home_opened",
                              "app_uninstalled",
                              "tokens_revoked"
                            ]
                          },
                          "interactivity": {
                            "is_enabled": true,
                            "request_url": "https://api.whooshbang.com/internal/webhooks/slack/apps/CTBQNURSpqxDgLcqvbEDcA/interactions"
                          },
                          "is_hosted": false,
                          "is_mcp_enabled": false,
                          "org_deploy_enabled": false,
                          "socket_mode_enabled": false,
                          "token_rotation_enabled": true
                        }
                      },
                      "diagnostic_id": "diag_slack_app_manifest_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/tests": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "get": {
        "operationId": "listConnectionTests",
        "summary": "List this connection's recent owner-triggered tests",
        "description": "Newest first. This is the audit-safe failure history for one\nconnection: what was tried, when, what came back, and what to do about\nit. Every entry is safe to render, log, and paste into an issue.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Tests placed against exactly this connection.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionTestCollection"
                },
                "examples": {
                  "tests": {
                    "value": {
                      "items": [
                        {
                          "id": "cntest_11111111111111111111111111111111",
                          "connection_id": "chcon_77777777777777777777777777777777",
                          "kind": "signed_interaction",
                          "status": "succeeded",
                          "requested_at": "2026-09-02T09:00:00.000Z",
                          "completed_at": "2026-09-02T09:00:22.000Z",
                          "expires_at": "2026-09-02T09:15:00.000Z",
                          "evidence": {
                            "identity_handle": "Acme Notify",
                            "workspace_display_name": "Acme",
                            "accepted_at": "2026-09-02T09:00:01.000Z",
                            "observed_at": "2026-09-02T09:00:22.000Z",
                            "round_trip_ms": 22000,
                            "signature_verified": true,
                            "ingress_host": "api.whooshbang.com"
                          },
                          "recovery_action": "none",
                          "diagnostic_id": "diag_connection_test_succeeded_001"
                        },
                        {
                          "id": "cntest_22222222222222222222222222222222",
                          "connection_id": "chcon_77777777777777777777777777777777",
                          "kind": "outbound_notification",
                          "status": "failed",
                          "requested_at": "2026-09-02T08:40:00.000Z",
                          "completed_at": "2026-09-02T08:40:02.000Z",
                          "expires_at": "2026-09-02T08:55:00.000Z",
                          "failure_code": "credential_unavailable",
                          "recovery_action": "reinstall",
                          "diagnostic_id": "diag_connection_test_failed_001"
                        }
                      ],
                      "page": 1,
                      "page_size": 25,
                      "total": 2
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createConnectionTest",
        "summary": "Prove this exact connection still works",
        "description": "Runs one test against one connection, on demand, and answers with what\nit observed rather than with a claim.\n\nAvailable on any Slack connection, whether the app is one the customer\nowns or the one WhooshBang operates. Every other provider and mode is\nrefused rather than reporting a pass it never ran.\n\n**A test addresses the workspace member who authorized this exact\nconnection, and nobody else.** For an app the customer owns that is the\nperson who installed it, once, for one connection. The\nWhooshBang-operated app's installation is shared across tenants, so\n\"whoever installed the app\" is not necessarily anybody the calling\ntenant named; what is recorded instead is the member who approved this\nenvironment's own connection, during its own authorization, and each\nlater authorization replaces it. One tenant therefore cannot cause a\nmessage to somebody another tenant authorized.\n\n`outbound_notification` sends one visible private message through this\nexact identity to that member, and settles when the provider accepts\nit. Nobody else can be addressed: a test cannot reach a channel, and it\ncannot reach a subscriber who has not authorized anything.\n\n`signed_interaction` sends that person a message with one button and\nthen waits. It settles when the provider calls this deployment's\ninteractivity URL and the signature over the untouched body verifies\nagainst the secret this connection custodies — the only proof that the\nsigning secret, the request URL, and public reachability are all\ncorrect at once. A window that closes with nothing arriving settles as\n`expired`, which says nobody pressed it, and a request that arrives and\ndoes not verify settles as `failed` with `unverified_request_received`.\n\nThe response is the placed test. An `outbound_notification` is usually\nalready settled when it returns; a `signed_interaction` is `pending`\nuntil somebody presses the button, so read it again or list this\nconnection's tests.\n\n**A provider failure is an answer, not a refusal.** If the connection\nhas not finished setup, or its grant is unavailable, or Slack refuses,\nrate-limits, or cannot be reached, the test is **recorded** and answers\n`201` carrying `status: failed`, a `failure_code` and a\n`recovery_action`. There is no `502` or `503` on this operation, and\nthat is deliberate: a diagnostic that leaves no trace is the one thing\nan audit-safe failure history cannot have, so the failure goes in the\nhistory rather than into a problem document nobody keeps.\n\nThree things are refused outright, because none describes a test that\nran: the connection is archived, it is not a Slack connection, or it is\na WhooshBang-operated Slack connection whose authorization has been\nrevoked — `idempotency_conflict` 409, `invalid_connection_transition`\nat `/`. A connection that has never recorded who authorized it is not\nrefused: it is a recorded failure with\n`verification_target_unknown`, because there is nobody a test could\nhonestly address.\n\nAn `outbound_notification` or `signed_interaction` test never carries\ncustomer notification content, never counts as a delivery to a\nsubscriber, and never changes what any subscriber receives.\n\n**`subscriber_message` works on every channel and addresses one\nsubscriber the caller names.** It sends `text` to that subscriber\nthrough exactly this connection, whether or not it is the default and\nwhatever channel the subscriber prefers, so a connection can be proved\nbefore it starts sending. It is a real message: it is recorded in the\nmessage history, the test's `message_id` names it, and the test\nsettles as that message does. A subscriber who has not connected\nthrough this connection is refused with `subscriber_not_connected`\n422, naming the subscriber and the channel, rather than as a\ndestination that does not exist. It needs the same write scope and,\nin the dashboard, an administrator.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "exact_request_body",
          "replay_retention_extends": false
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateConnectionTestRequest"
              },
              "examples": {
                "signedInteraction": {
                  "value": { "kind": "signed_interaction" }
                },
                "subscriberMessage": {
                  "value": {
                    "kind": "subscriber_message",
                    "to": { "subscriber_id": "customer_123" },
                    "text": "Checking this connection works."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The equivalent test an idempotent replay already placed.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConnectionTest" }
              }
            }
          },
          "201": {
            "description": "The placed test, settled if it could settle immediately.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConnectionTest" },
                "examples": {
                  "pending": {
                    "value": {
                      "id": "cntest_11111111111111111111111111111111",
                      "connection_id": "chcon_77777777777777777777777777777777",
                      "kind": "signed_interaction",
                      "status": "pending",
                      "requested_at": "2026-09-02T09:00:00.000Z",
                      "expires_at": "2026-09-02T09:15:00.000Z",
                      "evidence": {
                        "identity_handle": "Acme Notify",
                        "workspace_display_name": "Acme",
                        "accepted_at": "2026-09-02T09:00:01.000Z",
                        "ingress_host": "api.whooshbang.com"
                      },
                      "recovery_action": "none",
                      "diagnostic_id": "diag_connection_test_pending_001"
                    }
                  },
                  "subscriberMessage": {
                    "value": {
                      "id": "cntest_33333333333333333333333333333333",
                      "connection_id": "chcon_77777777777777777777777777777777",
                      "kind": "subscriber_message",
                      "status": "pending",
                      "requested_at": "2026-09-28T09:00:00.000Z",
                      "expires_at": "2026-09-29T09:00:00.000Z",
                      "message_id": "msg_33333333333333333333333333333333",
                      "recovery_action": "none",
                      "diagnostic_id": "diag_connection_test_subscriber"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/tests/{test_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" },
        { "$ref": "#/components/parameters/ConnectionTestId" }
      ],
      "get": {
        "operationId": "getConnectionTest",
        "summary": "Read one owner-triggered connection test",
        "description": "The durable answer to one test. A `signed_interaction` is read again\nhere until it settles; a pending test whose window has closed reads as\n`expired` on the way out rather than waiting for a sweep, so the status\nthe owner sees is the one they actually have.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "responses": {
          "200": {
            "description": "The exact test.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConnectionTest" },
                "examples": {
                  "succeeded": {
                    "value": {
                      "id": "cntest_11111111111111111111111111111111",
                      "connection_id": "chcon_77777777777777777777777777777777",
                      "kind": "signed_interaction",
                      "status": "succeeded",
                      "requested_at": "2026-09-02T09:00:00.000Z",
                      "completed_at": "2026-09-02T09:00:22.000Z",
                      "expires_at": "2026-09-02T09:15:00.000Z",
                      "evidence": {
                        "identity_handle": "Acme Notify",
                        "workspace_display_name": "Acme",
                        "accepted_at": "2026-09-02T09:00:01.000Z",
                        "observed_at": "2026-09-02T09:00:22.000Z",
                        "round_trip_ms": 22000,
                        "signature_verified": true,
                        "ingress_host": "api.whooshbang.com"
                      },
                      "recovery_action": "none",
                      "diagnostic_id": "diag_connection_test_succeeded_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notifier-connections": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listNotifierConnections",
        "summary": "Read which connection each notifier sends through",
        "description": "Every route in this environment, ordered by notifier and then\nconnection.\n\nThe default route decides which connection a message goes through\nwhen the subscriber is connected there and the sender names none. A\nsubscriber who is not connected through the default is reached through\nthe connection they connected through most recently, and a sender may\nname any connection the subscriber connected through. Routes never\nstop a connection sending; pausing the connection does.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Routes owned by exactly this organization, project, and environment.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotifierConnectionCollection"
                },
                "examples": {
                  "routes": {
                    "value": {
                      "items": [
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_11111111111111111111111111111111",
                          "is_default": true
                        },
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_22222222222222222222222222222222",
                          "is_default": false
                        }
                      ],
                      "total": 2,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "attachNotifierConnection",
        "summary": "Route a notifier through a connection",
        "description": "Points a notifier at a connection in the same environment and, unless\ntold otherwise, makes it the default the notifier sends and authorizes\nthrough.\n\nRepeating an identical request changes nothing and returns the same\nroutes, so a caller that lost a response can simply send it again. No\nidempotency key is required, because there is no second effect to\nsuppress.\n\nPromoting a new default demotes the old one in the same transaction, so\nno send ever observes two. **This changes which identity subscribers\nhear from next.** Bindings already authorized against the previously\ndefault connection keep their consent and stop being deliverable until\nthat connection is default again; nothing moves consent from one\nidentity to another, and nothing falls back between them.\n\nThe first connection created in an environment whose default notifier\nhas no route at all is attached by `createChannelConnection` itself, so\na first setup does not have to call this to start working. A later\nconnection never displaces an existing route on its own.\n\nRefusals reuse the closed Problem vocabulary:\n\n- the notifier or connection does not exist in this environment, or\n  belongs to another tenant — `resource_not_found` 404, identically in\n  both cases;\n- the connection is archived — `request_invalid` 400 with a\n  `connection_id` field error, because an archived connection is\n  terminal and routing to it would be silently undeliverable.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachNotifierConnectionRequest"
              },
              "examples": {
                "attach": {
                  "value": {
                    "notifier_id": "default",
                    "connection_id": "chcon_11111111111111111111111111111111",
                    "is_default": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Every route this notifier now has, including the one just written.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotifierConnectionCollection"
                },
                "examples": {
                  "routes": {
                    "value": {
                      "items": [
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_11111111111111111111111111111111",
                          "is_default": true
                        },
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_22222222222222222222222222222222",
                          "is_default": false
                        }
                      ],
                      "total": 2,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/notifier-connections/{notifier_id}/{connection_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/NotifierId" },
        { "$ref": "#/components/parameters/ChannelConnectionId" }
      ],
      "delete": {
        "operationId": "detachNotifierConnection",
        "summary": "Stop routing a notifier through a connection",
        "description": "Removes one route. The connection itself is untouched and keeps its\nidentity, its credential custody, and every binding subscribers gave\nit — this is the reversible half of retiring an identity, and archive\nis the terminal one.\n\nDetaching the default leaves the notifier with no default, and each\nmessage then goes through the connection its subscriber connected\nthrough most recently. No message ever reaches a subscriber through an\nidentity they did not connect through. To stop a connection sending,\npause it.\n\nRepeat-safe. Removing a route that is already gone returns the\nnotifier's remaining routes rather than a 404, because a caller that\nlost the first response must be able to confirm the outcome.\n",
        "tags": ["Channel connections"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "responses": {
          "200": {
            "description": "The routes this notifier has left.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotifierConnectionCollection"
                },
                "examples": {
                  "routes": {
                    "value": {
                      "items": [
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_11111111111111111111111111111111",
                          "is_default": true
                        },
                        {
                          "notifier_id": "default",
                          "connection_id": "chcon_22222222222222222222222222222222",
                          "is_default": false
                        }
                      ],
                      "total": 2,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/recipient-experience": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "get": {
        "operationId": "getProjectRecipientExperience",
        "summary": "Read project-owned recipient brand, fallback locale, and email answer behavior",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Current constrained project recipient experience.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectRecipientExperience"
                },
                "examples": {
                  "configured": {
                    "value": {
                      "project_id": "project_synthetic",
                      "default_locale": "es",
                      "brand": {
                        "display_name": "Acme Alerts",
                        "logo_asset_id": "asset_ac1e0000000000000000000000000001",
                        "accent_color": "#4F46E5",
                        "color_scheme": "system"
                      },
                      "row_version": 2,
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_project_experience"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "put": {
        "operationId": "updateProjectRecipientExperience",
        "summary": "Update project-owned recipient brand, fallback locale, and optional email answer behavior",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectRecipientExperienceRequest"
              },
              "examples": {
                "configure": {
                  "value": {
                    "default_locale": "es",
                    "brand": {
                      "display_name": "Acme Alerts",
                      "logo_asset_id": "asset_ac1e0000000000000000000000000001",
                      "accent_color": "#4F46E5",
                      "color_scheme": "system"
                    },
                    "row_version": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated constrained project recipient experience.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectRecipientExperience"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/recipient-experience/logo": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "put": {
        "operationId": "uploadRecipientBrandLogo",
        "summary": "Normalize, host, and configure one project recipient logo",
        "description": "Accepts only a bounded PNG payload. WhooshBang decodes and re-encodes it, stores only the normalized result, and atomically replaces the project's prior logo. The service never fetches a customer URL.",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "parameters": [
          {
            "name": "WhooshBang-Recipient-Experience-Version",
            "in": "header",
            "required": true,
            "description": "The project recipient-experience row version last observed by the owner.",
            "schema": { "type": "integer", "minimum": 1 }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary",
                "maxLength": 524288
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Normalized asset metadata and the configuration now using it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientBrandLogoUpload"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/recipient-experience": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "getEnvironmentRecipientExperience",
        "summary": "Read one environment's exact recipient browser policy",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Current revisioned environment recipient experience.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentRecipientExperience"
                },
                "examples": {
                  "configured": {
                    "value": {
                      "project_id": "project_synthetic",
                      "environment_id": "environment_project_synthetic_test",
                      "environment": "test",
                      "revision": 2,
                      "enabled_channels": ["telegram"],
                      "connectable_channels": ["telegram"],
                      "allowed_origins": ["https://app.acme.example"],
                      "return_destinations": [
                        {
                          "key": "notifications",
                          "url": "https://app.acme.example/settings/notifications"
                        }
                      ],
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_environment_experience"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "put": {
        "operationId": "updateEnvironmentRecipientExperience",
        "summary": "Replace one environment's enabled channels and exact browser policy",
        "description": "Origins are exact scheme/host/port values, written in any spelling that\nmeans that same origin: a trailing slash, an uppercase host, and an\nexplicitly written default port are accepted and stored in canonical\nform. Return destinations are registered developer keys resolving to\nexact URLs. Wildcards, templates, arbitrary recipient-time URLs, and\nchannels not backed by an offered compatible connection are refused.\n",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerCredential": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:write"],
        "x-organization-membership": "required",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEnvironmentRecipientExperienceRequest"
              },
              "examples": {
                "configure": {
                  "value": {
                    "revision": 1,
                    "enabled_channels": ["telegram"],
                    "allowed_origins": ["https://app.acme.example"],
                    "return_destinations": [
                      {
                        "key": "notifications",
                        "url": "https://app.acme.example/settings/notifications"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated revisioned environment recipient experience.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvironmentRecipientExperience"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscribers/{subscriber_id}/channel-settings": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "subscriber_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "get": {
        "operationId": "getSubscriberChannelSettings",
        "summary": "Read safe channel settings for one subscriber",
        "description": "Uses the exact authorized organization, project, environment, subscriber\nand default notifier. Only existing bindings can be managed; this never\nestablishes consent or revives a revoked binding. Dashboard mutations\nrequire current organization administrator membership. A project\ncredential must name its own stored project and environment.\n",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Current safe subscriber channel settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberChannelSettings"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscribers/{subscriber_id}/bindings/{binding_id}/{action}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "subscriber_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        },
        {
          "in": "path",
          "name": "binding_id",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        },
        {
          "in": "path",
          "name": "action",
          "required": true,
          "schema": {
            "type": "string",
            "enum": ["pause", "resume", "unsubscribe"]
          }
        }
      ],
      "post": {
        "operationId": "transitionSubscriberBinding",
        "summary": "Pause, resume, or unsubscribe one existing binding",
        "description": "Uses the exact authorized organization, project, environment, subscriber\nand default notifier. Only existing bindings can be managed; this never\nestablishes consent or revives a revoked binding. Dashboard mutations\nrequire current organization administrator membership. A project\ncredential must name its own stored project and environment.\n",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "responses": {
          "200": {
            "description": "Current safe subscriber channel settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberChannelSettings"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscribers/{subscriber_id}/preferred-binding": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "subscriber_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "put": {
        "operationId": "setSubscriberPreferredBinding",
        "summary": "Set the preferred active binding for one subscriber",
        "description": "Uses the exact authorized organization, project, environment, subscriber\nand default notifier. Only existing bindings can be managed; this never\nestablishes consent or revives a revoked binding. Dashboard mutations\nrequire current organization administrator membership. A project\ncredential must name its own stored project and environment.\n",
        "tags": ["Recipient experience"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] },
          { "bearerCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPreferredBindingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current safe subscriber channel settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberChannelSettings"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/recipient-sessions": {
      "post": {
        "operationId": "createRecipientSession",
        "summary": "Create one attenuated recipient browser session",
        "description": "The authenticated project credential supplies organization, project, and\nenvironment. The request supplies only one subscriber, optional locale,\noptional registered return key, and bounded expiry. The response is the\nonly reveal of the browser capability and contains no resolved return\nURL, provider identity, group state, or application credential.\n",
        "tags": ["Recipient experience"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRecipientSessionRequest"
              },
              "examples": {
                "create": {
                  "value": {
                    "subscriber_id": "user_123",
                    "locale": "es",
                    "return_to": "notifications",
                    "expires_in_seconds": 900
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Creation-only recipient capability and safe session projection.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateRecipientSessionResponse"
                },
                "examples": {
                  "created": {
                    "value": {
                      "session": {
                        "id": "recipient_session_user_123",
                        "capability_prefix": "wb_rs1.rsc_AAAAAAAAAAAAAAAAAAAAAA",
                        "state": "active",
                        "configuration_revision": 2,
                        "locale": "es",
                        "brand": {
                          "display_name": "Acme Alerts",
                          "logo_asset_id": "asset_ac1e0000000000000000000000000001",
                          "accent_color": "#4F46E5",
                          "color_scheme": "system"
                        },
                        "panel_copy": {},
                        "channels": [
                          {
                            "channel": "telegram",
                            "state": "available",
                            "preferred": false
                          }
                        ],
                        "operations": [
                          "session:read",
                          "handoff:create",
                          "binding:pause",
                          "binding:resume",
                          "binding:revoke",
                          "preference:write"
                        ],
                        "expires_at": "2026-08-22T18:15:00Z",
                        "diagnostic_id": "diag_n17_recipient_session_created"
                      },
                      "browser_capability": "wb_rs1.rsc_AAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
                      "hosted_url": "https://connect.whooshbang.com/recipient-settings"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" }
        }
      }
    },
    "/v1/recipient-sessions/{recipient_session_id}": {
      "parameters": [
        {
          "name": "recipient_session_id",
          "in": "path",
          "required": true,
          "description": "Opaque recipient-session identity; never browser authority.",
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "delete": {
        "operationId": "revokeRecipientSession",
        "summary": "Revoke one recipient browser session",
        "description": "Immediately and terminally ends the session selected inside the\nauthenticated project environment. The browser capability stops\nworking, and any independently issued provider handoff that has not\nalready been consumed stops yielding an authorization link.\n\nRepeating the request is safe. An already revoked, absent, or\nout-of-scope session produces the same empty response, so this route\ncannot be used to enumerate session identifiers across environments or\norganizations.\n",
        "tags": ["Recipient experience"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "capability_returned": false
        },
        "responses": {
          "204": {
            "description": "The session is no longer usable in this project environment."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/recipient-session": {
      "parameters": [
        {
          "name": "Origin",
          "in": "header",
          "required": true,
          "description": "Exact configured browser origin, pinned on first successful exchange.",
          "schema": { "type": "string", "minLength": 8, "maxLength": 255 }
        }
      ],
      "get": {
        "operationId": "getRecipientSession",
        "summary": "Read the current browser-safe recipient session",
        "tags": ["Recipient experience"],
        "security": [{ "recipientSessionCapability": [] }],
        "responses": {
          "200": {
            "description": "Safe state for this capability's one subscriber.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RecipientSession" },
                "examples": {
                  "active": {
                    "value": {
                      "id": "recipient_session_user_123",
                      "capability_prefix": "wb_rs1.rsc_AAAAAAAAAAAAAAAAAAAAAA",
                      "state": "active",
                      "configuration_revision": 2,
                      "locale": "es",
                      "brand": {
                        "display_name": "Acme Alerts",
                        "logo_asset_id": "asset_ac1e0000000000000000000000000001",
                        "accent_color": "#4F46E5",
                        "color_scheme": "system"
                      },
                      "panel_copy": {},
                      "channels": [
                        {
                          "channel": "telegram",
                          "state": "connected",
                          "binding_id": "binding_user_123_telegram",
                          "preferred": true
                        }
                      ],
                      "preference": {
                        "notifier_id": "default",
                        "binding_id": "binding_user_123_telegram",
                        "connection_id": "connection_acme_telegram",
                        "channel": "telegram",
                        "row_version": 1,
                        "updated_at": "2026-08-22T18:01:00Z",
                        "diagnostic_id": "diag_n17_preferred_binding"
                      },
                      "operations": [
                        "session:read",
                        "handoff:create",
                        "binding:pause",
                        "binding:resume",
                        "binding:revoke",
                        "preference:write"
                      ],
                      "expires_at": "2026-08-22T18:15:00Z",
                      "diagnostic_id": "diag_n17_recipient_session"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" }
        }
      }
    },
    "/v1/recipient-session/category-preferences": {
      "get": {
        "operationId": "getCategoryPreferences",
        "summary": "Read this subscriber's message categories and switches",
        "tags": ["Message categories"],
        "security": [{ "recipientSessionCapability": [] }],
        "responses": {
          "200": {
            "description": "Category choices for this exact subscriber.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCategoryPreferenceCollection"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" }
        }
      }
    },
    "/v1/recipient-session/category-preferences/{category_key}": {
      "parameters": [
        {
          "name": "category_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/MessageCategoryKey" }
        }
      ],
      "put": {
        "operationId": "setCategoryPreference",
        "summary": "Switch one of this subscriber's message categories on or off",
        "tags": ["Message categories"],
        "security": [{ "recipientSessionCapability": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSubscriberCategoryPreferenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated category choice.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCategoryPreference"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/recipient-session/logo/{asset_id}": {
      "parameters": [
        {
          "name": "Origin",
          "in": "header",
          "required": true,
          "description": "Exact configured browser origin pinned to the recipient session.",
          "schema": { "type": "string", "minLength": 8, "maxLength": 255 }
        },
        {
          "name": "asset_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/RecipientBrandAssetId" }
        }
      ],
      "get": {
        "operationId": "getRecipientBrandLogo",
        "summary": "Serve this session's current normalized recipient logo",
        "tags": ["Recipient experience"],
        "security": [{ "recipientSessionCapability": [] }],
        "responses": {
          "200": {
            "description": "Canonical PNG bytes for the exact brand projected into this session.",
            "headers": {
              "Cache-Control": {
                "schema": { "type": "string", "const": "no-store" }
              },
              "X-Content-Type-Options": {
                "schema": { "type": "string", "const": "nosniff" }
              }
            },
            "content": {
              "image/png": {
                "schema": { "type": "string", "format": "binary" }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/recipient-session/handoffs": {
      "parameters": [
        {
          "name": "Origin",
          "in": "header",
          "required": true,
          "schema": { "type": "string", "minLength": 8, "maxLength": 255 }
        }
      ],
      "post": {
        "operationId": "createProviderHandoff",
        "summary": "Create one independently single-use hosted provider handoff",
        "tags": ["Recipient experience"],
        "security": [{ "recipientSessionCapability": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProviderHandoffRequest"
              },
              "examples": {
                "popup": {
                  "value": {
                    "channel": "telegram",
                    "completion": {
                      "mode": "popup",
                      "target_origin": "https://app.acme.example",
                      "opener_nonce": "AAAAAAAAAAAAAAAAAAAAAA"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Exact hosted handoff and exact-origin completion contract.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProviderHandoff" },
                "examples": {
                  "handoff": {
                    "value": {
                      "id": "handoff_user_123_telegram",
                      "channel": "telegram",
                      "state": "pending",
                      "handoff_url": "https://connect.whooshbang.com/handoffs/wb_rh1.rhc_AAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
                      "completion": {
                        "mode": "popup",
                        "target_origin": "https://app.acme.example",
                        "opener_nonce": "AAAAAAAAAAAAAAAAAAAAAA"
                      },
                      "expires_at": "2026-08-22T18:05:00Z",
                      "diagnostic_id": "diag_n17_provider_handoff"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/recipient-session/preference": {
      "parameters": [
        {
          "name": "Origin",
          "in": "header",
          "required": true,
          "schema": { "type": "string", "minLength": 8, "maxLength": 255 }
        }
      ],
      "put": {
        "operationId": "setPreferredBinding",
        "summary": "Select one exact active binding for this subscriber and notifier",
        "description": "The capability supplies subscriber and tenant scope. The binding must be\nactive, connection-bound, attached, enabled, and offered by that exact\nenvironment. Moving an existing preference is explicit. An unavailable\npreference later refuses direct delivery without selecting a fallback.\n",
        "tags": ["Recipient experience"],
        "security": [{ "recipientSessionCapability": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPreferredBindingRequest"
              },
              "examples": {
                "prefer": {
                  "value": {
                    "binding_id": "binding_user_123_telegram_replacement",
                    "row_version": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The exact preferred binding.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PreferredBinding" },
                "examples": {
                  "preferred": {
                    "value": {
                      "notifier_id": "default",
                      "binding_id": "binding_user_123_telegram_replacement",
                      "connection_id": "connection_acme_telegram_replacement",
                      "channel": "telegram",
                      "row_version": 2,
                      "updated_at": "2026-08-22T18:01:00Z",
                      "diagnostic_id": "diag_n17_preferred_binding"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" }
        }
      }
    },
    "/v1/recipient-session/bindings/{binding_id}/{action}": {
      "parameters": [
        {
          "name": "Origin",
          "in": "header",
          "required": true,
          "schema": { "type": "string", "minLength": 8, "maxLength": 255 }
        },
        {
          "name": "binding_id",
          "in": "path",
          "required": true,
          "description": "Exact binding owned by this capability's subscriber; never authority by itself.",
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        },
        {
          "name": "action",
          "in": "path",
          "required": true,
          "schema": { "type": "string", "enum": ["pause", "resume", "revoke"] }
        }
      ],
      "post": {
        "operationId": "transitionBinding",
        "summary": "Pause, resume, or revoke this subscriber's exact binding",
        "tags": ["Recipient experience"],
        "security": [{ "recipientSessionCapability": [] }],
        "responses": {
          "200": {
            "description": "Refreshed safe recipient session. A preference naming a paused or revoked binding remains an unavailable exact choice, so delivery refuses without fallback until the recipient explicitly selects another active binding.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RecipientSession" }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/RecipientCapabilityInvalid"
          },
          "403": { "$ref": "#/components/responses/RecipientOriginForbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/email-consent-assertions": {
      "post": {
        "operationId": "assertEmailConsent",
        "summary": "Assert existing consent for one customer-owned email recipient",
        "description": "Creates or resolves the subscriber and activates the exact binding atomically.\nShared email refuses assertions. Active domain, OAuth, webhook and connection\nauthority are required. Recipient revocation, pause, suppression and holds win.\nIdentical retries return current binding state; changed inputs conflict.\n",
        "tags": ["Subscribers"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssertEmailConsentRequest"
              },
              "examples": {
                "assertion": {
                  "value": {
                    "subscriber_id": "customer-42",
                    "notifier_id": "updates",
                    "connection_id": "chcon_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "domain_id": "emldom_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "address": "User@xn--bcher-kva.example",
                    "consented": true,
                    "consented_at": "2026-09-01T12:00:00.000Z",
                    "source": "account-settings"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The asserted binding with authenticated audit metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BindingSummary" },
                "examples": {
                  "binding": {
                    "value": {
                      "id": "binding_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      "project_id": "proj_example",
                      "environment": "live",
                      "subscriber_id": "customer-42",
                      "notifier_id": "updates",
                      "channel": "email",
                      "connection_id": "chcon_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      "status": "active",
                      "address": "User@xn--bcher-kva.example",
                      "consent": {
                        "kind": "asserted_prior_consent",
                        "consented_at": "2026-09-01T12:00:00.000Z",
                        "source": "account-settings",
                        "asserted_at": "2026-09-11T12:00:00.000Z",
                        "asserted_by": {
                          "kind": "credential",
                          "id": "cred_example"
                        },
                        "domain_id": "emldom_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/subscribers": {
      "get": {
        "operationId": "listSubscribers",
        "summary": "List, search and filter the project's subscribers",
        "description": "The project's subscribers, newest first, with the channels each can be\nreached on in the authenticated environment. `q` finds part of an ID,\na display name or a channel name through a search index that holds\nkeyed fragments rather than the values, so the database can tell\nwhich subscribers share part of an identifier but cannot read one.\n",
        "tags": ["Subscribers"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Prefix or part of a subscriber's ID, display name or kept channel name,\nfrom one character. Matching is case-insensitive; SQL wildcard\ncharacters are literal search input.\n",
            "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
          },
          {
            "name": "channel",
            "in": "query",
            "required": false,
            "description": "Only subscribers reachable on this channel in the environment.",
            "schema": { "$ref": "#/components/schemas/Channel" }
          },
          {
            "name": "connection_id",
            "in": "query",
            "required": false,
            "description": "Only subscribers who connected through this connection.",
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          },
          {
            "name": "group",
            "in": "query",
            "required": false,
            "description": "Only current members of the static group with this key, in the\nenvironment asked about. Combines with every other filter, so `q`\nsearches within the group.\n",
            "schema": { "$ref": "#/components/schemas/GroupKey" }
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "active_after",
            "in": "query",
            "required": false,
            "description": "Only subscribers whose `last_activity_at` is at or after this.",
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "active_before",
            "in": "query",
            "required": false,
            "description": "Only subscribers whose `last_activity_at` is before this.",
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of subscribers, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCollection"
                },
                "examples": {
                  "subscribers": {
                    "value": {
                      "items": [
                        {
                          "subscriber_id": "user_123",
                          "display_name": "Jane Smith",
                          "name": "Jane Smith",
                          "locale": "es",
                          "channels": ["telegram"],
                          "last_activity_at": "2026-09-28T17:00:00Z",
                          "created_at": "2026-08-22T18:00:00Z",
                          "updated_at": "2026-09-28T18:00:00Z",
                          "diagnostic_id": "diag_subscriber_listed"
                        }
                      ],
                      "next_cursor": "c3Vic2NyaWJlcnNfbmV4dA",
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createSubscriber",
        "summary": "Create a subscriber and optional initial static-group memberships",
        "description": "Every group key must resolve to an active group in the authenticated\nproject environment. Subscriber and memberships commit together or not\nat all. A later create conflicts instead of replacing memberships.\n",
        "tags": ["Subscribers"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriberRequest"
              },
              "examples": {
                "initialGroups": {
                  "value": {
                    "subscriber_id": "user_123",
                    "locale": "es",
                    "groups": ["organization-updates", "trial-users"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The subscriber after atomic creation.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" },
                "examples": {
                  "subscriber": {
                    "value": {
                      "subscriber_id": "user_123",
                      "locale": "es",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_subscriber_created"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/subscribers/{subscriber_id}": {
      "parameters": [
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getSubscriber",
        "summary": "Read one subscriber in the authenticated project environment",
        "tags": ["Subscribers"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Subscriber details and Standard-privacy channel profiles for the requested environment.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "patch": {
        "operationId": "updateSubscriber",
        "summary": "Set a subscriber's display name, forced language or forced time zone",
        "description": "Sets or removes the name your application knows the subscriber by.\nIt is kept on every privacy setting and preferred over the channel's\nown name wherever the subscriber is shown. The operation is naturally\nidempotent. Forced language and canonical IANA time-zone overrides take\nprecedence over application and channel values. Null clears an override.\nDashboard-session writes require an administrator.\n",
        "tags": ["Subscribers"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSubscriberRequest"
              },
              "examples": {
                "displayName": {
                  "value": {
                    "display_name": "Jane Smith",
                    "time_zone_override": "America/Costa_Rica"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The subscriber with its updated display name, forced language or forced time zone.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" },
                "examples": {
                  "subscriber": {
                    "value": {
                      "subscriber_id": "user_123",
                      "display_name": "Jane Smith",
                      "name": "Jane Smith",
                      "locale": "es",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-09-28T18:00:00Z",
                      "diagnostic_id": "diag_subscriber_updated",
                      "time_zone_override": "America/Costa_Rica",
                      "effective_time_zone": "America/Costa_Rica",
                      "time_zone_source": "administrator"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/subscriber-groups": {
      "get": {
        "operationId": "listSubscriberGroups",
        "summary": "List static subscriber groups in the authenticated environment",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous static-group page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Bounded stable page of static groups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "post": {
        "operationId": "createSubscriberGroup",
        "summary": "Create one static subscriber group with an immutable key",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriberGroupRequest"
              },
              "examples": {
                "create": {
                  "value": {
                    "key": "trial-users",
                    "display_name": "Trial users",
                    "description": "Organizations currently evaluating Acme."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created static group.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" },
                "examples": {
                  "group": {
                    "value": {
                      "id": "group_trial_users",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "key": "trial-users",
                      "display_name": "Trial users",
                      "description": "Organizations currently evaluating Acme.",
                      "status": "active",
                      "membership_revision": 1,
                      "row_version": 1,
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_subscriber_group"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/subscriber-groups/{group_key}": {
      "parameters": [
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "get": {
        "operationId": "getSubscriberGroup",
        "summary": "Read one static subscriber group",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Current group metadata and membership revision.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "put": {
        "operationId": "updateSubscriberGroup",
        "summary": "Rename or redescribe an active static group",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSubscriberGroupRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated group with its immutable key.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      },
      "delete": {
        "operationId": "deleteSubscriberGroup",
        "summary": "Delete a subscriber group permanently while retaining its key and history",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "parameters": [
          {
            "name": "stop_broadcasts",
            "in": "query",
            "description": "Stop this group's remaining broadcasts. Already sent messages and provider calls in flight cannot be recalled. Defaults to false, preserving accepted broadcasts.",
            "schema": { "type": "boolean", "default": false }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted group tombstone; repeating the operation is safe.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/subscriber-groups/{group_key}/members": {
      "parameters": [
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "get": {
        "operationId": "listSubscriberGroupMembers",
        "summary": "List active membership generations with bounded pagination",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous membership page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Active member generations at the reported group revision.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupMembershipCollection"
                },
                "examples": {
                  "members": {
                    "value": {
                      "group_key": "trial-users",
                      "membership_revision": 1,
                      "items": [
                        {
                          "group_id": "group_trial_users",
                          "group_key": "trial-users",
                          "subscriber_id": "user_123",
                          "generation": 1,
                          "added_revision": 1,
                          "status": "active",
                          "created_at": "2026-08-22T18:00:00Z",
                          "updated_at": "2026-08-22T18:00:00Z",
                          "diagnostic_id": "diag_n17_group_membership"
                        }
                      ],
                      "page": 1,
                      "page_size": 50,
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/subscriber-groups/{group_key}/members/{subscriber_id}": {
      "parameters": [
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        },
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "put": {
        "operationId": "addSubscriberGroupMember",
        "summary": "Idempotently add one subscriber as a new membership generation",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "responses": {
          "200": {
            "description": "Existing active membership or newly created generation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupMembership"
                },
                "examples": {
                  "membership": {
                    "value": {
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "subscriber_id": "user_123",
                      "generation": 1,
                      "added_revision": 1,
                      "status": "active",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_group_membership"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      },
      "delete": {
        "operationId": "removeSubscriberGroupMember",
        "summary": "Idempotently remove one active membership generation",
        "tags": ["Subscriber groups"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["subscriptions:write"],
        "responses": {
          "204": {
            "description": "The subscriber is absent; repeating removal is a no-op."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/subscriber-groups/{group_key}/broadcasts": {
      "parameters": [
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "post": {
        "operationId": "createGroupBroadcast",
        "summary": "Accept one durable broadcast at the group's current membership revision",
        "description": "Fan-out creates ordinary messages unique by broadcast, subscriber, and\nhistorical membership generation. Adds after acceptance are excluded; removal\nbefore provider attempt skips that generation; re-add creates a new\ngeneration and never revives the old broadcast audience.\n",
        "tags": ["Group broadcasts"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request_and_group_key",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGroupBroadcastRequest"
              },
              "examples": {
                "create": {
                  "value": {
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "Your trial ends tomorrow."
                    },
                    "correlation_id": "trial-ending-2026-08-23",
                    "metadata": { "source": "billing" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Durable broadcast acceptance and snapshotted audience revision.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GroupBroadcast" },
                "examples": {
                  "accepted": {
                    "value": {
                      "id": "broadcast_trial_ending",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "audience_revision": 1,
                      "status": "accepted",
                      "aggregate": {
                        "audience": 1,
                        "expanded": 0,
                        "pending": 1,
                        "provider_accepted": 0,
                        "delivered": 0,
                        "skipped": 0,
                        "failed": 0,
                        "cancelled": 0,
                        "expired": 0
                      },
                      "accepted_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "expires_at": "2026-08-23T18:00:00Z",
                      "diagnostic_id": "diag_n17_broadcast_accepted"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/group-broadcasts/{broadcast_id}": {
      "parameters": [
        {
          "name": "broadcast_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getGroupBroadcast",
        "summary": "Read aggregate expansion and ordinary child-message outcomes",
        "tags": ["Group broadcasts"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Current aggregate projection without a second delivery state machine.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GroupBroadcast" },
                "examples": {
                  "complete": {
                    "value": {
                      "id": "broadcast_trial_ending",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "audience_revision": 1,
                      "status": "complete",
                      "aggregate": {
                        "audience": 1,
                        "expanded": 1,
                        "pending": 0,
                        "provider_accepted": 1,
                        "delivered": 0,
                        "skipped": 0,
                        "failed": 0,
                        "cancelled": 0,
                        "expired": 0
                      },
                      "accepted_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:01:00Z",
                      "expires_at": "2026-08-23T18:00:00Z",
                      "diagnostic_id": "diag_n17_broadcast_complete"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/capabilities": {
      "get": {
        "operationId": "getCapabilities",
        "summary": "Inspect provider-neutral capabilities",
        "tags": ["Capabilities"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["capabilities:read"],
        "responses": {
          "200": {
            "description": "Current stable capability vocabulary and active degradation.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderCapabilitiesCollection"
                },
                "examples": {
                  "providers": {
                    "value": {
                      "schema": "whooshbang.provider-capabilities-collection.v1",
                      "providers": [
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "telegram",
                          "text": { "supported": true, "maximum_bytes": 4096 },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": {
                              "mode": "conditional",
                              "explanation": "Available when the provider returns an exact reply context for the question; otherwise the message is delivered without the control."
                            }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        },
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "slack",
                          "text": { "supported": true, "maximum_bytes": 12000 },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": { "mode": "native" }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        },
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "email",
                          "text": {
                            "supported": true,
                            "maximum_bytes": 100000
                          },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": { "mode": "native" }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        }
                      ],
                      "total": 3
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscription-links": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "post": {
        "operationId": "createSubscriptionLinkInEnvironment",
        "summary": "Create a subscription link in a named project environment",
        "description": "The environment-scoped form of `createSubscriptionLink`, for a caller\nwhose authority selects an organization rather than a project. Behavior,\nrequest, and response are identical; the path names the scope the\ncredential form takes from its bearer, and the service checks it\nagainst the granting person's membership before acting.\n",
        "tags": ["Subscription links"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_organization", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriptionLinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The link was created in the named environment.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionLink" },
                "examples": {
                  "pending": {
                    "value": {
                      "id": "slink_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "channels": ["telegram"],
                      "recipient_language": "es",
                      "connection": {
                        "id": "connection_synthetic_telegram_001",
                        "mode": "whooshbang_shared",
                        "display_name": "WhooshBang",
                        "identity": {
                          "handle": "WhooshBangSyntheticBot",
                          "provider": "telegram"
                        }
                      },
                      "status": "pending",
                      "authorization_url": "https://t.me/WhooshBangSyntheticBot?start=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                      "created_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "diagnostic_id": "diag_link_pending_001"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscription-links/{subscription_link_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/SubscriptionLinkId" }
      ],
      "get": {
        "operationId": "getSubscriptionLinkInEnvironment",
        "summary": "Inspect a subscription link in a named project environment",
        "description": "The environment-scoped form of `getSubscriptionLink`. A link outside the\nnamed environment is absent, exactly as it is for a credential.\n",
        "tags": ["Subscription links"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Current link state and, once completed, its safe binding summary.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriptionLink" },
                "examples": {
                  "activated": {
                    "value": {
                      "id": "slink_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "channels": ["telegram"],
                      "recipient_language": "es",
                      "connection": {
                        "id": "connection_synthetic_telegram_001",
                        "mode": "whooshbang_shared",
                        "display_name": "WhooshBang",
                        "identity": {
                          "handle": "WhooshBangSyntheticBot",
                          "provider": "telegram"
                        }
                      },
                      "status": "activated",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "connection_id": "connection_synthetic_telegram_001",
                        "status": "active"
                      },
                      "created_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:47:00Z",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "diagnostic_id": "diag_link_active_001"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/messages": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listMessagesInEnvironment",
        "summary": "List accepted messages with filters",
        "description": "Content-free message history. Filters combine. accepted_after is inclusive; accepted_before is exclusive. Supply after or page, never both. after accepts the opaque next_after continuation; history intentionally has no total.",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          {
            "in": "query",
            "name": "after",
            "required": false,
            "schema": { "type": "string", "minLength": 1, "maxLength": 2048 }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": { "$ref": "#/components/schemas/ListPageSize" }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": { "$ref": "#/components/schemas/ListPageNumber" }
          },
          {
            "in": "query",
            "name": "connection_id",
            "required": false,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          },
          {
            "in": "query",
            "name": "accepted_after",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "in": "query",
            "name": "accepted_before",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "in": "query",
            "name": "subscriber_id",
            "required": false,
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          },
          {
            "in": "query",
            "name": "state",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": { "$ref": "#/components/schemas/MessageState" }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MessageListPage" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "createMessageInEnvironment",
        "summary": "Create an asynchronous message in a named project environment",
        "description": "The environment-scoped form of `createMessage`. The path names the\norganization, project, and environment the credential form takes from its\nbearer; test and live remain a property of the named environment and are\nnever selected by the request body.\n",
        "tags": ["Messages"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_organization", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateMessageRequest" }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The message was accepted in the named environment.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Message" },
                "examples": {
                  "accepted": {
                    "value": {
                      "id": "msg_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:00Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 0,
                        "highest_proven_provider_state": "none",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_accept_001",
                      "correlation_id": "export_987",
                      "metadata": { "job": "export_987" }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/messages/{message_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/MessageId" }
      ],
      "get": {
        "operationId": "getMessageInEnvironment",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "Inspect a message in a named project environment",
        "description": "The environment-scoped form of `getMessage`, including the same bounded\nlong poll. Inspection acknowledges, consumes, retries, and replays\nnothing.\nNotification grants can read only current operator recipients in their\naudience: self means the signed-in person; team includes current\nteammates with access to this project. Customer subscribers and retired\nmemberships are hidden with 404, including during a held poll.\n",
        "parameters": [
          { "$ref": "#/components/parameters/ResponseInspectionWait" }
        ],
        "tags": ["Messages"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Canonical message state at the moment the read completed.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Message" },
                "examples": {
                  "accepted": {
                    "value": {
                      "id": "msg_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "subscriber_id": "customer_123",
                      "notifier_id": "default",
                      "binding": {
                        "id": "binding_synthetic_001",
                        "project_id": "project_synthetic",
                        "environment": "test",
                        "subscriber_id": "customer_123",
                        "notifier_id": "default",
                        "channel": "telegram",
                        "status": "active"
                      },
                      "delivery_target": "simulator",
                      "state": "provider_accepted",
                      "accepted_at": "2026-07-25T17:45:00Z",
                      "updated_at": "2026-07-25T17:45:02Z",
                      "expires_at": "2026-07-26T17:45:00Z",
                      "delivery": {
                        "attempt_count": 1,
                        "highest_proven_provider_state": "provider_accepted",
                        "retry_scheduled": false
                      },
                      "diagnostic_id": "diag_message_provider_001",
                      "correlation_id": "export_987",
                      "metadata": { "job": "export_987" }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/interactions/{interaction_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/InteractionId" }
      ],
      "get": {
        "operationId": "getInteractionInEnvironment",
        "x-notification-scopes": ["notifications:self", "notifications:team"],
        "summary": "Inspect an interaction response in a named project environment",
        "description": "The environment-scoped form of `getInteraction`, including the same\nbounded long poll and the same retained-answer semantics.\nNotification grants can read only current operator recipients in their\naudience: self means the signed-in person; team includes current\nteammates with access to this project. Customer subscribers and retired\nmemberships are hidden with 404, including during a held poll.\n",
        "parameters": [
          { "$ref": "#/components/parameters/ResponseInspectionWait" }
        ],
        "tags": ["Messages"],
        "security": [
          { "bearerGrant": ["messages:read"] },
          { "bearerGrant": ["notifications:self"] },
          { "bearerGrant": ["notifications:team"] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Canonical interaction state at the moment the read completed.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/InteractionSummary" },
                "examples": {
                  "answered": {
                    "value": {
                      "id": "interaction_synthetic_confirm",
                      "type": "confirm",
                      "state": "answered",
                      "expires_at": "2026-07-25T18:00:00Z",
                      "correlation_id": "request_confirm_001",
                      "answered_at": "2026-07-25T17:47:00Z",
                      "answer_retained": true,
                      "answer": true
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/usage": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "getEnvironmentUsage",
        "summary": "Count an environment's accepted messages per day",
        "description": "One bucket per UTC day from `from` to `to` inclusive, oldest first,\nincluding days with no messages. Each day's `accepted` count comes from\nthe usage ledger, which outlives the messages themselves. Each day's\n`groups` splits the day by `group_by` and comes from the messages, which\nare kept for 90 days; `breakdown_retained_from` says where that window\nstarts.\n\n`to` defaults to today and `from` to 29 days before `to`, so a request\nwith neither returns the last 30 days. A range longer than 366 days,\na `from` after `to`, or a malformed date is `request_invalid`.\n",
        "tags": ["Messages"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "The first UTC day counted, as `YYYY-MM-DD`.",
            "schema": { "$ref": "#/components/schemas/UsageDate" }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "The last UTC day counted, as `YYYY-MM-DD`. Defaults to today.",
            "schema": { "$ref": "#/components/schemas/UsageDate" }
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "description": "What each day's breakdown splits messages by.",
            "schema": { "$ref": "#/components/schemas/UsageGrouping" }
          }
        ],
        "responses": {
          "200": {
            "description": "The environment's accepted messages per day.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/UsageReport" },
                "examples": {
                  "usage": {
                    "value": {
                      "from": "2026-09-26",
                      "to": "2026-09-28",
                      "group_by": "state",
                      "breakdown_retained_from": "2026-06-30",
                      "first_accepted_on": "2026-03-02",
                      "days": [
                        { "day": "2026-09-26", "accepted": 0, "groups": [] },
                        {
                          "day": "2026-09-27",
                          "accepted": 12,
                          "groups": [
                            { "key": "provider_accepted", "count": 11 },
                            { "key": "terminal_failed", "count": 1 }
                          ]
                        },
                        {
                          "day": "2026-09-28",
                          "accepted": 5,
                          "groups": [
                            { "key": "provider_accepted", "count": 3 },
                            { "key": "retry_wait", "count": 2 }
                          ]
                        }
                      ],
                      "totals": {
                        "accepted": 17,
                        "groups": [
                          { "key": "provider_accepted", "count": 14 },
                          { "key": "retry_wait", "count": 2 },
                          { "key": "terminal_failed", "count": 1 }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/machine-clients": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listMachineClientOperations",
        "summary": "Read machine client status and backlog",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["machine-clients:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineClientOperationsList"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "operationId": "createMachineClientInEnvironment",
        "summary": "Create a destination-bound machine client in a named project environment",
        "description": "The environment-scoped form of `createMachineClient`. Scope remains the\nexact bound destination; the path only names where the client is created.\n",
        "tags": ["Machine clients"],
        "security": [
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_organization", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMachineClientRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The machine client was created in the named environment.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineClient" },
                "examples": {
                  "provisioning": {
                    "value": {
                      "id": "machine_client_synthetic_001",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "machine_id": "machine_synthetic_a",
                      "notifier_id": "default",
                      "subscriber_id": "agent_relay_operator",
                      "binding_id": "binding_synthetic_relay",
                      "display_name": "Synthetic local machine",
                      "status": "provisioning",
                      "scope_summary": [
                        "machine-messages:write",
                        "machine-messages:read",
                        "machine-events:read",
                        "machine-events:ack"
                      ],
                      "created_at": "2026-07-25T17:40:00Z",
                      "updated_at": "2026-07-25T17:40:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/machine-clients/{machine_client_id}/credentials": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        { "$ref": "#/components/parameters/MachineClientId" }
      ],
      "post": {
        "operationId": "registerMachineCredentialInEnvironment",
        "summary": "Register a machine-credential digest in a named project environment",
        "description": "The environment-scoped form of `registerMachineCredential`. Registers\nonly the credential ID and SHA-256 digest; the path only names where the\nowning machine client lives. Request and response shapes are that\noperation's exactly, including its published examples.\n",
        "tags": ["Machine clients"],
        "security": [
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterMachineCredentialRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing safe credential metadata on an equivalent registration replay; never secret or digest.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineCredential" }
              }
            }
          },
          "201": {
            "description": "Newly registered safe credential metadata; never secret or digest.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineCredential" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/capabilities": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "getCapabilitiesInEnvironment",
        "summary": "Inspect provider-neutral capabilities for a named project environment",
        "description": "The environment-scoped form of `getCapabilities`. The vocabulary is\nprovider-neutral and identical; the path names the environment whose\nactive degradation is reported.\n",
        "tags": ["Capabilities"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["capabilities:read"],
        "responses": {
          "200": {
            "description": "Current stable capability vocabulary and active degradation.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProviderCapabilitiesCollection"
                },
                "examples": {
                  "providers": {
                    "value": {
                      "schema": "whooshbang.provider-capabilities-collection.v1",
                      "providers": [
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "telegram",
                          "text": { "supported": true, "maximum_bytes": 4096 },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": {
                              "mode": "conditional",
                              "explanation": "Available when the provider returns an exact reply context for the question; otherwise the message is delivered without the control."
                            }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        },
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "slack",
                          "text": { "supported": true, "maximum_bytes": 12000 },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": { "mode": "native" }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        },
                        {
                          "schema": "whooshbang.provider-capabilities.v1",
                          "provider": "email",
                          "text": {
                            "supported": true,
                            "maximum_bytes": 100000
                          },
                          "interaction": {
                            "confirm": { "mode": "native" },
                            "select": { "mode": "native" },
                            "input": { "mode": "native" }
                          },
                          "streaming": { "mode": "final_only" },
                          "edit": { "supported": false },
                          "receipts": {
                            "provider_accepted": true,
                            "delivered": false,
                            "read": false
                          },
                          "contexts": {
                            "private_chat": { "mode": "supported" },
                            "thread": { "mode": "unsupported" },
                            "group": { "mode": "unsupported" }
                          },
                          "rate_limit": {
                            "strategy": "provider_retry_after",
                            "explanation": "Safe provider retry timing is honoured when the provider supplies it."
                          },
                          "degradation": { "active": false }
                        }
                      ],
                      "total": 3
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/email-consent-assertions": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "post": {
        "operationId": "assertEmailConsentInEnvironment",
        "summary": "Assert existing consent for one customer-owned email recipient",
        "description": "Creates or resolves the subscriber and activates the exact binding atomically.\nShared email refuses assertions. Active domain, OAuth, webhook and connection\nauthority are required. Recipient revocation, pause, suppression and holds win.\nIdentical retries return current binding state; changed inputs conflict.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssertEmailConsentRequest"
              },
              "examples": {
                "assertion": {
                  "value": {
                    "subscriber_id": "customer-42",
                    "notifier_id": "updates",
                    "connection_id": "chcon_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "domain_id": "emldom_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                    "address": "User@xn--bcher-kva.example",
                    "consented": true,
                    "consented_at": "2026-09-01T12:00:00.000Z",
                    "source": "account-settings"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The asserted binding with authenticated audit metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/BindingSummary" },
                "examples": {
                  "binding": {
                    "value": {
                      "id": "binding_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      "project_id": "proj_example",
                      "environment": "live",
                      "subscriber_id": "customer-42",
                      "notifier_id": "updates",
                      "channel": "email",
                      "connection_id": "chcon_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      "status": "active",
                      "address": "User@xn--bcher-kva.example",
                      "consent": {
                        "kind": "asserted_prior_consent",
                        "consented_at": "2026-09-01T12:00:00.000Z",
                        "source": "account-settings",
                        "asserted_at": "2026-09-11T12:00:00.000Z",
                        "asserted_by": {
                          "kind": "credential",
                          "id": "cred_example"
                        },
                        "domain_id": "emldom_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscribers": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listSubscribersInEnvironment",
        "summary": "List, search and filter subscribers in a named project environment",
        "description": "The environment-scoped form of `listSubscribers`. Channels, groups and\nactivity are those of the named environment.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous page.",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Prefix or part of a subscriber's ID, display name or kept channel name,\nfrom one character. Matching is case-insensitive; SQL wildcard\ncharacters are literal search input.\n",
            "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
          },
          {
            "name": "channel",
            "in": "query",
            "required": false,
            "description": "Only subscribers reachable on this channel in the environment.",
            "schema": { "$ref": "#/components/schemas/Channel" }
          },
          {
            "name": "connection_id",
            "in": "query",
            "required": false,
            "description": "Only subscribers who connected through this connection.",
            "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          },
          {
            "name": "group",
            "in": "query",
            "required": false,
            "description": "Only current members of the static group with this key, in the\nenvironment asked about. Combines with every other filter, so `q`\nsearches within the group.\n",
            "schema": { "$ref": "#/components/schemas/GroupKey" }
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "active_after",
            "in": "query",
            "required": false,
            "description": "Only subscribers whose `last_activity_at` is at or after this.",
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          },
          {
            "name": "active_before",
            "in": "query",
            "required": false,
            "description": "Only subscribers whose `last_activity_at` is before this.",
            "schema": { "$ref": "#/components/schemas/Timestamp" }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of subscribers, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberCollection"
                },
                "examples": {
                  "subscribers": {
                    "value": {
                      "items": [
                        {
                          "subscriber_id": "user_123",
                          "display_name": "Jane Smith",
                          "name": "Jane Smith",
                          "locale": "es",
                          "channels": ["telegram"],
                          "last_activity_at": "2026-09-28T17:00:00Z",
                          "created_at": "2026-08-22T18:00:00Z",
                          "updated_at": "2026-09-28T18:00:00Z",
                          "diagnostic_id": "diag_subscriber_listed"
                        }
                      ],
                      "next_cursor": "c3Vic2NyaWJlcnNfbmV4dA",
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createSubscriberInEnvironment",
        "summary": "Create a subscriber and initial memberships in a named project environment",
        "description": "The environment-scoped form of `createSubscriber`, for a caller whose\nauthority selects an organization rather than a project. Behavior, request,\nand response are identical; the path names the scope the credential\nform takes from its bearer, and the service checks it against the\npresenting session or grant before acting.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriberRequest"
              },
              "examples": {
                "initialGroups": {
                  "value": {
                    "subscriber_id": "user_123",
                    "locale": "es",
                    "groups": ["organization-updates", "trial-users"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The subscriber after atomic creation.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" },
                "examples": {
                  "subscriber": {
                    "value": {
                      "subscriber_id": "user_123",
                      "locale": "es",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_subscriber_created"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscribers/{subscriber_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getSubscriberInEnvironment",
        "summary": "Read one subscriber in a named project environment",
        "description": "The environment-scoped form of `getSubscriber`. A subscriber outside the\nnamed environment is absent, exactly as it is for a credential.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Subscriber details and Standard-privacy channel profiles for the requested environment.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "patch": {
        "operationId": "updateSubscriberInEnvironment",
        "summary": "Set a subscriber's display name, forced language or forced time zone in a named project environment",
        "description": "The environment-scoped form of `updateSubscriber`. A subscriber outside\nthe named environment's project is absent, exactly as it is for a\ncredential. On a dashboard session it needs an administrator.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSubscriberRequest"
              },
              "examples": {
                "displayName": {
                  "value": {
                    "display_name": "Jane Smith",
                    "time_zone_override": "America/Costa_Rica"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The subscriber with its updated display name, forced language or forced time zone.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Subscriber" },
                "examples": {
                  "subscriber": {
                    "value": {
                      "subscriber_id": "user_123",
                      "display_name": "Jane Smith",
                      "name": "Jane Smith",
                      "locale": "es",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-09-28T18:00:00Z",
                      "diagnostic_id": "diag_subscriber_updated",
                      "time_zone_override": "America/Costa_Rica",
                      "effective_time_zone": "America/Costa_Rica",
                      "time_zone_source": "administrator"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/subscribers/{subscriber_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "delete": {
        "operationId": "eraseSubscriber",
        "summary": "Erase one subscriber across the project",
        "description": "Erases the person represented by this customer-supplied subscriber id\nacross both project environments. Personal content, answers, identities,\nand identifiers are removed while non-identifying delivery and usage\nshells remain. Pending work and old capabilities cannot restore or send\ndata for the erased person.\n\nRepeating the operation is safe, including when the subscriber is already\nabsent. Project-environment credentials cannot call this project-wide\noperation. A provider action that has already begun returns\n`privacy_operation_in_progress` rather than claiming erasure won the race;\nretry after that operation finishes.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": [
          "subscriptions:write",
          "messages:write",
          "machine-clients:write"
        ],
        "x-organization-membership": "required",
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "204": {
            "description": "The subscriber's personal data is erased or was already absent."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/subscribers/{subscriber_id}/data-export": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getSubscriberDataExport",
        "summary": "Export all customer-controlled data held for one subscriber",
        "description": "Returns one complete, machine-readable artifact across every environment\nin the project. `provided_by_subscriber` is the Article 20 portable subset;\nthe three provenance sections together provide the Article 15 access copy.\nWhooshBang-controller audit and service log data is identified as excluded\nand requires a separate recipient request. Project-environment credentials\ncannot call this project-wide operation.\n",
        "tags": ["Subscribers"],
        "security": [
          { "clerkSession": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": [
          "subscriptions:read",
          "messages:read",
          "machine-clients:read"
        ],
        "x-organization-membership": "required",
        "responses": {
          "200": {
            "description": "Complete project-wide customer-controller subscriber data export.",
            "headers": {
              "Content-Disposition": {
                "schema": { "type": "string" },
                "description": "Fixed safe attachment filename."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberDataExport"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscriber-groups": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "listSubscriberGroupsInEnvironment",
        "summary": "List static subscriber groups in a named project environment",
        "description": "The environment-scoped form of `listSubscriberGroups`. The page, its\nbounds, and its cursor are identical; the path names the environment\nwhose groups are listed.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous static-group page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Bounded stable page of static groups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupCollection"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "post": {
        "operationId": "createSubscriberGroupInEnvironment",
        "summary": "Create one static subscriber group in a named project environment",
        "description": "The environment-scoped form of `createSubscriberGroup`. The key is\nimmutable and unique inside the named environment, exactly as it is for\na credential.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriberGroupRequest"
              },
              "examples": {
                "create": {
                  "value": {
                    "key": "trial-users",
                    "display_name": "Trial users",
                    "description": "Organizations currently evaluating Acme."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created static group.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" },
                "examples": {
                  "group": {
                    "value": {
                      "id": "group_trial_users",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "key": "trial-users",
                      "display_name": "Trial users",
                      "description": "Organizations currently evaluating Acme.",
                      "status": "active",
                      "membership_revision": 1,
                      "row_version": 1,
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_subscriber_group"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscriber-groups/{group_key}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "get": {
        "operationId": "getSubscriberGroupInEnvironment",
        "summary": "Read one static subscriber group in a named project environment",
        "description": "The environment-scoped form of `getSubscriberGroup`. A group outside the\nnamed environment is absent, exactly as it is for a credential.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "responses": {
          "200": {
            "description": "Current group metadata and membership revision.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "put": {
        "operationId": "updateSubscriberGroupInEnvironment",
        "summary": "Rename or redescribe an active static group in a named project environment",
        "description": "The environment-scoped form of `updateSubscriberGroup`. The key stays\nimmutable and the row version still guards the write.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSubscriberGroupRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated group with its immutable key.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      },
      "delete": {
        "operationId": "deleteSubscriberGroupInEnvironment",
        "summary": "Delete a subscriber group permanently in a named project environment",
        "description": "The environment-scoped form of `deleteSubscriberGroup`. The key stays\nreserved, accepted broadcasts and membership provenance are preserved,\nand repeating the operation is safe.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "parameters": [
          {
            "name": "stop_broadcasts",
            "in": "query",
            "description": "Stop this group's remaining broadcasts. Already sent messages and provider calls in flight cannot be recalled. Defaults to false, preserving accepted broadcasts.",
            "schema": { "type": "boolean", "default": false }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted group tombstone; repeating the operation is safe.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SubscriberGroup" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscriber-groups/{group_key}/members": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "get": {
        "operationId": "listSubscriberGroupMembersInEnvironment",
        "summary": "List active membership generations in a named project environment",
        "description": "The environment-scoped form of `listSubscriberGroupMembers`. Removed\ngenerations stay internal here too; only current active members are\npublished.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:read"],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from the previous membership page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Active member generations at the reported group revision.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupMembershipCollection"
                },
                "examples": {
                  "members": {
                    "value": {
                      "group_key": "trial-users",
                      "membership_revision": 1,
                      "items": [
                        {
                          "group_id": "group_trial_users",
                          "group_key": "trial-users",
                          "subscriber_id": "user_123",
                          "generation": 1,
                          "added_revision": 1,
                          "status": "active",
                          "created_at": "2026-08-22T18:00:00Z",
                          "updated_at": "2026-08-22T18:00:00Z",
                          "diagnostic_id": "diag_n17_group_membership"
                        }
                      ],
                      "page": 1,
                      "page_size": 50,
                      "total": 1
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscriber-groups/{group_key}/members/{subscriber_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        },
        {
          "name": "subscriber_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "put": {
        "operationId": "addSubscriberGroupMemberInEnvironment",
        "summary": "Idempotently add one subscriber in a named project environment",
        "description": "The environment-scoped form of `addSubscriberGroupMember`. A subscriber\nthat does not already exist in the named environment is absent; this\noperation creates memberships, never subscribers.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "responses": {
          "200": {
            "description": "Existing active membership or newly created generation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriberGroupMembership"
                },
                "examples": {
                  "membership": {
                    "value": {
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "subscriber_id": "user_123",
                      "generation": 1,
                      "added_revision": 1,
                      "status": "active",
                      "created_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "diagnostic_id": "diag_n17_group_membership"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      },
      "delete": {
        "operationId": "removeSubscriberGroupMemberInEnvironment",
        "summary": "Idempotently remove one active membership in a named project environment",
        "description": "The environment-scoped form of `removeSubscriberGroupMember`. Removal\nstops not-yet-attempted broadcast children and is a no-op for a\nsubscriber that is already absent.\n",
        "tags": ["Subscriber groups"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["subscriptions:write"],
        "responses": {
          "204": {
            "description": "The subscriber is absent; repeating removal is a no-op."
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/subscriber-groups/{group_key}/broadcasts": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "group_key",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/GroupKey" }
        }
      ],
      "post": {
        "operationId": "createGroupBroadcastInEnvironment",
        "summary": "Accept one durable broadcast in a named project environment",
        "description": "The environment-scoped form of `createGroupBroadcast`. Fan-out,\naudience snapshotting, and child-message uniqueness are identical; test\nand live remain a property of the named environment and are never\nselected by the request body.\n",
        "tags": ["Group broadcasts"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_project_environment", "operation_id", "key"],
          "equivalence": "validated_request_and_group_key",
          "replay_retention_extends": false
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGroupBroadcastRequest"
              },
              "examples": {
                "create": {
                  "value": {
                    "notifier_id": "default",
                    "content": {
                      "type": "text",
                      "text": "Your trial ends tomorrow."
                    },
                    "correlation_id": "trial-ending-2026-08-23",
                    "metadata": { "source": "billing" }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Durable broadcast acceptance and snapshotted audience revision.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GroupBroadcast" },
                "examples": {
                  "accepted": {
                    "value": {
                      "id": "broadcast_trial_ending",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "audience_revision": 1,
                      "status": "accepted",
                      "aggregate": {
                        "audience": 1,
                        "expanded": 0,
                        "pending": 1,
                        "provider_accepted": 0,
                        "delivered": 0,
                        "skipped": 0,
                        "failed": 0,
                        "cancelled": 0,
                        "expired": 0
                      },
                      "accepted_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:00:00Z",
                      "expires_at": "2026-08-23T18:00:00Z",
                      "diagnostic_id": "diag_n17_broadcast_accepted"
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/group-broadcasts/{broadcast_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "name": "broadcast_id",
          "in": "path",
          "required": true,
          "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        }
      ],
      "get": {
        "operationId": "getGroupBroadcastInEnvironment",
        "summary": "Read aggregate expansion and child outcomes in a named project environment",
        "description": "The environment-scoped form of `getGroupBroadcast`. The aggregate is the\nsame projection over expansion and ordinary child message states; a\nbroadcast outside the named environment is absent.\n",
        "tags": ["Group broadcasts"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Current aggregate projection without a second delivery state machine.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GroupBroadcast" },
                "examples": {
                  "complete": {
                    "value": {
                      "id": "broadcast_trial_ending",
                      "project_id": "project_synthetic",
                      "environment": "test",
                      "group_id": "group_trial_users",
                      "group_key": "trial-users",
                      "audience_revision": 1,
                      "status": "complete",
                      "aggregate": {
                        "audience": 1,
                        "expanded": 1,
                        "pending": 0,
                        "provider_accepted": 1,
                        "delivered": 0,
                        "skipped": 0,
                        "failed": 0,
                        "cancelled": 0,
                        "expired": 0
                      },
                      "accepted_at": "2026-08-22T18:00:00Z",
                      "updated_at": "2026-08-22T18:01:00Z",
                      "expires_at": "2026-08-23T18:00:00Z",
                      "diagnostic_id": "diag_n17_broadcast_complete"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/messages/{message_id}/delivery": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "message_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "get": {
        "operationId": "getMessageDeliveryHistory",
        "summary": "Read delivery history and retained content",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageDeliveryHistory"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/messages/{message_id}/image": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "message_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "get": {
        "operationId": "getMessageNotificationImage",
        "summary": "Read the retained notification image",
        "description": "Returns canonical PNG bytes as bounded base64 JSON for faithful preview. Accessible only through an authorized retained message, never by an arbitrary asset ID. Purged content or unavailable pixels return404.",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageNotificationImage"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/interactions/{interaction_id}/timeline": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "interaction_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "get": {
        "operationId": "getInteractionTimeline",
        "summary": "Read interaction history and retained answer",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/InteractionTimeline" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/channel-connections/{connection_id}/sender": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "connection_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "post": {
        "operationId": "updateEmailSender",
        "summary": "Change a customer email domain sender name",
        "description": "Customer-owned email-domain connections only. Dashboard sessions require an administrator. row_version prevents overwriting a concurrent edit.",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["connections:write"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmailSenderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ChannelConnection" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-events/{event_id}/attempts": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "event_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "get": {
        "operationId": "getCustomerEventDeliveryHistory",
        "summary": "Read customer event delivery attempts",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEventDeliveryHistory"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/customer-events/{event_id}/attempts/{attempt_id}/replay": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "event_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        },
        {
          "in": "path",
          "name": "attempt_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        }
      ],
      "post": {
        "operationId": "replayCustomerEventAttempt",
        "summary": "Schedule a recorded customer event attempt again",
        "description": "Schedules a fresh delivery sequence for an eligible recorded attempt. Dashboard sessions require an administrator. The event content and endpoint secret are never returned.",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:write"],
        "responses": {
          "202": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEventDeliveryAttempt"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/delivery-holds": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" }
      ],
      "get": {
        "operationId": "getDeliveryHolds",
        "summary": "Read delivery holds",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DeliveryHolds" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/environments/{environment_id}/machine-clients/{machine_client_id}/revoke": {
      "parameters": [
        { "$ref": "#/components/parameters/ProjectId" },
        { "$ref": "#/components/parameters/EnvironmentId" },
        {
          "in": "path",
          "name": "machine_client_id",
          "required": true,
          "schema": { "type": "string", "minLength": 1, "maxLength": 128 }
        },
        { "$ref": "#/components/parameters/IdempotencyKey" }
      ],
      "post": {
        "operationId": "revokeMachineClientInEnvironment",
        "summary": "Revoke a machine client and its credentials",
        "description": "Irreversibly revokes the client and its credentials; existing unacknowledged events remain retained. Requires an administrator on a dashboard session and an idempotency key. A replay returns the original revocation.",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["machine-clients:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "validated_request_after_documented_defaults",
          "replay_retention_extends": false
        },
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MachineClient" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/projects/{project_id}/recipient-copy-catalogue": {
      "parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
      "get": {
        "operationId": "getRecipientCopyCatalogue",
        "summary": "Read every recipient text in one language",
        "tags": ["Administration"],
        "security": [
          { "clerkSession": [] },
          { "bearerCredential": [] },
          { "bearerGrant": [] },
          { "bearerOrganizationCredential": [] }
        ],
        "x-required-scopes": ["projects:read"],
        "parameters": [
          {
            "in": "query",
            "name": "language",
            "required": false,
            "schema": { "$ref": "#/components/schemas/RecipientLanguage" }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientCopyCatalogue"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/operator-messages": {
      "post": {
        "operationId": "sendOperatorMessageWithCredential",
        "summary": "sendOperatorMessage",
        "description": "Message a current teammate by name or operator ID. Personal callers may omit recipient or use me. Shared credentials must name a recipient. Runtime machine credentials report recipient_required for omitted or me; named operator sends are forbidden because runtime authority remains subscriber-bound.",
        "tags": ["Operators"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOperatorMessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OperatorMessageResult"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/operators/broadcasts": {
      "post": {
        "operationId": "broadcastOperatorsWithCredential",
        "summary": "broadcastOperators",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGroupBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorBroadcast" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/operators/broadcasts/{broadcast_id}": {
      "get": {
        "operationId": "getOperatorBroadcastWithCredential",
        "summary": "getOperatorBroadcast",
        "description": "Membership-derived operator messaging. Only the authenticated human can manage personal preferences.",
        "tags": ["Operators"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          {
            "name": "broadcast_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized result.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperatorBroadcast" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/v1/customer-endpoints": {
      "get": {
        "operationId": "listCustomerEndpointsWithCredential",
        "summary": "List safe customer-endpoint health metadata",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Safe endpoint lifecycle and health metadata without URLs or protected content.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointCollection"
                },
                "examples": {
                  "endpoints": {
                    "value": {
                      "items": [
                        {
                          "id": "endpoint_11111111111111111111111111111111",
                          "project_id": "project_synthetic_alpha",
                          "environment_id": "environment_test_synthetic_alpha",
                          "environment": "test",
                          "status": "active",
                          "verification_status": "verified",
                          "event_types": [
                            "interaction.received",
                            "message.delivered"
                          ],
                          "secret_version": 2,
                          "health": "failing",
                          "created_at": "2026-08-06T12:00:00.000Z",
                          "updated_at": "2026-08-06T14:00:00.000Z",
                          "verification_attempted_at": "2026-08-06T12:05:00.000Z",
                          "verified_at": "2026-08-06T12:05:00.000Z",
                          "rotated_at": "2026-08-06T13:00:00.000Z",
                          "last_success_at": "2026-08-06T13:30:00.000Z",
                          "last_failure": {
                            "at": "2026-08-06T14:00:00.000Z",
                            "category": "network_failure"
                          },
                          "diagnostic_id": "diag_endpoint_list_001"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "post": {
        "operationId": "createCustomerEndpointWithCredential",
        "summary": "Create an active customer endpoint and reveal its signing secret once",
        "description": "Creates an active endpoint and sends a signed diagnostic ping. A 2xx acknowledges the ping; no echo handshake is required. SSRF destination validation applies.",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "final_normalized_url_and_validated_request",
          "replay_retention_extends": false
        },
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerEndpointRequest"
              },
              "examples": {
                "createEndpoint": {
                  "value": {
                    "url": "https://events.example.com/whooshbang",
                    "event_types": [
                      "interaction.received",
                      "message.delivered"
                    ],
                    "local_test": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Equivalent replay returning safe endpoint metadata without the secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "replayed": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "unverified",
                        "verification_status": "pending",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 1,
                        "health": "never_delivered",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T12:00:00.000Z",
                        "diagnostic_id": "diag_endpoint_replay_001"
                      }
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Newly active endpoint, recorded signed ping result, and its one-time signing secret.",
            "headers": {
              "WhooshBang-Diagnostic-Id": {
                "$ref": "#/components/headers/DiagnosticId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "created": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "unverified",
                        "verification_status": "pending",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 1,
                        "health": "never_delivered",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T12:00:00.000Z",
                        "diagnostic_id": "diag_endpoint_create_001"
                      },
                      "secret": "whsec_AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/customer-endpoints/{endpoint_id}": {
      "parameters": [{ "$ref": "#/components/parameters/CustomerEndpointId" }],
      "get": {
        "operationId": "getCustomerEndpointWithCredential",
        "summary": "Read safe lifecycle and health metadata for one endpoint",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "responses": {
          "200": {
            "description": "Safe endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/v1/customer-endpoints/{endpoint_id}/verify": {
      "parameters": [{ "$ref": "#/components/parameters/CustomerEndpointId" }],
      "post": {
        "operationId": "verifyCustomerEndpointWithCredential",
        "summary": "Send a signed test ping and record whether the receiver returns 2xx",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "responses": {
          "200": {
            "description": "Verified active endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "502": { "$ref": "#/components/responses/ProviderTerminal" },
          "503": { "$ref": "#/components/responses/ProviderRetryable" }
        }
      }
    },
    "/v1/customer-endpoints/{endpoint_id}/rotate": {
      "parameters": [{ "$ref": "#/components/parameters/CustomerEndpointId" }],
      "post": {
        "operationId": "rotateCustomerEndpointWithCredential",
        "summary": "Create a new signing version with bounded old/new overlap",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-idempotency": {
          "required": false,
          "retention_seconds": 604800,
          "scope": ["authenticated_environment", "operation_id", "key"],
          "equivalence": "endpoint_and_validated_request",
          "replay_retention_extends": false
        },
        "x-secret-reveal": {
          "responses": 1,
          "replayable": false,
          "later_reads": "metadata_only"
        },
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RotateCustomerEndpointRequest"
              },
              "examples": { "rotate": { "value": { "overlap_seconds": 3600 } } }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Equivalent replay without another secret reveal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                }
              }
            }
          },
          "201": {
            "description": "Rotated endpoint and one-time new secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointMutationResult"
                },
                "examples": {
                  "rotated": {
                    "value": {
                      "endpoint": {
                        "id": "endpoint_11111111111111111111111111111111",
                        "project_id": "project_synthetic_alpha",
                        "environment_id": "environment_test_synthetic_alpha",
                        "environment": "test",
                        "status": "active",
                        "verification_status": "verified",
                        "event_types": [
                          "interaction.received",
                          "message.delivered"
                        ],
                        "secret_version": 2,
                        "health": "healthy",
                        "created_at": "2026-08-06T12:00:00.000Z",
                        "updated_at": "2026-08-06T13:00:00.000Z",
                        "verification_attempted_at": "2026-08-06T12:05:00.000Z",
                        "verified_at": "2026-08-06T12:05:00.000Z",
                        "rotated_at": "2026-08-06T13:00:00.000Z",
                        "last_success_at": "2026-08-06T12:30:00.000Z",
                        "diagnostic_id": "diag_endpoint_rotate_001"
                      },
                      "secret": "whsec_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/EndpointRotationConflict" }
        }
      }
    },
    "/v1/customer-endpoints/{endpoint_id}/{action}": {
      "parameters": [
        { "$ref": "#/components/parameters/CustomerEndpointId" },
        {
          "name": "action",
          "in": "path",
          "required": true,
          "schema": { "type": "string", "enum": ["pause", "resume", "disable"] }
        }
      ],
      "post": {
        "operationId": "transitionCustomerEndpointWithCredential",
        "summary": "Pause, resume, or terminally disable an endpoint",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:write"],
        "x-repeat-semantics": {
          "same_target": "idempotent",
          "secret_returned": false
        },
        "responses": {
          "200": {
            "description": "Updated safe endpoint metadata.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CustomerEndpoint" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        },
        "description": "Creates an active endpoint and sends a signed diagnostic ping. A 2xx acknowledges the ping; no echo handshake is required. SSRF destination validation applies."
      }
    },
    "/v1/customer-endpoints/{endpoint_id}/attempts": {
      "parameters": [{ "$ref": "#/components/parameters/CustomerEndpointId" }],
      "get": {
        "operationId": "listCustomerEndpointAttemptsWithCredential",
        "summary": "Inspect protected content-free delivery diagnostics",
        "tags": ["Customer endpoints"],
        "security": [{ "bearerCredential": [] }],
        "x-required-scopes": ["messages:read"],
        "parameters": [
          { "$ref": "#/components/parameters/ListAfterCursor" },
          { "$ref": "#/components/parameters/ListPageLimit" },
          { "$ref": "#/components/parameters/PageNumber" }
        ],
        "responses": {
          "200": {
            "description": "Safe status, timing, and failure categories only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerEndpointAttemptCollection"
                },
                "examples": {
                  "attempts": {
                    "value": {
                      "endpoint_id": "endpoint_11111111111111111111111111111111",
                      "attempts": [
                        {
                          "id": "ceattempt_11111111111111111111111111111111",
                          "event_id": "evt_interaction_received_synthetic",
                          "attempt": 1,
                          "status": "terminal_failed",
                          "diagnostic_code": "network_failure",
                          "started_at": "2026-08-06T14:00:00.000Z",
                          "completed_at": "2026-08-06T14:00:01.000Z",
                          "created_at": "2026-08-06T14:00:00.000Z"
                        }
                      ],
                      "total": 1,
                      "page": 1,
                      "page_size": 50
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "clerkSession": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Clerk session JWT",
        "description": "A verified human session whose active Clerk organization selects exactly\none WhooshBang organization. Every administration operation rechecks the\nprojected organization membership; session identity never selects a project\nor environment from request data.\n"
      },
      "bearerGrant": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "OAuth 2.0 access token",
        "description": "An access token issued by the WhooshBang authorization server for one\nconsenting organization member. It selects exactly one organization and carries\nthe scopes that member consented to, and never a project: an operation\nnames its project and environment in the path, and the service checks\nboth against the granting person's membership before acting. A project\ncredential can name no project but its own; an organization credential names\none per call the same way this does.\n"
      },
      "bearerOrganizationCredential": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wb_oc1.ocred_<16-byte-base64url>.<32-byte-base64url-secret>",
        "description": "Selects exactly one organization and nothing below it. It names no project\nand no environment, so it authenticates only operations whose path does,\nand its authority there is the intersection of its scopes with the\nproject-credential vocabulary — never wider than a project credential\nwould have been for the same project environment. A path naming a\nproject outside its organization is refused with `credential_organization_mismatch`\nrather than a bare scope failure. `organization:read` is the one scope it can\nhold that a project credential cannot, and it authorizes only the\norganization's project directory: listing the organization's projects and reading\none, which is the organization-wide question a project credential cannot ask\nand the reason a `--project <slug>` selector can work at all. It is\nrequired *in addition to* each of those operations' own\n`x-required-scopes`, never instead of them.\nCredentials cannot be read after creation.\n"
      },
      "bearerCredential": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wb_pc1.pcred_<16-byte-base64url>.<32-byte-base64url-secret>",
        "description": "Selects exactly one organization, project, and `test` or `live` environment.\nCredentials cannot be read after creation. Except for explicitly\nsynthetic creation/rotation reveal fixtures, complete bearer values\nmust never appear in fixtures, errors, logs, metrics, or inspection\nsurfaces.\n"
      },
      "machineCredential": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "wb_mc1.mcred_<16-byte-base64url>.<32-byte-base64url-secret>",
        "description": "A locally generated runtime credential bound server-side to exactly one\nproject/environment, machine client, notifier, subscriber, binding, and\nevent stream. Project credentials cannot use machine-only endpoints.\nRevoked credentials fail before resource lookup.\n"
      },
      "recipientSessionCapability": {
        "type": "apiKey",
        "in": "header",
        "name": "WhooshBang-Recipient-Capability",
        "description": "A creation-only, short-lived capability bound server-side to one exact\norganization, project, environment, subscriber, configuration revision,\npresenting origin, and registered return destination. It is accepted\nonly on the `/v1/recipient-session` browser surface and never as bearer\nauthority on an ordinary application route.\n"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Optional visible ASCII key retained for seven days from first acceptance.\nA retry with the same key returns the original result and never acts twice.\nWithout a key each request is new.\nEquivalent replay returns the original status and logical resource;\nmaterially different validated input returns `idempotency_conflict`.\n",
        "schema": { "$ref": "#/components/schemas/IdempotencyKey" }
      },
      "SubscriptionLinkId": {
        "name": "subscription_link_id",
        "in": "path",
        "required": true,
        "description": "Opaque subscription-link identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "ProjectId": {
        "name": "project_id",
        "in": "path",
        "required": true,
        "description": "Opaque project identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "EnvironmentId": {
        "name": "environment_id",
        "in": "path",
        "required": true,
        "description": "Opaque project-environment identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "ApiCredentialId": {
        "name": "credential_id",
        "in": "path",
        "required": true,
        "description": "Canonical opaque project credential identity; never a readable secret.",
        "schema": { "$ref": "#/components/schemas/ApiCredentialId" }
      },
      "OrganizationCredentialId": {
        "name": "organization_credential_id",
        "in": "path",
        "required": true,
        "description": "Canonical opaque organization credential identity; never a readable secret.",
        "schema": { "$ref": "#/components/schemas/OrganizationCredentialId" }
      },
      "ApiCredentialAfterCursor": {
        "name": "after",
        "in": "query",
        "required": false,
        "description": "Opaque cursor returned by the previous credential page.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "^[A-Za-z0-9_-]+$"
        }
      },
      "ApiCredentialPageLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum credential metadata records returned in one page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "ListAfterCursor": {
        "name": "after",
        "in": "query",
        "required": false,
        "description": "Opaque cursor returned by the previous page of this list.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "^[A-Za-z0-9_-]+$"
        }
      },
      "ListPageLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum records returned in one page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "PageNumber": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "1-based page number, for a caller showing a person where they are in a\nlist rather than walking the whole set. Mutually exclusive with\n`after`: sending both is `request_invalid`, because a cursor and a page\nnumber are two different answers to \"which records next\". A page past\nthe end of the list is an empty page, not an error.\n\nWhat is bounded is the row the page starts at, not the page number.\n`(page - 1) * limit` may not exceed 50,000 — the deepest row any\npublished list ceiling reaches — and a request past that is\n`request_invalid`. So every row of every list stays addressable\nwhatever page size the caller chose.\n",
        "schema": { "$ref": "#/components/schemas/ListPageNumber" }
      },
      "ProjectAfterCursor": {
        "name": "after",
        "in": "query",
        "required": false,
        "description": "Opaque cursor returned by the previous project page.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "^[A-Za-z0-9_-]+$"
        }
      },
      "ProjectPageLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum projects returned in one page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "MessageId": {
        "name": "message_id",
        "in": "path",
        "required": true,
        "description": "Opaque logical message identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "NotificationImageAssetId": {
        "name": "asset_id",
        "in": "path",
        "required": true,
        "description": "Opaque immutable notification-image version identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/NotificationImageAssetId" }
      },
      "InteractionId": {
        "name": "interaction_id",
        "in": "path",
        "required": true,
        "description": "Opaque interaction identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "MachineClientId": {
        "name": "machine_client_id",
        "in": "path",
        "required": true,
        "description": "Opaque machine-client identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "MachineCredentialId": {
        "name": "credential_id",
        "in": "path",
        "required": true,
        "description": "Canonical opaque credential identifier; never a readable secret.",
        "schema": { "$ref": "#/components/schemas/MachineCredentialId" }
      },
      "MachineEventId": {
        "name": "event_id",
        "in": "path",
        "required": true,
        "description": "Opaque event identity constrained to the authenticated machine stream.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "ChannelConnectionId": {
        "name": "connection_id",
        "in": "path",
        "required": true,
        "description": "Opaque connection identity; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "ConnectionTestId": {
        "name": "test_id",
        "in": "path",
        "required": true,
        "description": "Opaque identity of one owner-triggered connection test; never authorization.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "NotifierId": {
        "name": "notifier_id",
        "in": "path",
        "required": true,
        "description": "The notifier whose routing is being changed, as `default_notifier.id` on the project environment reports it. This is the notifier's own identity, not the `notifier_id` reference a send carries.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "CustomerEndpointId": {
        "name": "endpoint_id",
        "in": "path",
        "required": true,
        "description": "Opaque endpoint identity; never authorization and never a URL.",
        "schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
      },
      "MachineAfterCursor": {
        "name": "after",
        "in": "query",
        "required": false,
        "description": "Exact atomically committed cursor returned by the previous successful\npoll or acknowledgement. Omit only for the first poll. A foreign,\nunknown, or known-but-uncommitted cursor fails closed and cannot rewind\nthe stream.\n",
        "schema": { "$ref": "#/components/schemas/MachineCursor" }
      },
      "MachinePollWait": {
        "name": "wait",
        "in": "query",
        "required": false,
        "description": "Bounded server hold time in seconds.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 30,
          "default": 30
        }
      },
      "ResponseInspectionWait": {
        "name": "wait",
        "in": "query",
        "required": false,
        "description": "Bounded server hold time in whole seconds. Omission defaults to 30;\nzero requests an immediate read. A wait that expires returns the\ncurrent resource successfully rather than a timeout problem.\n",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 30,
          "default": 30
        }
      },
      "MachinePollLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum stable-ordered events returned.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 50,
          "default": 25
        }
      }
    },
    "headers": {
      "DiagnosticId": {
        "description": "Safe public correlation identifier for protected diagnostics.",
        "schema": { "$ref": "#/components/schemas/DiagnosticId" }
      }
    },
    "schemas": {
      "MessageCategoryKey": {
        "type": "string",
        "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$",
        "minLength": 1,
        "maxLength": 63
      },
      "MessageCategory": {
        "type": "object",
        "description": "One project-owned category. Its key stays stable when settings change.",
        "required": [
          "key",
          "name",
          "description",
          "purpose",
          "level",
          "can_turn_off",
          "is_default"
        ],
        "properties": {
          "key": { "$ref": "#/components/schemas/MessageCategoryKey" },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "description": { "type": "string", "minLength": 1, "maxLength": 160 },
          "purpose": { "enum": ["service", "marketing"] },
          "level": { "enum": ["low", "normal", "high", "critical"] },
          "can_turn_off": { "type": "boolean" },
          "is_default": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "MessageCategoryCollection": {
        "type": "object",
        "required": ["items", "total"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/MessageCategory" }
          },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "CreateMessageCategoryRequest": {
        "type": "object",
        "required": [
          "key",
          "name",
          "description",
          "purpose",
          "level",
          "can_turn_off"
        ],
        "properties": {
          "key": { "$ref": "#/components/schemas/MessageCategoryKey" },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "description": { "type": "string", "minLength": 1, "maxLength": 160 },
          "purpose": { "enum": ["service", "marketing"] },
          "level": { "enum": ["low", "normal", "high", "critical"] },
          "can_turn_off": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "UpdateMessageCategoryRequest": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "description": { "type": "string", "minLength": 1, "maxLength": 160 },
          "purpose": { "enum": ["service", "marketing"] },
          "level": { "enum": ["low", "normal", "high", "critical"] },
          "can_turn_off": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "SubscriberCategoryPreference": {
        "type": "object",
        "required": [
          "key",
          "name",
          "description",
          "purpose",
          "level",
          "can_turn_off",
          "is_default",
          "enabled"
        ],
        "properties": {
          "key": { "$ref": "#/components/schemas/MessageCategoryKey" },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "description": { "type": "string", "minLength": 1, "maxLength": 160 },
          "purpose": { "enum": ["service", "marketing"] },
          "level": { "enum": ["low", "normal", "high", "critical"] },
          "can_turn_off": { "type": "boolean" },
          "is_default": { "type": "boolean" },
          "enabled": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "SubscriberCategoryPreferenceCollection": {
        "type": "object",
        "required": ["items", "total"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/SubscriberCategoryPreference"
            }
          },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "SetSubscriberCategoryPreferenceRequest": {
        "type": "object",
        "required": ["enabled"],
        "properties": { "enabled": { "type": "boolean" } },
        "additionalProperties": false
      },
      "WhoAmI": {
        "type": "object",
        "description": "Current principal, authorized context, safe channel readiness and deterministic personal me identity. Contains no email or provider destination.",
        "required": ["principal", "context", "capabilities", "detail"],
        "properties": {
          "principal": {
            "type": "object",
            "description": "The credential actually authenticated for this request; service identity never implies its creator is the recipient.",
            "required": ["type", "id"],
            "properties": {
              "type": {
                "enum": [
                  "personal_session",
                  "personal_mcp",
                  "project_credential",
                  "organization_credential",
                  "machine_client"
                ]
              },
              "id": { "type": "string", "minLength": 1, "maxLength": 128 }
            },
            "additionalProperties": false
          },
          "context": {
            "type": "object",
            "description": "Explicit authorized account and project context. No context is guessed across tenants.",
            "required": [
              "organization_id",
              "project_id",
              "environment_id",
              "environment"
            ],
            "properties": {
              "organization_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128
              },
              "project_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128
              },
              "environment_id": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128
              },
              "environment": { "enum": ["test", "live"] }
            },
            "additionalProperties": false
          },
          "capabilities": {
            "type": "object",
            "description": "Current messaging permissions; quota, binding readiness and provider gates still apply per send.",
            "required": [
              "can_message_self",
              "can_message_teammates",
              "can_broadcast_operators"
            ],
            "properties": {
              "can_message_self": { "type": "boolean" },
              "can_message_teammates": { "type": "boolean" },
              "can_broadcast_operators": { "type": "boolean" }
            },
            "additionalProperties": false
          },
          "user": {
            "type": "object",
            "description": "Verified authenticated human identity. Absent for shared/service credentials.",
            "required": ["id", "name"],
            "properties": {
              "id": { "type": "string", "minLength": 1, "maxLength": 128 },
              "name": { "type": "string", "minLength": 1, "maxLength": 256 }
            },
            "additionalProperties": false
          },
          "me": { "$ref": "#/components/schemas/Operator" },
          "detail": { "type": "string", "minLength": 1, "maxLength": 1024 }
        },
        "additionalProperties": false
      },
      "Operator": {
        "type": "object",
        "description": "A safe, membership-derived operator in the authorized project. No email, provider identifiers or credentials are exposed.",
        "required": ["id", "name", "role", "readiness", "preferences_url"],
        "properties": {
          "id": { "type": "string", "minLength": 1, "maxLength": 128 },
          "name": { "type": "string", "minLength": 1, "maxLength": 256 },
          "role": { "enum": ["admin", "member", "messenger"] },
          "readiness": { "enum": ["ready", "channel_unavailable"] },
          "preferred_channel": { "$ref": "#/components/schemas/Channel" },
          "preferences_url": { "type": "string", "format": "uri" },
          "setup_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "An actionable platform setup reason when the default shared email setup is missing, ambiguous or unavailable."
          }
        },
        "additionalProperties": false
      },
      "OperatorCollection": {
        "type": "object",
        "description": "Read-only predefined operators audience, filtered to current account and project membership.",
        "required": ["group", "items", "total"],
        "properties": {
          "group": { "const": "operators" },
          "items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Operator" }
          },
          "total": { "$ref": "#/components/schemas/ListTotal" },
          "next_cursor": { "type": "string", "minLength": 1, "maxLength": 128 },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" }
        },
        "additionalProperties": false
      },
      "OperatorResolution": {
        "type": "object",
        "description": "Exact normalized name or stable operator identity. Duplicate names are never guessed.",
        "required": ["outcome", "choices"],
        "properties": {
          "outcome": { "enum": ["resolved", "ambiguous", "not_found"] },
          "choices": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Operator" }
          }
        },
        "additionalProperties": false
      },
      "CreateOperatorMessageRequest": {
        "type": "object",
        "description": "Send to a teammate by exact name or operator ID, or use me. Omitted recipient means the verified authenticated human only. Shared and service credentials must name a recipient. Preferred channel, service-email billing and marketing restrictions still apply.",
        "required": [],
        "properties": {
          "recipient": { "type": "string", "minLength": 1, "maxLength": 128 },
          "content": { "$ref": "#/components/schemas/MessageContentInput" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "Optional server-authoritative expiry after acceptance, through year 9999. Omit for 24 hours."
          },
          "correlation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "metadata": { "$ref": "#/components/schemas/Metadata" },
          "interaction": {
            "$ref": "#/components/schemas/InteractionSendRequest"
          },
          "purpose": {
            "enum": ["service", "marketing"],
            "default": "service",
            "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
          },
          "category_key": {
            "$ref": "#/components/schemas/MessageCategoryKey",
            "description": "Optional project category. Omitted service sends use Updates; omitted marketing sends use Marketing."
          }
        },
        "additionalProperties": false,
        "allOf": [
          {
            "anyOf": [
              {
                "required": ["content"],
                "properties": {
                  "content": {
                    "$ref": "#/components/schemas/MessageContentInput"
                  }
                },
                "additionalProperties": true
              },
              {
                "required": ["interaction"],
                "properties": {
                  "interaction": {
                    "$ref": "#/components/schemas/InteractionSendRequest"
                  }
                },
                "additionalProperties": true
              }
            ]
          }
        ]
      },
      "OperatorMessageResult": {
        "type": "object",
        "description": "Readable acceptance or refusal. Accepted means queued, never proof of provider delivery.",
        "required": ["outcome", "choices", "detail"],
        "properties": {
          "outcome": {
            "enum": [
              "accepted",
              "ambiguous",
              "not_found",
              "recipient_required",
              "channel_unavailable"
            ]
          },
          "choices": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Operator" }
          },
          "detail": { "type": "string", "minLength": 1, "maxLength": 1024 },
          "message": { "$ref": "#/components/schemas/Message" },
          "preferences_url": { "type": "string", "format": "uri" }
        },
        "additionalProperties": false
      },
      "OperatorBroadcastRecipient": {
        "type": "object",
        "description": "Per-person broadcast result. Sent requires provider acceptance; skipped includes removed membership or an unavailable destination.",
        "required": ["operator_id", "outcome"],
        "properties": {
          "operator_id": { "type": "string", "minLength": 1, "maxLength": 128 },
          "name": { "type": "string" },
          "outcome": { "enum": ["pending", "sent", "skipped", "failed"] },
          "message_id": { "type": "string", "minLength": 1, "maxLength": 128 },
          "reason": { "type": "string" }
        },
        "additionalProperties": false
      },
      "OperatorBroadcast": {
        "type": "object",
        "description": "Durable operators broadcast using ordinary child messages and charging. Read again for provider outcomes.",
        "required": ["broadcast", "recipients"],
        "properties": {
          "broadcast": { "$ref": "#/components/schemas/GroupBroadcast" },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OperatorBroadcastRecipient"
            }
          }
        },
        "additionalProperties": false
      },
      "OperatorPreferences": {
        "type": "object",
        "description": "The authenticated person’s own destinations and preferred channel in this project. Shared credentials cannot manage a human’s preferences.",
        "required": ["operator", "settings", "connections"],
        "properties": {
          "operator": { "$ref": "#/components/schemas/Operator" },
          "settings": {
            "$ref": "#/components/schemas/SubscriberChannelSettings"
          },
          "accounts": {
            "type": "array",
            "maxItems": 10,
            "description": "Who each of your connected channels reaches, as the channel named you when you connected: a Telegram or Slack name and username, by binding. Kept only on the Standard privacy setting, so it is empty otherwise.",
            "items": {
              "type": "object",
              "required": ["binding_id"],
              "properties": {
                "binding_id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                "name": { "type": "string", "minLength": 1, "maxLength": 254 },
                "username": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                }
              },
              "additionalProperties": false
            }
          },
          "connections": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "An available personal connection route.",
              "required": ["id", "channel", "name"],
              "properties": {
                "id": { "type": "string", "minLength": 1, "maxLength": 128 },
                "channel": { "$ref": "#/components/schemas/Channel" },
                "name": { "type": "string" }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "OperatorConnectRequest": {
        "type": "object",
        "description": "Connect the signed-in person’s own destination through a configured channel. This never changes another person’s channels.",
        "required": ["connection_id", "channel"],
        "properties": {
          "connection_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "channel": { "enum": ["telegram", "slack"] }
        },
        "additionalProperties": false
      },
      "ListPageSize": {
        "type": "integer",
        "minimum": 1,
        "maximum": 100,
        "description": "The page size that produced `items`, echoed so a caller that sent no `limit` can still divide `total` into pages without knowing the server default."
      },
      "MessageState": {
        "type": "string",
        "enum": [
          "accepted",
          "dispatch_pending",
          "queued",
          "sending",
          "provider_accepted",
          "retry_wait",
          "terminal_failed",
          "outcome_unknown",
          "cancelled",
          "expired"
        ]
      },
      "Timestamp": {
        "type": "string",
        "format": "date-time",
        "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$",
        "description": "An RFC 3339 timestamp with a UTC offset. The server is authoritative."
      },
      "MessageListEntry": {
        "type": "object",
        "description": "Accepted-message summary: a one-line snippet of what the message said, and no interaction answer.",
        "required": [
          "accepted_at",
          "diagnostic_id",
          "environment",
          "id",
          "notifier_id",
          "state",
          "subscriber_id",
          "updated_at",
          "attempt_count",
          "highest_proven_provider_state",
          "retry_scheduled",
          "channel"
        ],
        "properties": {
          "accepted_at": { "$ref": "#/components/schemas/Timestamp" },
          "correlation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "subscriber_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 254,
            "description": "What to call the subscriber, resolved as on the subscriber's `name`: your display name, otherwise the channel's own name where the privacy setting keeps it. Absent when there is neither."
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "category": {
            "$ref": "#/components/schemas/MessageCategorySnapshot",
            "description": "Category as accepted. Absent on messages accepted before categories existed."
          },
          "state": { "$ref": "#/components/schemas/MessageState" },
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "connection_test_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The connection test that sent this message, when one did. A `subscriber_message` test is a real message and is recorded in the history as one, marked by this field. Absent on every ordinary send."
          },
          "attempt_count": { "type": "integer", "minimum": 0 },
          "highest_proven_provider_state": {
            "$ref": "#/components/schemas/HighestProvenProviderState"
          },
          "retry_at": { "$ref": "#/components/schemas/Timestamp" },
          "retry_scheduled": { "type": "boolean" },
          "classified_error": {
            "$ref": "#/components/schemas/ClassifiedError"
          },
          "content_snippet": {
            "type": "string",
            "minLength": 1,
            "maxLength": 121,
            "description": "The start of what the message said, on one line: its text, or the title of block content, cut to 120 characters with an ellipsis. Absent when `content_retained` is false."
          },
          "content_retained": {
            "type": "boolean",
            "description": "False once the message's content has been deleted at the end of its retention period (7 days, or 90 on paid plans, after it finished). The rest of the entry is kept."
          },
          "channel": { "$ref": "#/components/schemas/Channel" }
        },
        "additionalProperties": false
      },
      "MessageListPage": {
        "type": "object",
        "description": "Newest accepted messages first, bounded by limit. next_after is the opaque continuation for after. No total: filtered history is a time-series read, so listing a page does not scan the entire retained history. Page numbers are optional and bounded; they may move as new messages arrive.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/MessageListEntry" },
            "maxItems": 100
          },
          "next_after": { "type": "string", "minLength": 1, "maxLength": 2048 },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" }
        },
        "additionalProperties": false
      },
      "MessageDeliveryTimelineEntry": {
        "type": "object",
        "required": ["at", "kind"],
        "properties": {
          "at": { "$ref": "#/components/schemas/Timestamp" },
          "attempt": { "type": "integer", "minimum": 1 },
          "classified_error_code": {
            "$ref": "#/components/schemas/ProblemCode"
          },
          "kind": {
            "type": "string",
            "enum": [
              "accepted",
              "queued",
              "attempt_started",
              "attempt_sent",
              "attempt_retry_scheduled",
              "attempt_could_not_send",
              "attempt_outcome_unknown",
              "could_not_send",
              "outcome_unknown",
              "cancelled",
              "expired"
            ]
          },
          "retry_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "RetainedMessageContent": {
        "description": "Authorized retained notification. source keeps the complete original portable content, including its title, sections and image. No content remains after irreversible retention purge.",
        "oneOf": [
          {
            "type": "object",
            "required": ["state"],
            "properties": { "state": { "const": "not_retained" } },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["state", "text", "source"],
            "properties": {
              "state": { "const": "available" },
              "text": {
                "description": "The complete notification content. This remains authoritative and sufficient when an adapter cannot render optional structure.",
                "type": "string",
                "minLength": 1,
                "maxLength": 8192,
                "x-max-utf8-bytes": 8192
              },
              "source": { "$ref": "#/components/schemas/TextContent" }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["state", "document"],
            "properties": {
              "state": { "const": "available" },
              "document": { "$ref": "#/components/schemas/DocumentContent" }
            },
            "additionalProperties": false
          }
        ]
      },
      "MessageDeliveryHistory": {
        "type": "object",
        "description": "Tenant-authorized delivery history and retained original content. interaction_request is present only while the original presentation remains retained; its original expires_at is historical, and a new send must use a new future expiry.",
        "required": ["message", "content", "timeline"],
        "properties": {
          "message": { "$ref": "#/components/schemas/Message" },
          "content": { "$ref": "#/components/schemas/RetainedMessageContent" },
          "metadata": { "$ref": "#/components/schemas/Metadata" },
          "timeline": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MessageDeliveryTimelineEntry"
            }
          },
          "interaction_request": {
            "$ref": "#/components/schemas/InteractionRequest"
          }
        },
        "additionalProperties": false
      },
      "InteractionTimelineEntry": {
        "type": "object",
        "description": "Content-free timeline: no prompt, option, answer, endpoint URL, provider identity or credential field.",
        "required": ["at", "kind"],
        "properties": {
          "at": { "$ref": "#/components/schemas/Timestamp" },
          "attempt": { "type": "integer", "minimum": 1 },
          "attempt_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "classification": {
            "type": "string",
            "enum": [
              "received",
              "answered",
              "duplicate",
              "no_longer_active",
              "identity_rejected",
              "invalid",
              "unanchored"
            ]
          },
          "diagnostic_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "endpoint_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "event_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "kind": {
            "type": "string",
            "enum": [
              "created",
              "callback_received",
              "callback_answered",
              "callback_duplicate",
              "callback_no_longer_active",
              "callback_identity_rejected",
              "callback_invalid",
              "callback_unanchored",
              "answered",
              "expired",
              "cancelled",
              "presentation_updated",
              "presentation_failed",
              "event_created",
              "event_delivery_started",
              "event_delivered",
              "event_delivery_retry_scheduled",
              "event_delivery_failed",
              "event_delivery_held",
              "machine_event_published",
              "machine_event_acknowledged",
              "machine_event_quarantined"
            ]
          },
          "machine_client_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "machine_event_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "quarantine_reason_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false
      },
      "InteractionTimeline": {
        "type": "object",
        "description": "The customer-authorized interaction trace. The separately retained answer is never embedded in timeline entries.",
        "required": [
          "answer",
          "interaction_id",
          "message_id",
          "state",
          "timeline",
          "type"
        ],
        "properties": {
          "answer": {
            "oneOf": [
              {
                "type": "object",
                "required": ["retained"],
                "properties": { "retained": { "const": false } },
                "additionalProperties": false
              },
              {
                "type": "object",
                "required": ["retained", "value"],
                "properties": {
                  "retained": { "const": true },
                  "value": {
                    "oneOf": [{ "type": "boolean" }, { "type": "string" }]
                  }
                },
                "additionalProperties": false
              }
            ]
          },
          "interaction_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "message_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "resolution_latency_ms": { "type": "integer", "minimum": 0 },
          "state": {
            "type": "string",
            "enum": ["answered", "cancelled", "expired", "open"]
          },
          "timeline": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/InteractionTimelineEntry" }
          },
          "type": { "type": "string", "enum": ["confirm", "input", "select"] }
        },
        "additionalProperties": false
      },
      "UpdateEmailSenderRequest": {
        "type": "object",
        "description": "Changes the sender name on a customer-owned email-domain connection. Shared addresses keep the WhooshBang sender. Dashboard sessions require an administrator.",
        "required": ["row_version", "sender_display_name"],
        "properties": {
          "row_version": { "type": "integer", "minimum": 1 },
          "sender_display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "pattern": "^[^\\u0000-\\u001F\\u007F-\\u009F\\u2028\\u2029]+$"
          }
        },
        "additionalProperties": false
      },
      "CustomerEventDeliveryAttempt": {
        "type": "object",
        "required": [
          "attempt",
          "created_at",
          "delivery_sequence",
          "endpoint_id",
          "event_id",
          "id",
          "manual_replay",
          "status"
        ],
        "properties": {
          "attempt": { "type": "integer", "minimum": 1 },
          "completed_at": { "$ref": "#/components/schemas/Timestamp" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "delivery_sequence": { "type": "integer", "minimum": 1 },
          "diagnostic_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "endpoint_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "event_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "http_status": { "type": "integer", "minimum": 100, "maximum": 599 },
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "manual_replay": { "type": "boolean" },
          "next_attempt_at": { "$ref": "#/components/schemas/Timestamp" },
          "started_at": { "$ref": "#/components/schemas/Timestamp" },
          "status": {
            "type": "string",
            "enum": [
              "attempting",
              "delivered",
              "paused",
              "pending",
              "retry_wait",
              "terminal_failed"
            ]
          }
        },
        "additionalProperties": false
      },
      "CustomerEventDeliveryHistory": {
        "type": "object",
        "description": "Recorded delivery attempts for one customer event, with no endpoint URL, event content or signing secret.",
        "required": ["attempts", "event_id"],
        "properties": {
          "attempts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerEventDeliveryAttempt"
            }
          },
          "event_id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        },
        "additionalProperties": false
      },
      "DeliveryHolds": {
        "type": "object",
        "description": "Which deliveries are held. Operator incident reasons are never returned.",
        "required": ["held_endpoint_ids"],
        "properties": {
          "held_by": {
            "type": "string",
            "enum": [
              "global",
              "provider",
              "organization",
              "project",
              "endpoint",
              "client",
              "connection"
            ]
          },
          "held_endpoint_ids": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        },
        "additionalProperties": false
      },
      "MachineClientOperations": {
        "type": "object",
        "required": [
          "active_credentials",
          "machine_client",
          "machine_event_backlog",
          "total_credentials"
        ],
        "properties": {
          "active_credentials": { "type": "integer", "minimum": 0 },
          "credential_last_used_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "held_by": {
            "type": "string",
            "enum": [
              "global",
              "provider",
              "organization",
              "project",
              "endpoint",
              "client",
              "connection"
            ]
          },
          "machine_client": { "$ref": "#/components/schemas/MachineClient" },
          "machine_event_backlog": { "type": "integer", "minimum": 0 },
          "machine_event_oldest_age_ms": { "type": "integer", "minimum": 0 },
          "total_credentials": { "type": "integer", "minimum": 0 }
        },
        "additionalProperties": false
      },
      "MachineClientOperationsList": {
        "type": "object",
        "description": "Machine-client operational summaries, without consuming events or exposing credential material.",
        "required": ["items", "quarantine"],
        "properties": {
          "items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/MachineClientOperations" }
          },
          "quarantine": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "contract_schema",
                "count",
                "last_acknowledged_at",
                "machine_client_id",
                "reason_code"
              ],
              "properties": {
                "contract_schema": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 2048
                },
                "count": { "type": "integer", "minimum": 0 },
                "last_acknowledged_at": {
                  "$ref": "#/components/schemas/Timestamp"
                },
                "machine_client_id": {
                  "$ref": "#/components/schemas/OpaqueIdentifier"
                },
                "reason_code": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "RecipientCopyCatalogue": {
        "type": "object",
        "description": "The complete bounded text catalogue for one language. Values are raw templates: placeholders and behavioral controls retain their meaning when words change.",
        "required": ["project_id", "language", "items"],
        "properties": {
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "language": { "$ref": "#/components/schemas/RecipientLanguage" },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "key",
                "default_value",
                "value",
                "overridden",
                "maximum_length"
              ],
              "properties": {
                "key": { "$ref": "#/components/schemas/RecipientCopyKey" },
                "default_value": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 8192
                },
                "value": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 8192
                },
                "overridden": { "type": "boolean" },
                "maximum_length": { "type": "integer", "minimum": 1 }
              },
              "additionalProperties": false
            },
            "maxItems": 123,
            "minItems": 123
          }
        },
        "additionalProperties": false
      },
      "MessageNotificationImage": {
        "type": "object",
        "description": "Canonical PNG bytes for the retained image of one authorized message, encoded as base64. A purged message or unavailable image returns404; no provider URL is disclosed.",
        "required": ["asset_id", "content_type", "data_base64"],
        "properties": {
          "asset_id": {
            "$ref": "#/components/schemas/NotificationImageAssetId"
          },
          "content_type": { "const": "image/png" },
          "data_base64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 699052,
            "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
          }
        },
        "additionalProperties": false
      },
      "OpaqueIdentifier": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[^\u0000-\u001f-  ]+$",
        "description": "An opaque identifier. Its shape, ordering, and embedded content are not public promises."
      },
      "ListPageNumber": {
        "type": "integer",
        "minimum": 1,
        "maximum": 50000,
        "description": "A 1-based page number. Present on a response only when the request addressed the list by page rather than by cursor: a cursor walk cannot know which page it is on. What is bounded is the row a page starts at, not the page number: a request whose first row would be past 50,000 — the deepest row any published list ceiling reaches — is refused as `request_invalid`. Bounding the page number instead would make the last rows of a large list unreachable at a small page size, which is exactly when a person is paging through one."
      },
      "ChannelConnectionProvider": {
        "type": "string",
        "enum": ["telegram", "slack", "email"],
        "description": "A provider that can back a Channel Connection. A member can be frozen before its adapter exists; deployments advertise only providers they can execute."
      },
      "ChannelConnectionMode": {
        "type": "string",
        "enum": [
          "whooshbang_shared",
          "whooshbang_hosted",
          "customer_managed",
          "customer_byok"
        ],
        "description": "How this environment obtained its provider identity. `whooshbang_shared` selects a disclosed global WhooshBang identity; `whooshbang_hosted` authorizes the WhooshBang-owned distributed app at one provider authority without making that installation caller-selectable; the customer modes end with an identity the customer owns."
      },
      "ChannelConnectionStatus": {
        "type": "string",
        "enum": ["pending", "active", "degraded", "disabled", "archived"],
        "description": "`degraded` still delivers: the identity a subscriber consented to has not changed, only its last health check. `archived` is terminal, so consent granted against it is never revived."
      },
      "ProviderHealthState": {
        "type": "string",
        "enum": ["unknown", "healthy", "degraded", "unhealthy"]
      },
      "ConnectionLifecycleOperation": {
        "type": "string",
        "enum": [
          "validate",
          "provision",
          "reauthorize",
          "repair",
          "health",
          "rotate",
          "disable",
          "deprovision",
          "purge"
        ]
      },
      "SharedProviderIdentity": {
        "type": "object",
        "description": "A WhooshBang-owned identity an environment may select. Its credential is operated by WhooshBang and is structurally absent from this API.",
        "required": ["id", "display_name", "health"],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" }
        },
        "additionalProperties": false
      },
      "ConnectionProvider": {
        "description": "What one provider supports for connection setup and lifecycle. Known provider arms forbid contradictory setup modes; deployments still omit an arm entirely until they can execute it.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "provider",
              "display_name",
              "setup_modes",
              "lifecycle_operations",
              "shared_installation_supported",
              "shared_identities"
            ],
            "properties": {
              "provider": { "const": "telegram" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "setup_modes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 3,
                "uniqueItems": true,
                "items": {
                  "enum": [
                    "whooshbang_shared",
                    "customer_managed",
                    "customer_byok"
                  ]
                }
              },
              "lifecycle_operations": {
                "type": "array",
                "maxItems": 9,
                "uniqueItems": true,
                "items": {
                  "$ref": "#/components/schemas/ConnectionLifecycleOperation"
                }
              },
              "shared_installation_supported": { "type": "boolean" },
              "shared_identities": {
                "type": "array",
                "maxItems": 20,
                "items": {
                  "$ref": "#/components/schemas/SharedProviderIdentity"
                }
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "provider",
              "display_name",
              "setup_modes",
              "lifecycle_operations",
              "shared_installation_supported",
              "shared_identities"
            ],
            "properties": {
              "provider": { "const": "slack" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "setup_modes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 2,
                "uniqueItems": true,
                "items": { "enum": ["whooshbang_hosted", "customer_managed"] }
              },
              "lifecycle_operations": {
                "type": "array",
                "maxItems": 9,
                "uniqueItems": true,
                "items": {
                  "$ref": "#/components/schemas/ConnectionLifecycleOperation"
                }
              },
              "shared_installation_supported": { "const": true },
              "shared_identities": { "type": "array", "maxItems": 0 }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "The frozen email setup modes. A deployment omits this arm until an executable email adapter is registered.",
            "required": [
              "provider",
              "display_name",
              "setup_modes",
              "lifecycle_operations",
              "shared_installation_supported",
              "shared_identities"
            ],
            "properties": {
              "provider": { "const": "email" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "setup_modes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 2,
                "uniqueItems": true,
                "items": { "enum": ["whooshbang_shared", "customer_managed"] }
              },
              "lifecycle_operations": {
                "type": "array",
                "maxItems": 9,
                "uniqueItems": true,
                "items": {
                  "$ref": "#/components/schemas/ConnectionLifecycleOperation"
                }
              },
              "shared_installation_supported": { "const": true },
              "shared_identities": {
                "type": "array",
                "maxItems": 20,
                "items": {
                  "$ref": "#/components/schemas/SharedProviderIdentity"
                }
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "ConnectionProviderCollection": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "#/components/schemas/ConnectionProvider" }
          },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "ChannelConnection": {
        "description": "One environment's provider-discriminated connection. Credentials and provider-native authority identifiers are structurally absent.",
        "oneOf": [
          { "$ref": "#/components/schemas/TelegramChannelConnection" },
          { "$ref": "#/components/schemas/HostedChannelConnection" },
          {
            "$ref": "#/components/schemas/CustomerApplicationChannelConnection"
          },
          { "$ref": "#/components/schemas/EmailChannelConnection" }
        ]
      },
      "ChannelConnectionCollection": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/ChannelConnection" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "CreateChannelConnectionRequest": {
        "description": "Selects the provider identity this environment will send through, discriminated on `mode`, and naming the provider it is for. The two customer-owned modes differ only in where the bot comes from: `customer_byok` connects one the customer already has, and `customer_managed` has Telegram create a new one on the administrator's own Telegram account. Neither supersedes the other, because a bot that already exists can never be adopted into managed mode — the manager that may act for a bot is fixed when the bot is created.",
        "oneOf": [
          {
            "type": "object",
            "description": "Reuses a disclosed WhooshBang-owned identity. WhooshBang operates its credential, so selecting one conveys no ability to read, rotate, or retire it.",
            "required": ["mode", "display_name", "shared_identity_id"],
            "properties": {
              "mode": { "type": "string", "enum": ["whooshbang_shared"] },
              "provider": {
                "type": "string",
                "const": "telegram",
                "default": "telegram",
                "description": "This established setup arm is Telegram-only. Omitted means telegram. A provider whose setup is structurally different — an OAuth install rather than a credential — has its own arm of this union rather than bending this one."
              },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "shared_identity_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Connects a provider identity the customer already owns by supplying its credential.\n\nThis arm carries no identity field, and the absence is deliberate. `provider_identity_digest` is unique across every tenant, so an endpoint that digested a client-supplied identity would answer \"already claimed\" for a bot the caller does not own — an oracle for whether any given bot is connected to WhooshBang by anyone. The identity is derived server-side from a provider-validated `getMe` on the submitted credential, which no caller can forge without holding the credential itself.",
            "required": ["mode", "display_name", "credential"],
            "properties": {
              "mode": { "type": "string", "enum": ["customer_byok"] },
              "provider": {
                "type": "string",
                "const": "telegram",
                "default": "telegram",
                "description": "This established setup arm is Telegram-only. Omitted means telegram. A provider whose setup is structurally different — an OAuth install rather than a credential — has its own arm of this union rather than bending this one."
              },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "credential": {
                "type": "string",
                "minLength": 1,
                "maxLength": 512,
                "writeOnly": true,
                "description": "The customer's own provider credential; for Telegram, the bot token BotFather issued. Write-only: it is sealed on arrival and is never echoed here or by any later read, and no reference to it appears in `ChannelConnection`."
              },
              "confirm_webhook_takeover": {
                "type": "boolean",
                "description": "Consent to replace a webhook the identity already has. Absent or `false`, an occupied identity is refused rather than silently detaching whatever was receiving its updates."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Starts a guided setup in which Telegram creates a brand new bot on the administrator's own Telegram account. The connection comes back `pending` with a `setup` describing the one thing a human still has to do, because creating a bot is a person-only action no API of ours can perform for them.\n\nThis arm carries no credential field at all, and that absence is the entire point of the mode: Telegram hands the new bot's token to WhooshBang server to server, so it never passes through a browser, a clipboard, this request, or any response. There is nothing here for a caller to paste, and therefore nothing for a caller to leak.",
            "required": ["mode", "display_name", "suggested_bot_username"],
            "properties": {
              "mode": { "type": "string", "enum": ["customer_managed"] },
              "provider": {
                "type": "string",
                "const": "telegram",
                "default": "telegram",
                "description": "This established setup arm is Telegram-only. Omitted means telegram. A provider whose setup is structurally different — an OAuth install rather than a credential — has its own arm of this union rather than bending this one."
              },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "suggested_bot_username": {
                "$ref": "#/components/schemas/SuggestedBotUsername"
              },
              "suggested_bot_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "The display name prefilled in the same dialog — what a subscriber reads at the top of the chat, as opposed to the @username they address. Unlike the username this one can be changed afterwards, so it is a convenience rather than a commitment. Omit it and Telegram's dialog opens with no name suggested."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Starts a guided setup in which the customer creates and owns their own application at the provider. The connection comes back `pending` with an `app_setup` carrying the provider's own creation link, already filled in with this application's configuration where the provider allows it.\n\nThis arm carries no credential field, because at this point no credential exists: the provider issues the application's secrets when the owner creates it. They arrive later through the write-only rotation boundary, and the installation grant never arrives from the caller at all — WhooshBang obtains it from the provider's installation exchange. The three names here are what the owner's own recipients will see, which is why the caller chooses them rather than WhooshBang: a generated name would permanently brand a customer's own application with ours, and that is the one thing customer-owned modes exist to prevent.\n\nA provider that does not set a connection up this way refuses the request as an unavailable setup mode. Each provider may also refuse a name its own rules do not allow, within the bounds stated here.",
            "required": [
              "mode",
              "provider",
              "display_name",
              "app_name",
              "bot_display_name",
              "app_description"
            ],
            "properties": {
              "mode": { "type": "string", "const": "customer_managed" },
              "provider": {
                "$ref": "#/components/schemas/ChannelConnectionProvider"
              },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "What this connection is called inside WhooshBang. Unrelated to what the provider shows recipients."
              },
              "app_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 35,
                "description": "The application name the provider's creation flow is prefilled with. The owner can still change it at the provider; this is a suggestion, not a reservation."
              },
              "bot_display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 80,
                "description": "The bot display name in the same flow — what a recipient reads at the top of the conversation."
              },
              "app_description": {
                "type": "string",
                "minLength": 1,
                "maxLength": 140,
                "description": "The short description the provider shows beside the application."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Starts the hosted authorization for a WhooshBang-owned distributed application installed independently at the provider authority the provider derives during authorization. The caller supplies neither installation identity nor credential material. A provider without a hosted application refuses the request as an unavailable setup mode.",
            "required": ["mode", "provider", "display_name"],
            "properties": {
              "mode": { "type": "string", "const": "whooshbang_hosted" },
              "provider": {
                "$ref": "#/components/schemas/ChannelConnectionProvider"
              },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Selects the recipient-verified shared email identity. No sender domain, provider installation or credential is caller supplied.",
            "required": [
              "mode",
              "provider",
              "display_name",
              "shared_identity_id"
            ],
            "properties": {
              "mode": { "const": "whooshbang_shared" },
              "provider": { "const": "email" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "shared_identity_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Authorizes one account-owned email domain to this environment connection. The installation and domain are WhooshBang ids resolved under the authenticated organization; provider team ids, API keys and OAuth credentials are forbidden by shape.",
            "required": [
              "mode",
              "provider",
              "display_name",
              "installation_id",
              "domain_id",
              "sender_local_part",
              "sender_display_name"
            ],
            "properties": {
              "mode": { "const": "customer_managed" },
              "provider": { "const": "email" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "installation_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "domain_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "sender_local_part": {
                "$ref": "#/components/schemas/EmailLocalPart"
              },
              "sender_display_name": {
                "$ref": "#/components/schemas/EmailDisplayName"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "UpdateChannelConnectionRequest": {
        "type": "object",
        "description": "Edits a connection under the row version that was read. Provider, mode, identity, and ownership are immutable; replacing any of them is a new connection.",
        "required": ["row_version"],
        "properties": {
          "row_version": { "type": "integer", "minimum": 1 },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": { "type": "string", "enum": ["active", "disabled"] }
        },
        "additionalProperties": false
      },
      "RotateChannelConnectionCredentialRequest": {
        "description": "Replaces the secret behind a connection, discriminated by where a replacement can come from at all. A customer-owned bot has one only its owner can produce and therefore sends it; a managed bot has one only Telegram can issue and therefore sends nothing. An application the customer owns has separate authorities and names each one it hands over. Either way the connection keeps its provider identity, so a subscriber stays bound to the identity it consented to and only the secret changes.\n\nThe first submission during setup uses this same boundary. Handing a secret over and replacing it are the same operation — a write that never reads the old value back — and giving initial setup its own endpoint would have meant two ways to do one thing, differing only in what the connection's status happened to be.",
        "oneOf": [
          {
            "type": "object",
            "description": "Supplies or replaces the application-specific authorities of an application the customer owns. Every authority that provider's application takes is sent together, both for the first submission during setup and for every later replacement.\n\nSending only the one that changed would read as the kinder API, and it is the wrong shape: the authorities are sealed as one versioned set, so replacing one alone would mean decrypting the others and writing them back — reading secrets at a boundary whose whole purpose is that nothing reads them.\n\n`application_identity` is safe metadata; the secrets are write-only and are never readable afterwards by any surface. `ingress_secret` is optional in shape because not every provider signs inbound requests with a secret the owner holds; a provider whose application does have one refuses a request that leaves it out, and refuses an `application_identity` that is not in its own format.\n\nThere is no bot-token field here, and the absence is the point: WhooshBang obtains the installation grant from the provider's installation exchange, so it never passes through a browser, a clipboard, this request, or any response.",
            "required": [
              "provider",
              "application_identity",
              "application_secret"
            ],
            "properties": {
              "provider": {
                "$ref": "#/components/schemas/ChannelConnectionProvider"
              },
              "application_identity": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128,
                "pattern": "^[\\x21-\\x7e]+$",
                "description": "The identifier the provider issued for the application — for Slack, its Client ID. Safe application metadata rather than an authority: it identifies the application in an authorization redirect the provider's users can already see."
              },
              "application_secret": {
                "type": "string",
                "minLength": 1,
                "maxLength": 512,
                "writeOnly": true,
                "description": "The secret the application authenticates to the provider with — for Slack, its Client Secret. Write-only: sealed on arrival, never echoed here or by any later read, and reachable only by the exchanges that need it."
              },
              "ingress_secret": {
                "type": "string",
                "minLength": 1,
                "maxLength": 512,
                "writeOnly": true,
                "description": "The secret that verifies an inbound request really came from the provider — for Slack, its Signing Secret. Write-only on the same terms, and reachable only by ingress verification."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Replaces the customer-owned credential behind a connection. The connection keeps its provider identity, so a subscriber stays bound to the identity it consented to and only the secret changes; a credential for a different identity is refused.",
            "required": ["credential"],
            "properties": {
              "credential": {
                "type": "string",
                "minLength": 1,
                "maxLength": 512,
                "writeOnly": true,
                "description": "The replacement provider credential. Write-only on the same terms as the credential a `customer_byok` create supplies: sealed on arrival and never echoed."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Rotates a `customer_managed` connection, whose replacement only Telegram can issue. Asked to rotate, Telegram revokes the bot's current token and returns the successor to the manager that created it, so there is no customer-supplied credential to send and no field here to send one in — a caller able to supply one would be describing a bot this mode never handed it. The identity is untouched: the same bot keeps the same @username and the same subscribers, and only the secret behind it is new.",
            "required": ["source"],
            "properties": {
              "source": {
                "type": "string",
                "const": "provider_managed",
                "description": "Names the provider as the origin of the replacement. It is stated rather than inferred so that a body which lost its credential in transit is refused as malformed instead of being read as a request to have the provider mint a new token."
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "ConnectionTestKind": {
        "type": "string",
        "enum": [
          "outbound_notification",
          "signed_interaction",
          "subscriber_message"
        ],
        "description": "Which half of a connection a test exercises. `outbound_notification` proves this exact identity can put a message in front of the person who set it up. `signed_interaction` proves the opposite direction: that the provider can reach this deployment's interactivity URL and that the request it signs verifies against the secret we hold. The two fail for entirely different reasons, so they are never collapsed into one result. `subscriber_message` sends a short text to one named subscriber through exactly this connection, whichever connection is the default and whatever channel the subscriber prefers, and records it in the message history as a test. It settles as that message does; a failed one carries no `failure_code`, because the message it names says why.",
        "$comment": "Provider-neutral vocabulary. `outbound_notification` and `signed_interaction` are implemented for Slack only; a provider that cannot run one refuses it rather than reporting a pass it never proved. `subscriber_message` works on every channel."
      },
      "ConnectionTestRecoveryAction": {
        "type": "string",
        "enum": [
          "none",
          "complete_setup",
          "replace_credentials",
          "reinstall",
          "retry_later",
          "check_request_url",
          "contact_support"
        ],
        "description": "The exact safe next action for one test result, in product vocabulary.\n\nIt is a different vocabulary from a connection's own recovery action because the actions genuinely differ: a test that nothing answered is fixed by checking the request URL the provider was given, and a request that arrived and did not verify is fixed by re-entering the app's secrets — neither of which is a lifecycle transition on the connection.\n\n`check_request_url` is also the honest answer when nobody simply pressed the button: the window closed with nothing arriving, and that has exactly two causes."
      },
      "ConnectionTestStatus": {
        "type": "string",
        "enum": ["pending", "succeeded", "failed", "expired"],
        "description": "`pending` means the test is placed and its answer has not arrived; a signed-interaction test stays there until somebody presses the button it sent. `expired` is the honest reading of a pending test whose window closed: nothing failed, nobody answered."
      },
      "ConnectionTestFailureCode": {
        "type": "string",
        "enum": [
          "setup_incomplete",
          "verification_target_unknown",
          "credential_unavailable",
          "provider_rejected",
          "provider_unavailable",
          "provider_rate_limited",
          "unverified_request_received"
        ],
        "description": "Why a test did not pass, in a vocabulary the owner can act on rather than the provider's wire error.\n\n`verification_target_unknown` means nobody has installed the app from this deployment yet, so there is no owner to send a test to. `unverified_request_received` is a statement of fact and not a diagnosis: a request carrying this test's own challenge reached the interactivity URL and its signature did not verify against the secret this connection holds.\n\nA window that closed with nothing arriving is not in this list, because it is not a failure: it reads as `expired`, which says nobody answered rather than that anything broke."
      },
      "ConnectionTestEvidence": {
        "type": "object",
        "description": "What a finished test actually observed. Every field is safe to render, log, and paste into an issue: no credential, no provider-native app, workspace, channel, or user identifier, and no message content.",
        "properties": {
          "identity_handle": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The visible handle the test went out as — the same identity a subscriber would see."
          },
          "workspace_display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The provider workspace the test ran in, as its own members see it named."
          },
          "accepted_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When the provider accepted the outbound message. Acceptance is the provider's own answer, not our belief."
          },
          "observed_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When the signed request the test was waiting for arrived and verified."
          },
          "round_trip_ms": {
            "type": "integer",
            "minimum": 0,
            "maximum": 86400000,
            "description": "Milliseconds from placing the test to observing its answer."
          },
          "signature_verified": {
            "type": "boolean",
            "description": "Whether the provider's signature over the untouched request body verified against the secret this connection custodies. Present only once a request has arrived."
          },
          "ingress_host": {
            "type": "string",
            "minLength": 1,
            "maxLength": 253,
            "description": "The public host the provider actually called, which is what a misconfigured or stale request URL gets wrong. It is this deployment's own hostname and names no tenant."
          }
        },
        "additionalProperties": false
      },
      "ConnectionTest": {
        "type": "object",
        "description": "One owner-triggered proof that an exact connection still works, run on demand and answered with evidence rather than with a claim.\n\nIt is deliberately incapable of carrying a secret: nothing here is a credential, a provider-native identifier, or message content, and a test that failed says why in a closed vocabulary rather than by quoting a provider.",
        "required": [
          "id",
          "connection_id",
          "kind",
          "status",
          "requested_at",
          "expires_at",
          "recovery_action",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "kind": { "$ref": "#/components/schemas/ConnectionTestKind" },
          "status": { "$ref": "#/components/schemas/ConnectionTestStatus" },
          "requested_at": { "$ref": "#/components/schemas/Timestamp" },
          "completed_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When the test settled. Absent while it is still pending."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When a pending test stops waiting. A test that reaches this without an answer becomes `expired`, which is not a failure of the connection."
          },
          "evidence": { "$ref": "#/components/schemas/ConnectionTestEvidence" },
          "failure_code": {
            "$ref": "#/components/schemas/ConnectionTestFailureCode"
          },
          "recovery_action": {
            "$ref": "#/components/schemas/ConnectionTestRecoveryAction",
            "description": "The exact safe next action for this result. `none` on a pass."
          },
          "message_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The message a `subscriber_message` test sent, in the environment's message history. Absent for the other kinds."
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "ConnectionTestCollection": {
        "type": "object",
        "description": "This connection's recent tests, newest first. It is the audit-safe failure history for a connection: what was tried, when, and what came back.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/ConnectionTest" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "UsageDate": {
        "type": "string",
        "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$",
        "description": "A calendar day in UTC, as `YYYY-MM-DD`."
      },
      "UsageGrouping": {
        "type": "string",
        "enum": ["state", "channel", "connection"],
        "description": "What a usage breakdown splits each day's messages by: their current `MessageState`, their `Channel`, or the channel connection they were sent through."
      },
      "UsageReport": {
        "type": "object",
        "description": "An environment's accepted messages per UTC day over an inclusive range, one bucket for every day in the range including days with none, oldest first. `totals` sums the range.",
        "required": [
          "from",
          "to",
          "group_by",
          "breakdown_retained_from",
          "days",
          "totals"
        ],
        "properties": {
          "from": { "$ref": "#/components/schemas/UsageDate" },
          "to": { "$ref": "#/components/schemas/UsageDate" },
          "group_by": { "$ref": "#/components/schemas/UsageGrouping" },
          "breakdown_retained_from": {
            "$ref": "#/components/schemas/UsageDate",
            "description": "The first day whose breakdown is complete. Messages older than 90 days are no longer kept, so earlier days report `accepted` without a full breakdown."
          },
          "first_accepted_on": {
            "$ref": "#/components/schemas/UsageDate",
            "description": "The first day this environment ever accepted a message, whatever the range asked for. Absent when it has never accepted one."
          },
          "days": {
            "type": "array",
            "minItems": 1,
            "maxItems": 366,
            "items": { "$ref": "#/components/schemas/UsageBucket" }
          },
          "totals": {
            "type": "object",
            "required": ["accepted", "groups"],
            "properties": {
              "accepted": { "type": "integer", "minimum": 0 },
              "groups": {
                "type": "array",
                "maxItems": 200,
                "items": { "$ref": "#/components/schemas/UsageGroupCount" }
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "CreateConnectionTestRequest": {
        "type": "object",
        "description": "Places a test against an exact connection. Installer diagnostics carry only kind. subscriber_message names a subscriber and either legacy plain text or complete portable content, with an optional interaction. It is a real send, including in live, through exactly this connection.",
        "required": ["kind"],
        "properties": {
          "kind": { "$ref": "#/components/schemas/ConnectionTestKind" },
          "to": {
            "type": "object",
            "description": "Who a `subscriber_message` test goes to. The subscriber must have connected through this connection.",
            "required": ["subscriber_id"],
            "properties": {
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              }
            },
            "additionalProperties": false
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "description": "The words a `subscriber_message` test sends, as plain text."
          },
          "content": { "$ref": "#/components/schemas/MessageContent" },
          "interaction": {
            "$ref": "#/components/schemas/InteractionSendRequest"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": { "kind": { "const": "subscriber_message" } },
              "required": ["kind"]
            },
            "then": {
              "required": ["to"],
              "oneOf": [
                {
                  "required": ["text"],
                  "properties": { "content": false, "text": {} }
                },
                {
                  "required": ["content"],
                  "properties": { "text": false, "content": {} }
                }
              ],
              "properties": { "to": {} }
            },
            "else": {
              "properties": {
                "to": false,
                "text": false,
                "content": false,
                "interaction": false
              }
            }
          }
        ],
        "additionalProperties": false
      },
      "CustomerApplicationManifest": {
        "type": "object",
        "description": "The exact configuration an application the customer creates and owns is created from, as data rather than as a URL-encoded blob.\n\nIt exists so the owner can read what they are about to approve, and so a reviewer can check it, without opening the provider. It is built by the provider that owns the format, so `manifest` is that provider's own document and `provider` says whose. It carries configuration only: no organization, project, or environment, no credential, and no provider-native identifier. Any opaque handle inside the request URLs selects candidate setup state and authorizes nothing — a request still has to carry the provider's own proof over the untouched body before anything inside it is believed.",
        "required": [
          "provider",
          "creation_url",
          "app_name",
          "bot_display_name",
          "description",
          "bot_scopes",
          "user_scopes",
          "request_urls",
          "diagnostic_id"
        ],
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/ChannelConnectionProvider"
          },
          "creation_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 8192,
            "description": "The same prefilled creation link the setup carries, repeated here so one read answers both questions."
          },
          "app_name": { "type": "string", "minLength": 1, "maxLength": 35 },
          "bot_display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "description": { "type": "string", "minLength": 1, "maxLength": 140 },
          "bot_scopes": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": { "type": "string", "minLength": 1, "maxLength": 64 },
            "description": "Every provider scope or permission the application's bot will ask for, exactly as the provider will show them. Raw provider vocabulary on purpose: this is the screen the owner is about to approve, and translating it would make it unverifiable."
          },
          "user_scopes": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": { "type": "string", "minLength": 1, "maxLength": 64 },
            "description": "Every provider scope a recipient will be asked for when they sign in. Separate from the bot scopes because they are approved by different people at different moments. Empty for a provider whose recipients never sign in through the application."
          },
          "request_urls": {
            "type": "object",
            "description": "Where this deployment answers the application. Each is present only when the provider calls it separately: a provider that delivers events and interactions to one endpoint names it once, and one with no recipient sign-in has no recipient redirect. A stale or edited value here is the failure a signed-interaction test detects.",
            "minProperties": 1,
            "properties": {
              "events": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://[^\\s]+$",
                "maxLength": 2048
              },
              "interactions": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://[^\\s]+$",
                "maxLength": 2048
              },
              "installation_redirect": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://[^\\s]+$",
                "maxLength": 2048
              },
              "recipient_redirect": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://[^\\s]+$",
                "maxLength": 2048
              }
            },
            "additionalProperties": false
          },
          "manifest": {
            "type": "object",
            "description": "The literal configuration document the provider is handed, in that provider's own format, for a provider that creates an application from one. Reproduced whole so what the owner reviews and what the provider receives cannot drift apart. Absent for a provider whose application is configured field by field rather than from a document.",
            "additionalProperties": true
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "NotifierConnectionRoute": {
        "type": "object",
        "description": "One notifier's use of one connection in the same environment. This is the record that decides which identity a send actually leaves through: a connection nothing routes to is configured and inert, and a subscriber cannot authorize against it either. Routing is deliberately separate from creating the connection so that adding a second identity never moves traffic on its own.",
        "required": ["notifier_id", "connection_id", "is_default"],
        "properties": {
          "notifier_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The notifier's own identity, as `default_notifier.id` reports it on the project environment. Deliberately not the `notifier_id` reference a send carries: a send names a notifier by a stable public reference, and routing names the exact row, so renaming a reference cannot silently repoint traffic."
          },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "is_default": {
            "type": "boolean",
            "description": "Whether this is the one connection the notifier sends and authorizes through. A notifier has at most one default at a time; the mapping is plural so later routing rules have somewhere to live, but exactly one route decides today's traffic. A notifier whose routes are all non-default sends nothing."
          }
        },
        "additionalProperties": false
      },
      "NotifierConnectionCollection": {
        "type": "object",
        "description": "The routes read back after a change, or every route in the environment when listed. Ordered by notifier and then connection so a caller diffing two reads sees a real change rather than a reordering.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": { "$ref": "#/components/schemas/NotifierConnectionRoute" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "AttachNotifierConnectionRequest": {
        "type": "object",
        "description": "Routes a notifier through a connection in the same environment, and optionally makes it the default. Repeating an identical request changes nothing, so a caller that lost a response can simply send it again.\n\nPromoting a new default demotes the old one in the same transaction, so no send ever sees two. That is a real change to which identity subscribers hear from next: bindings already authorized against the previous connection keep their consent and stop being deliverable until that connection is default again. Consent is never moved between identities.",
        "required": ["notifier_id", "connection_id"],
        "properties": {
          "notifier_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The notifier's own identity, as `default_notifier.id` reports it on the project environment."
          },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "is_default": {
            "type": "boolean",
            "default": true,
            "description": "Defaults to true because attaching a connection a notifier will not use is rarely the intent, and the plural mapping exists for routing rules that do not exist yet. Send `false` to record the route without moving traffic to it."
          }
        },
        "additionalProperties": false
      },
      "DiagnosticId": {
        "type": "string",
        "minLength": 8,
        "maxLength": 128,
        "pattern": "^[A-Za-z0-9_-]+$",
        "description": "A safe public identifier used to correlate protected service diagnostics."
      },
      "IdempotencyKey": {
        "type": "string",
        "minLength": 8,
        "maxLength": 255,
        "pattern": "^[!-~]+$",
        "description": "Visible ASCII, scoped by authenticated environment, operation ID, and key, and retained for seven days from first acceptance."
      },
      "BillingProjectSlots": {
        "type": "object",
        "required": [
          "project_capacity",
          "requested_project_ids",
          "active_project_ids"
        ],
        "properties": {
          "project_capacity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "requested_project_ids": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" },
            "uniqueItems": true,
            "maxItems": 2147483647
          },
          "active_project_ids": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" },
            "uniqueItems": true,
            "maxItems": 2147483647
          }
        },
        "additionalProperties": false,
        "description": "Reusable account project slots. After a downgrade the oldest requested projects retain active slots. Unassigned projects retain data, accepted delivery and answers; new live sends require an active slot. Paid capacity includes all unexpired project purchases, so retained dropped extras can exceed the maximum renewing selection."
      },
      "AssignBillingProjectSlotsRequest": {
        "type": "object",
        "required": ["project_ids"],
        "properties": {
          "project_ids": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" },
            "uniqueItems": true,
            "maxItems": 10025
          }
        },
        "additionalProperties": false,
        "description": "Replace the requested active project selection with owned, active projects within current paid capacity. An empty selection releases all slots."
      },
      "BillingPromotions": {
        "type": "object",
        "required": [
          "promotional_credit_usd",
          "free_shared_emails",
          "branding_removed_until",
          "promotions"
        ],
        "properties": {
          "promotional_credit_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40,
            "description": "Unexpired promotional message credit available now."
          },
          "free_shared_emails": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647,
            "description": "Unexpired free shared emails available now."
          },
          "branding_removed_until": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ],
            "description": "When the latest active branding promotion ends, if one is active."
          },
          "promotions": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/BillingPromotion" },
            "maxItems": 200
          }
        },
        "additionalProperties": false,
        "description": "An organization's promotions: rewards WhooshBang gave it and promotion codes it redeemed, newest first."
      },
      "BillingPromotion": {
        "type": "object",
        "required": [
          "id",
          "source",
          "name",
          "status",
          "starts_at",
          "ends_at",
          "ended_at",
          "benefit"
        ],
        "properties": {
          "id": { "type": "string", "pattern": "^grn_[0-9a-z]{26}$" },
          "source": {
            "type": "string",
            "enum": ["whooshbang", "code"],
            "description": "`whooshbang` for a reward WhooshBang gave the organization directly; `code` for a promotion code the organization redeemed."
          },
          "name": {
            "anyOf": [
              { "type": "string", "minLength": 1, "maxLength": 120 },
              { "type": "null" }
            ],
            "description": "The promotion's name for a redeemed code. Null for a direct reward."
          },
          "status": {
            "type": "string",
            "enum": ["active", "pending", "expired", "used", "revoked"],
            "description": "`pending` is a credit pack discount carried by a payment still waiting for the customer's bank; it is not available to another purchase. `used` applies only to a discount that has been applied to a purchase or put on a plan. `revoked` means WhooshBang withdrew what remained."
          },
          "starts_at": { "type": "string", "format": "date-time" },
          "ends_at": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ],
            "description": "When the benefit stops. Null for a discount, which ends when it is used or, for a plan discount, after its months."
          },
          "ended_at": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ],
            "description": "When the promotion was used or withdrawn, if it was."
          },
          "benefit": {
            "oneOf": [
              {
                "type": "object",
                "required": ["kind", "credit_usd", "remaining_usd"],
                "properties": {
                  "kind": { "const": "message_credit" },
                  "credit_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40
                  },
                  "remaining_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40
                  }
                },
                "additionalProperties": false,
                "description": "Promotional credit for messages. Spent before purchased, bonus and welcome credit; it never pays the shared-email charge."
              },
              {
                "type": "object",
                "required": ["kind", "shared_emails", "remaining"],
                "properties": {
                  "kind": { "const": "shared_emails" },
                  "shared_emails": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000000
                  },
                  "remaining": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000000
                  }
                },
                "additionalProperties": false,
                "description": "Emails through WhooshBang's shared email service with no shared-email charge. The message itself is still paid for."
              },
              {
                "type": "object",
                "required": ["kind"],
                "properties": { "kind": { "const": "branding" } },
                "additionalProperties": false,
                "description": "WhooshBang branding can be removed from recipient messages until ends_at."
              },
              {
                "type": "object",
                "required": [
                  "kind",
                  "applies_to",
                  "percent_off",
                  "amount_off_usd",
                  "duration",
                  "months"
                ],
                "properties": {
                  "kind": { "const": "discount" },
                  "applies_to": {
                    "type": "string",
                    "enum": ["credit_packs", "subscriptions"]
                  },
                  "percent_off": {
                    "anyOf": [
                      { "type": "integer", "minimum": 1, "maximum": 90 },
                      { "type": "null" }
                    ]
                  },
                  "amount_off_usd": {
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                        "maxLength": 40
                      },
                      { "type": "null" }
                    ]
                  },
                  "duration": {
                    "type": "string",
                    "enum": ["once", "repeating"]
                  },
                  "months": {
                    "anyOf": [
                      { "type": "integer", "minimum": 1, "maximum": 12 },
                      { "type": "null" }
                    ]
                  }
                },
                "additionalProperties": false,
                "description": "Money off the next credit pack, or off plan and add-on charges for one charge or a number of months."
              }
            ]
          }
        },
        "additionalProperties": false,
        "description": "One promotion an organization holds. Promotional value has no cash value, is never refunded and cannot move to another organization."
      },
      "RedeemBillingPromotionRequest": {
        "type": "object",
        "required": ["code"],
        "properties": {
          "code": {
            "type": "string",
            "minLength": 4,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9 _-]*$",
            "description": "The promotion code. Case, spaces, hyphens and underscores are ignored."
          }
        },
        "additionalProperties": false
      },
      "BillingEntitlements": {
        "type": "object",
        "required": [
          "content_retention_days",
          "plan",
          "project_capacity",
          "can_hide_attribution",
          "paid_through",
          "live_notifications_remaining",
          "shared_emails_remaining",
          "allowance_period_end",
          "offers",
          "has_subscription",
          "recurring_available",
          "payment_issue"
        ],
        "properties": {
          "content_retention_days": {
            "type": "integer",
            "enum": [7, 90],
            "description": "Current retention window for new notification content. Verified payments extend content still present; irreversible purges are never recovered. Previously captured paid windows do not shrink."
          },
          "plan": { "type": "string", "enum": ["payg", "team", "agency"] },
          "project_capacity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "can_hide_attribution": { "type": "boolean" },
          "paid_through": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ]
          },
          "live_notifications_remaining": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "maxLength": 20
          },
          "shared_emails_remaining": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)$",
            "maxLength": 20
          },
          "allowance_period_end": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ]
          },
          "recurring_available": {
            "type": "boolean",
            "description": "Whether plans and add-ons can be bought now. False when the deployment has no recurring catalog or cannot take payments."
          },
          "offers": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "kind",
                "monthly_price_usd",
                "live_notifications",
                "shared_emails",
                "included_projects",
                "hide_attribution"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": ["team", "agency", "attribution", "project"]
                },
                "monthly_price_usd": {
                  "type": "string",
                  "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                  "maxLength": 40
                },
                "live_notifications": {
                  "type": "string",
                  "pattern": "^(0|[1-9][0-9]*)$",
                  "maxLength": 20
                },
                "shared_emails": {
                  "type": "string",
                  "pattern": "^(0|[1-9][0-9]*)$",
                  "maxLength": 20
                },
                "included_projects": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2147483647
                },
                "hide_attribution": { "type": "boolean" }
              },
              "additionalProperties": false
            }
          },
          "has_subscription": { "type": "boolean" },
          "pending_subscription_change_id": {
            "type": ["string", "null"],
            "pattern": "^subscription_change_[a-f0-9]{32}$",
            "minLength": 52,
            "maxLength": 52
          },
          "payment_issue": {
            "anyOf": [
              { "type": "null" },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["amount_usd", "next_attempt_at"],
                "properties": {
                  "amount_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40
                  },
                  "next_attempt_at": {
                    "anyOf": [
                      { "type": "string", "format": "date-time" },
                      { "type": "null" }
                    ]
                  }
                }
              }
            ],
            "description": "A recurring charge the default card did not pay. Paid access continues until the paid boundary; another attempt follows at next_attempt_at, or none when null. Update the card to settle it."
          },
          "recurring_selection": {
            "$ref": "#/components/schemas/SubscriptionSelection",
            "description": "Selection that will renew; paid project capacity can also include dropped extras until their original expiry. Optional for compatibility with older servers."
          }
        },
        "additionalProperties": false
      },
      "SubscriptionSelection": {
        "type": "object",
        "required": ["plan", "hide_attribution", "additional_projects"],
        "properties": {
          "plan": { "type": "string", "enum": ["payg", "team", "agency"] },
          "hide_attribution": {
            "type": "boolean",
            "description": "Remove WhooshBang branding from recipient emails, messages and subscription pages."
          },
          "additional_projects": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000,
            "description": "Extra projects beyond the plan's included projects, each billed monthly."
          }
        },
        "additionalProperties": false,
        "description": "An account's recurring selection: a plan, branding removal and extra projects. The server selects approved prices and allowances. Branding removal is included on Team and Agency; Pay as you go may add it. Choosing Pay as you go with nothing else ends every recurring charge at the paid boundary."
      },
      "SubscriptionChange": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "status",
          "selection",
          "monthly_price_usd",
          "charge_now_usd",
          "unused_time_credit_usd",
          "promotion",
          "renewal_promotion",
          "effective_at",
          "expires_at",
          "client_secret",
          "failure",
          "publishable_key"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^subscription_change_[a-f0-9]{32}$",
            "minLength": 52,
            "maxLength": 52
          },
          "kind": {
            "type": "string",
            "enum": ["start", "upgrade", "boundary"]
          },
          "status": {
            "type": "string",
            "enum": [
              "reserved",
              "processing",
              "pending",
              "scheduled",
              "applied",
              "expired"
            ]
          },
          "selection": { "$ref": "#/components/schemas/SubscriptionSelection" },
          "monthly_price_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "charge_now_usd": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                "maxLength": 40
              },
              { "type": "null" }
            ]
          },
          "unused_time_credit_usd": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                "maxLength": 40
              },
              { "type": "null" }
            ],
            "description": "Compatibility field: new upgrades return 0.000000; starts and boundary changes return null. Historical quotes can retain their recorded unused-time credit. No new automatic unused-time refunds or offsets."
          },
          "promotion": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "percent_off",
                  "duration",
                  "months",
                  "discount_usd"
                ],
                "properties": {
                  "percent_off": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90
                  },
                  "duration": {
                    "type": "string",
                    "enum": ["once", "repeating"]
                  },
                  "months": {
                    "anyOf": [
                      { "type": "integer", "minimum": 1, "maximum": 12 },
                      { "type": "null" }
                    ]
                  },
                  "discount_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40,
                    "description": "What the promotion takes off charge_now_usd."
                  }
                },
                "additionalProperties": false
              },
              { "type": "null" }
            ],
            "description": "A promotion code's plan discount applied to this first plan or add-on purchase: charge_now_usd is already reduced by it, and the monthly charges keep it for its months. Null when no plan discount applies."
          },
          "renewal_promotion": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "percent_off",
                  "duration",
                  "renewal_price_usd",
                  "ends_at"
                ],
                "properties": {
                  "percent_off": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90
                  },
                  "duration": {
                    "type": "string",
                    "enum": ["once", "repeating"]
                  },
                  "renewal_price_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40,
                    "description": "What the next monthly charge for this selection comes to with the promotion: monthly_price_usd less its percentage."
                  },
                  "ends_at": {
                    "anyOf": [
                      { "type": "string", "format": "date-time" },
                      { "type": "null" }
                    ],
                    "description": "When a repeating promotion stops applying. Null for a once promotion, which applies to the next monthly charge only."
                  }
                },
                "additionalProperties": false
              },
              { "type": "null" }
            ],
            "description": "A plan discount already running on the subscription, which keeps lowering the monthly charges after this change. It never reduces charge_now_usd. Null when none applies to the next monthly charge, and once a change is no longer a quote."
          },
          "effective_at": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ]
          },
          "expires_at": { "type": "string", "format": "date-time" },
          "client_secret": {
            "anyOf": [
              { "type": "string", "minLength": 1, "maxLength": 512 },
              { "type": "null" }
            ],
            "description": "Present only while the card issuer asks the customer to confirm this charge in the payment form."
          },
          "publishable_key": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^pk_(test|live)_[A-Za-z0-9]{1,250}$"
              },
              { "type": "null" }
            ],
            "description": "The public key the payment form uses with client_secret. Present only with client_secret."
          },
          "failure": {
            "anyOf": [
              {
                "type": "string",
                "enum": ["card_declined", "authentication_failed"]
              },
              { "type": "null" }
            ],
            "description": "Why the last charge attempt failed. Update the card, then confirm again."
          }
        },
        "additionalProperties": false,
        "description": "An owned recurring selection. A reserved quote has not charged anything. start buys the first plan or add-on; upgrade charges now, resets the cycle and credits unused paid time; boundary reductions start at the existing paid boundary. Confirm the exact immediate charge; the default card pays it. Processing or pending changes are recovered, never repeated."
      },
      "ConfirmSubscriptionChangeRequest": {
        "type": "object",
        "required": ["approved_charge_now_usd"],
        "properties": {
          "approved_charge_now_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40,
            "description": "The exact charge_now_usd from the saved quote; cents only, for explicit card-charge approval."
          }
        },
        "additionalProperties": false
      },
      "ProjectAttribution": {
        "type": "object",
        "required": [
          "hide_attribution",
          "attribution_hidden",
          "can_hide_attribution"
        ],
        "properties": {
          "hide_attribution": { "type": "boolean" },
          "attribution_hidden": { "type": "boolean" },
          "can_hide_attribution": { "type": "boolean" }
        },
        "additionalProperties": false,
        "description": "The saved project preference and current server-enforced paid entitlement. Expiry restores visible attribution without changing sender identity, consent, unsubscribe or answer controls."
      },
      "UpdateProjectAttributionRequest": {
        "type": "object",
        "required": ["hide_attribution"],
        "properties": { "hide_attribution": { "type": "boolean" } },
        "additionalProperties": false
      },
      "UpdateAutoTopUpSettingsRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled",
          "purchase_cents",
          "trigger_cents",
          "monthly_cap_cents"
        ],
        "properties": {
          "enabled": { "type": "boolean" },
          "purchase_cents": {
            "type": "integer",
            "enum": [500, 1000, 2500, 5000, 10000]
          },
          "trigger_cents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "monthly_cap_cents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        }
      },
      "AutoTopUpSettings": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled",
          "purchase_cents",
          "trigger_cents",
          "monthly_cap_cents",
          "available",
          "monthly_reserved_cents",
          "state",
          "card",
          "last_purchase"
        ],
        "properties": {
          "enabled": { "type": "boolean" },
          "purchase_cents": {
            "type": "integer",
            "enum": [500, 1000, 2500, 5000, 10000]
          },
          "trigger_cents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "monthly_cap_cents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "available": { "type": "boolean" },
          "monthly_reserved_cents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "state": {
            "type": "string",
            "enum": [
              "disabled",
              "needs_card",
              "ready",
              "processing",
              "card_update_required",
              "monthly_cap_reached"
            ]
          },
          "card": {
            "anyOf": [
              { "type": "null" },
              { "$ref": "#/components/schemas/BillingCard" }
            ]
          },
          "last_purchase": {
            "anyOf": [
              { "type": "null" },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "id",
                  "purchase_cents",
                  "credit_usd",
                  "completed_at"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^auto_top_up_[a-f0-9]{32}$"
                  },
                  "purchase_cents": {
                    "type": "integer",
                    "enum": [500, 1000, 2500, 5000, 10000]
                  },
                  "credit_usd": {
                    "type": "string",
                    "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                    "maxLength": 40
                  },
                  "completed_at": { "type": "string", "format": "date-time" }
                }
              }
            ],
            "description": "The most recent paid automatic purchase, if any."
          }
        },
        "description": "Automatic top-up is off by default. When on, the default card buys the selected pack whenever credit falls below the trigger. The monthly cap counts pending and paid purchases started in each UTC calendar month; refunds do not restore it. Turning it off stops future purchases; one already processing may finish. needs_card means there is no default card yet."
      },
      "BillingAccount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "currency",
          "purchased_credit_usd",
          "bonus_credit_usd",
          "starter_credit_usd",
          "available_core_credit_usd",
          "available_email_credit_usd",
          "core_price_per_1000_usd",
          "shared_email_price_per_1000_usd",
          "purchases_available",
          "packs",
          "card",
          "receipt_email"
        ],
        "properties": {
          "currency": { "const": "USD" },
          "purchased_credit_usd": {
            "type": "string",
            "pattern": "^-?(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "bonus_credit_usd": {
            "type": "string",
            "pattern": "^-?(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "starter_credit_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "available_core_credit_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "available_email_credit_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "core_price_per_1000_usd": { "const": "3.000000" },
          "shared_email_price_per_1000_usd": { "const": "1.000000" },
          "purchases_available": {
            "type": "boolean",
            "description": "Whether this deployment can take card payments now. When false, credit, plans and add-ons cannot be bought."
          },
          "packs": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["purchase_cents", "core_credit_usd"],
              "properties": {
                "purchase_cents": {
                  "type": "integer",
                  "enum": [500, 1000, 2500, 5000, 10000]
                },
                "core_credit_usd": {
                  "type": "string",
                  "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
                  "maxLength": 40
                }
              }
            }
          },
          "card": {
            "anyOf": [
              { "type": "null" },
              { "$ref": "#/components/schemas/BillingCard" }
            ]
          },
          "receipt_email": {
            "anyOf": [
              { "type": "null" },
              { "$ref": "#/components/schemas/EmailAddress" }
            ],
            "description": "Where receipts and invoices are emailed. Null sends none."
          }
        },
        "description": "Shared account message credit. Bonus funds core sends only; shared email draws purchased or starter credit. Amounts are exact USD decimal strings. Negative purchased or bonus balances retain refund debt and are not spendable."
      },
      "BillingCard": {
        "type": "object",
        "additionalProperties": false,
        "required": ["brand", "last_four", "exp_month", "exp_year"],
        "properties": {
          "brand": { "type": "string", "minLength": 1, "maxLength": 32 },
          "last_four": { "type": "string", "pattern": "^[0-9]{4}$" },
          "exp_month": { "type": "integer", "minimum": 1, "maximum": 12 },
          "exp_year": { "type": "integer", "minimum": 2000, "maximum": 9999 }
        },
        "description": "The organization's one default card. It pays for credit, automatic top-up, plans and add-ons. Only the brand, last four digits and expiry are ever returned."
      },
      "CardSetup": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "client_secret",
          "publishable_key",
          "card"
        ],
        "properties": {
          "id": { "type": "string", "pattern": "^card_setup_[a-f0-9]{32}$" },
          "status": {
            "type": "string",
            "enum": ["open", "complete", "expired"]
          },
          "client_secret": {
            "anyOf": [
              { "type": "string", "minLength": 1, "maxLength": 512 },
              { "type": "null" }
            ]
          },
          "publishable_key": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^pk_(test|live)_[A-Za-z0-9]{1,250}$"
              },
              { "type": "null" }
            ]
          },
          "card": {
            "anyOf": [
              { "type": "null" },
              { "$ref": "#/components/schemas/BillingCard" }
            ]
          }
        },
        "description": "A card form session. A person enters the card in the embeddable payment form mounted with client_secret and publishable_key, then reconciles. A complete setup makes that card the one default card. client_secret is present only while open."
      },
      "CreateCreditPurchaseRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["purchase_cents"],
        "properties": {
          "purchase_cents": {
            "type": "integer",
            "enum": [500, 1000, 2500, 5000, 10000]
          },
          "approved_charge_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40,
            "description": "Optional. The card charge the customer approved: the pack price less any promotion shown to them. When it differs from what would be charged, the purchase is refused with credit_purchase_price_changed and nothing is charged."
          }
        },
        "description": "Buy one credit pack now with the default card. The amount is the explicit approval of the charge."
      },
      "CreditPurchase": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "purchase_cents",
          "credit_usd",
          "charged_usd",
          "discount_usd",
          "status",
          "failure",
          "client_secret",
          "card",
          "publishable_key"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^credit_purchase_[a-f0-9]{32}$"
          },
          "purchase_cents": {
            "type": "integer",
            "enum": [500, 1000, 2500, 5000, 10000]
          },
          "credit_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "charged_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40,
            "description": "What the card is charged: the pack price less any promotional discount. The pack's credit is unchanged."
          },
          "discount_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40,
            "description": "The promotional discount taken off the pack price, or 0.000000."
          },
          "status": {
            "type": "string",
            "enum": ["processing", "requires_action", "paid", "failed"]
          },
          "failure": {
            "anyOf": [
              {
                "type": "string",
                "enum": ["card_declined", "authentication_failed"]
              },
              { "type": "null" }
            ]
          },
          "client_secret": {
            "anyOf": [
              { "type": "string", "minLength": 1, "maxLength": 512 },
              { "type": "null" }
            ]
          },
          "publishable_key": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^pk_(test|live)_[A-Za-z0-9]{1,250}$"
              },
              { "type": "null" }
            ],
            "description": "The public key the payment form uses with client_secret. Present only with client_secret."
          },
          "card": { "$ref": "#/components/schemas/BillingCard" }
        },
        "description": "A credit pack charged to the default card. paid means the credit is in the balance. requires_action means the card issuer asks the customer to confirm in the payment form using client_secret; reconcile afterwards. A failed purchase charged nothing; start a new one after updating the card."
      },
      "BillingInvoice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "created_at",
          "amount_usd",
          "status",
          "purchase_cents",
          "items",
          "period_start",
          "period_end",
          "document_url",
          "document_kind"
        ],
        "properties": {
          "id": { "type": "string", "minLength": 1, "maxLength": 255 },
          "kind": {
            "type": "string",
            "enum": [
              "credit",
              "automatic_top_up",
              "recurring",
              "welcome_credit"
            ]
          },
          "created_at": { "type": "string", "format": "date-time" },
          "amount_usd": {
            "type": "string",
            "pattern": "^(0|[1-9][0-9]*)\\.[0-9]{6}$",
            "maxLength": 40
          },
          "status": {
            "type": "string",
            "enum": [
              "paid",
              "open",
              "void",
              "uncollectible",
              "refunded",
              "free"
            ]
          },
          "purchase_cents": {
            "anyOf": [
              { "type": "integer", "enum": [500, 1000, 2500, 5000, 10000] },
              { "type": "null" }
            ]
          },
          "items": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["kind", "quantity"],
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": ["team", "agency", "attribution", "project"]
                },
                "quantity": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10025
                }
              }
            }
          },
          "period_start": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ]
          },
          "period_end": {
            "anyOf": [
              { "type": "string", "format": "date-time" },
              { "type": "null" }
            ]
          },
          "document_url": {
            "anyOf": [
              { "type": "string", "format": "uri", "maxLength": 4096 },
              { "type": "null" }
            ]
          },
          "document_kind": {
            "anyOf": [
              { "type": "string", "enum": ["invoice", "receipt"] },
              { "type": "null" }
            ]
          }
        },
        "description": "One charge or credit grant. Credit purchases carry purchase_cents; recurring invoices carry their items and paid period. document_url downloads the invoice PDF or opens the receipt."
      },
      "BillingInvoiceCollection": {
        "type": "object",
        "description": "A page of invoices and receipts, newest first.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/BillingInvoice" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "UpdateBillingReceiptEmailRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["email"],
        "properties": {
          "email": {
            "anyOf": [
              { "type": "null" },
              { "$ref": "#/components/schemas/EmailAddress" }
            ],
            "description": "The receipt address, or null."
          }
        },
        "description": "Where receipts and invoices are emailed. Null stops them."
      },
      "OrganizationProjection": {
        "type": "object",
        "description": "The current Clerk organization projected as a WhooshBang tenant. Clerk organization and user identifiers are not public fields.",
        "required": [
          "id",
          "name",
          "status",
          "membership",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "status": { "type": "string", "enum": ["active", "suspended"] },
          "membership": {
            "$ref": "#/components/schemas/OrganizationMembershipSummary"
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "Teammate": {
        "type": "object",
        "description": "One person in the organization, or one invitation to it. Identity-provider identifiers are not public fields.",
        "required": [
          "id",
          "status",
          "role",
          "name",
          "email",
          "projects",
          "is_current_user",
          "created_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "status": { "$ref": "#/components/schemas/TeammateStatus" },
          "role": { "$ref": "#/components/schemas/OrganizationRole" },
          "name": {
            "anyOf": [
              { "type": "null" },
              { "type": "string", "minLength": 1, "maxLength": 200 }
            ],
            "description": "The person's name, when they have given one. Null for an invitation."
          },
          "email": {
            "anyOf": [
              { "type": "null" },
              { "type": "string", "minLength": 1, "maxLength": 320 }
            ],
            "description": "The address the person signs in with, or the address invited."
          },
          "projects": { "$ref": "#/components/schemas/TeammateProjectAccess" },
          "is_current_user": {
            "type": "boolean",
            "description": "Whether this is the person making the request."
          },
          "created_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When they joined, or when the invitation was sent."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When an invitation stops working. Absent for an active teammate."
          }
        },
        "additionalProperties": false
      },
      "TeammateCollection": {
        "type": "object",
        "description": "Everybody in the organization and every open invitation, people first.",
        "required": ["items", "total"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/Teammate" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "TeammateAccessRequest": {
        "type": "object",
        "description": "A role and, except for an admin, at least one project. An admin sees every project and takes no list.",
        "required": ["role"],
        "properties": {
          "role": { "$ref": "#/components/schemas/OrganizationRole" },
          "project_ids": {
            "type": "array",
            "maxItems": 1000,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        },
        "if": { "properties": { "role": { "const": "admin" } } },
        "then": {
          "properties": { "project_ids": { "type": "array", "maxItems": 0 } }
        },
        "else": {
          "required": ["project_ids"],
          "properties": { "project_ids": { "type": "array", "minItems": 1 } }
        },
        "additionalProperties": false
      },
      "InviteTeammateRequest": {
        "type": "object",
        "description": "Invites one person by email with their role and projects in one step.",
        "required": ["email", "role"],
        "properties": {
          "email": { "$ref": "#/components/schemas/EmailAddress" },
          "role": { "$ref": "#/components/schemas/OrganizationRole" },
          "project_ids": {
            "type": "array",
            "maxItems": 1000,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          }
        },
        "if": { "properties": { "role": { "const": "admin" } } },
        "then": {
          "properties": { "project_ids": { "type": "array", "maxItems": 0 } }
        },
        "else": {
          "required": ["project_ids"],
          "properties": { "project_ids": { "type": "array", "minItems": 1 } }
        },
        "additionalProperties": false
      },
      "UpdateProjectRequest": {
        "type": "object",
        "description": "Sets the project privacy policy. Moving from standard to minimal erases stored identifying profile data; moving to private also erases recipient language. Increasing collection does not restore erased data.",
        "required": ["privacy_mode"],
        "properties": {
          "privacy_mode": { "$ref": "#/components/schemas/PrivacyMode" },
          "data_collection_advisory_enabled": {
            "type": "boolean",
            "description": "Opt-in data-collection advisory on recipient connect and confirmation screens. Effective only with Standard privacy. An omitted update preserves the stored setting."
          }
        },
        "additionalProperties": false
      },
      "PrivacyMode": {
        "type": "string",
        "enum": ["minimal", "standard", "private"],
        "description": "Project profile collection policy. standard (the default for new projects) permits messenger profile data, including the name a subscriber's channel gives; minimal keeps recipient language only; private retains delivery routing and the customer-supplied subscriber identifier, with no profile data. Lowering collection erases existing fields the new mode disallows."
      },
      "CreateProjectRequest": {
        "type": "object",
        "description": "Creates one project inside the organization selected by the authenticated human session.",
        "required": ["name", "slug"],
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "default_locale": {
            "$ref": "#/components/schemas/RecipientLanguage",
            "default": "en",
            "description": "The application fallback locale for recipient-owned surfaces when no session, subscriber, or supported provider locale is available."
          },
          "privacy_mode": {
            "$ref": "#/components/schemas/PrivacyMode",
            "default": "standard"
          }
        },
        "additionalProperties": false
      },
      "DefaultNotifierSummary": {
        "type": "object",
        "description": "The default notifier created transactionally with one project environment.",
        "required": [
          "id",
          "environment_id",
          "display_name",
          "status",
          "is_default"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "display_name": { "const": "Default" },
          "status": { "type": "string", "enum": ["active", "disabled"] },
          "is_default": { "const": true }
        },
        "additionalProperties": false
      },
      "ProjectEnvironment": {
        "type": "object",
        "description": "A test or live project environment with its transactionally created default notifier.",
        "required": ["id", "project_id", "kind", "status", "default_notifier"],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "kind": { "$ref": "#/components/schemas/Environment" },
          "status": { "type": "string", "enum": ["active", "disabled"] },
          "default_notifier": {
            "$ref": "#/components/schemas/DefaultNotifierSummary"
          }
        },
        "additionalProperties": false
      },
      "Project": {
        "type": "object",
        "description": "An organization-scoped application project. Production exposes its live environment only; local and staging acceptance also expose test.",
        "required": [
          "id",
          "organization_id",
          "name",
          "slug",
          "status",
          "default_locale",
          "environments",
          "created_at",
          "updated_at",
          "diagnostic_id",
          "privacy_mode"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "organization_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "status": { "type": "string", "enum": ["active", "disabled"] },
          "default_locale": {
            "$ref": "#/components/schemas/RecipientLanguage"
          },
          "environments": {
            "type": "array",
            "minItems": 1,
            "maxItems": 2,
            "x-unique-property": "kind",
            "contains": {
              "type": "object",
              "required": ["kind"],
              "properties": { "kind": { "const": "live" } }
            },
            "items": { "$ref": "#/components/schemas/ProjectEnvironment" }
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "privacy_mode": { "$ref": "#/components/schemas/PrivacyMode" },
          "data_collection_advisory_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Opt-in data-collection advisory on recipient connect and confirmation screens. Effective only with Standard privacy. An omitted update preserves the stored setting."
          }
        },
        "additionalProperties": false
      },
      "ProjectCollection": {
        "type": "object",
        "description": "A stable page of projects inside the authenticated organization.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/Project" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "RecipientLanguage": {
        "type": "string",
        "enum": [
          "en",
          "es",
          "pt-BR",
          "fr",
          "de",
          "it",
          "nl",
          "pl",
          "ru",
          "uk",
          "tr",
          "id",
          "ar",
          "fa",
          "hi",
          "zh-Hans"
        ],
        "description": "A supported canonical recipient language tag."
      },
      "RecipientCopyKey": {
        "type": "string",
        "enum": [
          "hostedConsent.openProvider",
          "hostedConsent.readyDetail",
          "hostedConsent.readyTitle",
          "hostedConsent.slackReadyTitle",
          "hostedConsent.slackReadyDetail",
          "hostedConsent.returnToApplication",
          "consent.accept",
          "consent.deny",
          "consent.prompt",
          "consent.dataCollectionAdvisory",
          "management.heading",
          "management.next",
          "management.pause",
          "management.previous",
          "management.resume",
          "panel.heading",
          "panel.empty",
          "panel.connect",
          "panel.connected",
          "panel.handoffCancelled",
          "panel.loading",
          "panel.prefer",
          "panel.preferenceMoved",
          "panel.preferred",
          "panel.waiting",
          "hostedConsent.activatedDetail",
          "hostedConsent.activatedTitle",
          "hostedConsent.cancelledDetail",
          "hostedConsent.cancelledTitle",
          "hostedConsent.expiredDetail",
          "hostedConsent.expiredTitle",
          "hostedConsent.failedDetail",
          "hostedConsent.failedTitle",
          "hostedConsent.revokedDetail",
          "hostedConsent.revokedTitle",
          "hostedConsent.unavailableDetail",
          "hostedConsent.unavailableTitle",
          "consent.cancelled",
          "consent.confirmed",
          "consent.expired",
          "consent.failed",
          "consent.guidance",
          "consent.rebind",
          "consent.replace",
          "erasure.cancel",
          "erasure.cancelled",
          "erasure.completed",
          "erasure.confirm",
          "erasure.prompt",
          "erasure.retry",
          "management.activeStatus",
          "management.empty",
          "management.invalid",
          "management.pageEmpty",
          "management.pageEmptyControl",
          "management.paused",
          "management.pausedStatus",
          "management.resumed",
          "management.unsubscribe",
          "management.unsubscribed",
          "management.unsupported",
          "notification.input.empty",
          "notification.input.inactive",
          "notification.input.malformed",
          "notification.input.oversized",
          "notification.input.replyRequired",
          "notification.input.unsupported",
          "notification.interaction.cancelled",
          "notification.interaction.expired",
          "notification.interaction.inactive",
          "notification.interaction.recorded",
          "notification.manage",
          "notification.reply",
          "notification.selectPlaceholder",
          "notification.source",
          "gestures.hosted_page.anchored",
          "gestures.hosted_page.followUp",
          "gestures.hosted_page.followUpLead",
          "gestures.plain_reply.anchored",
          "gestures.plain_reply.followUp",
          "gestures.plain_reply.followUpLead",
          "gestures.quoted_reply.anchored",
          "gestures.quoted_reply.followUp",
          "gestures.quoted_reply.followUpLead",
          "gestures.threaded_reply.anchored",
          "gestures.threaded_reply.followUp",
          "gestures.threaded_reply.followUpLead",
          "panel.blockedPopup",
          "panel.confirmUnsubscribe",
          "panel.connectionDegraded",
          "panel.connectionUnhealthy",
          "panel.connectionUnknown",
          "panel.expired",
          "panel.handoffFailed",
          "panel.notPreferred",
          "panel.openInNewTab",
          "panel.pause",
          "panel.paused",
          "panel.preferenceRefused",
          "panel.preferenceUnavailableChoose",
          "panel.preferenceUnavailableConnect",
          "panel.preferenceUnavailablePaused",
          "panel.resume",
          "panel.unavailable",
          "panel.unsubscribe",
          "panel.unsubscribeWarning",
          "panel.channelNames.email",
          "hostedInteraction.openPage",
          "hostedInteraction.chosen",
          "hostedInteraction.chosenDetail",
          "hostedInteraction.confirmChoice",
          "hostedInteraction.submit",
          "hostedInteraction.answerLabel",
          "hostedInteraction.instructions",
          "hostedInteraction.reopen",
          "hostedInteraction.completed",
          "emailSubscription.activatedDetail",
          "emailSubscription.addressLabel",
          "emailSubscription.checkInbox",
          "emailSubscription.confirm",
          "emailSubscription.enterAddress",
          "emailSubscription.subjectPrefix",
          "emailSubscription.poweredBy"
        ],
        "description": "Every recipient-facing text is customizable (owner decision 2026-09-30, FXO-2739). Labels do not change the actions or capability semantics of recipient controls."
      },
      "RecipientCopyOverride": {
        "type": "object",
        "description": "One sparse project + language + string override. Omitted keys continue to use the complete shipped catalog.",
        "required": [
          "project_id",
          "language",
          "key",
          "value",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "language": { "$ref": "#/components/schemas/RecipientLanguage" },
          "key": { "$ref": "#/components/schemas/RecipientCopyKey" },
          "value": {
            "$ref": "#/components/schemas/RecipientCopyOverrideValue"
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "RecipientCopyOverrideCollection": {
        "type": "object",
        "description": "All sparse recipient-copy overrides for one project, optionally filtered to one canonical language, with complete address and length metadata.",
        "required": [
          "customizable_keys",
          "items",
          "maximum_length_by_key",
          "supported_languages"
        ],
        "properties": {
          "customizable_keys": {
            "type": "array",
            "description": "Every recipient-facing text address accepted by the update endpoint.",
            "minItems": 123,
            "maxItems": 123,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/RecipientCopyKey" }
          },
          "items": {
            "type": "array",
            "maxItems": 1952,
            "items": { "$ref": "#/components/schemas/RecipientCopyOverride" }
          },
          "maximum_length_by_key": {
            "type": "object",
            "description": "The exact Unicode code-point ceiling for each customizable string address.",
            "required": [
              "hostedConsent.openProvider",
              "hostedConsent.readyDetail",
              "hostedConsent.readyTitle",
              "hostedConsent.slackReadyTitle",
              "hostedConsent.slackReadyDetail",
              "hostedConsent.returnToApplication",
              "consent.accept",
              "consent.deny",
              "consent.prompt",
              "consent.dataCollectionAdvisory",
              "management.heading",
              "management.next",
              "management.pause",
              "management.previous",
              "management.resume",
              "panel.heading",
              "panel.empty",
              "panel.connect",
              "panel.connected",
              "panel.handoffCancelled",
              "panel.loading",
              "panel.prefer",
              "panel.preferenceMoved",
              "panel.preferred",
              "panel.waiting",
              "hostedConsent.activatedDetail",
              "hostedConsent.activatedTitle",
              "hostedConsent.cancelledDetail",
              "hostedConsent.cancelledTitle",
              "hostedConsent.expiredDetail",
              "hostedConsent.expiredTitle",
              "hostedConsent.failedDetail",
              "hostedConsent.failedTitle",
              "hostedConsent.revokedDetail",
              "hostedConsent.revokedTitle",
              "hostedConsent.unavailableDetail",
              "hostedConsent.unavailableTitle",
              "consent.cancelled",
              "consent.confirmed",
              "consent.expired",
              "consent.failed",
              "consent.guidance",
              "consent.rebind",
              "consent.replace",
              "erasure.cancel",
              "erasure.cancelled",
              "erasure.completed",
              "erasure.confirm",
              "erasure.prompt",
              "erasure.retry",
              "management.activeStatus",
              "management.empty",
              "management.invalid",
              "management.pageEmpty",
              "management.pageEmptyControl",
              "management.paused",
              "management.pausedStatus",
              "management.resumed",
              "management.unsubscribe",
              "management.unsubscribed",
              "management.unsupported",
              "notification.input.empty",
              "notification.input.inactive",
              "notification.input.malformed",
              "notification.input.oversized",
              "notification.input.replyRequired",
              "notification.input.unsupported",
              "notification.interaction.cancelled",
              "notification.interaction.expired",
              "notification.interaction.inactive",
              "notification.interaction.recorded",
              "notification.manage",
              "notification.reply",
              "notification.selectPlaceholder",
              "notification.source",
              "gestures.hosted_page.anchored",
              "gestures.hosted_page.followUp",
              "gestures.hosted_page.followUpLead",
              "gestures.plain_reply.anchored",
              "gestures.plain_reply.followUp",
              "gestures.plain_reply.followUpLead",
              "gestures.quoted_reply.anchored",
              "gestures.quoted_reply.followUp",
              "gestures.quoted_reply.followUpLead",
              "gestures.threaded_reply.anchored",
              "gestures.threaded_reply.followUp",
              "gestures.threaded_reply.followUpLead",
              "panel.blockedPopup",
              "panel.confirmUnsubscribe",
              "panel.connectionDegraded",
              "panel.connectionUnhealthy",
              "panel.connectionUnknown",
              "panel.expired",
              "panel.handoffFailed",
              "panel.notPreferred",
              "panel.openInNewTab",
              "panel.pause",
              "panel.paused",
              "panel.preferenceRefused",
              "panel.preferenceUnavailableChoose",
              "panel.preferenceUnavailableConnect",
              "panel.preferenceUnavailablePaused",
              "panel.resume",
              "panel.unavailable",
              "panel.unsubscribe",
              "panel.unsubscribeWarning",
              "panel.channelNames.email",
              "hostedInteraction.openPage",
              "hostedInteraction.chosen",
              "hostedInteraction.chosenDetail",
              "hostedInteraction.confirmChoice",
              "hostedInteraction.submit",
              "hostedInteraction.answerLabel",
              "hostedInteraction.instructions",
              "hostedInteraction.reopen",
              "hostedInteraction.completed",
              "emailSubscription.activatedDetail",
              "emailSubscription.addressLabel",
              "emailSubscription.checkInbox",
              "emailSubscription.confirm",
              "emailSubscription.enterAddress",
              "emailSubscription.subjectPrefix",
              "emailSubscription.poweredBy"
            ],
            "properties": {
              "hostedConsent.openProvider": { "type": "integer", "const": 80 },
              "hostedConsent.readyDetail": { "type": "integer", "const": 500 },
              "hostedConsent.readyTitle": { "type": "integer", "const": 500 },
              "hostedConsent.slackReadyTitle": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.slackReadyDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.returnToApplication": {
                "type": "integer",
                "const": 80
              },
              "consent.accept": { "type": "integer", "const": 40 },
              "consent.deny": { "type": "integer", "const": 40 },
              "consent.prompt": { "type": "integer", "const": 500 },
              "consent.dataCollectionAdvisory": {
                "type": "integer",
                "const": 500
              },
              "management.heading": { "type": "integer", "const": 500 },
              "management.next": { "type": "integer", "const": 40 },
              "management.pause": { "type": "integer", "const": 40 },
              "management.previous": { "type": "integer", "const": 40 },
              "management.resume": { "type": "integer", "const": 40 },
              "panel.heading": { "type": "integer", "const": 80 },
              "panel.empty": { "type": "integer", "const": 500 },
              "panel.connect": { "type": "integer", "const": 40 },
              "panel.connected": { "type": "integer", "const": 40 },
              "panel.handoffCancelled": { "type": "integer", "const": 500 },
              "panel.loading": { "type": "integer", "const": 500 },
              "panel.prefer": { "type": "integer", "const": 40 },
              "panel.preferenceMoved": { "type": "integer", "const": 500 },
              "panel.preferred": { "type": "integer", "const": 40 },
              "panel.waiting": { "type": "integer", "const": 500 },
              "hostedConsent.activatedDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.activatedTitle": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.cancelledDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.cancelledTitle": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.expiredDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.expiredTitle": { "type": "integer", "const": 500 },
              "hostedConsent.failedDetail": { "type": "integer", "const": 500 },
              "hostedConsent.failedTitle": { "type": "integer", "const": 500 },
              "hostedConsent.revokedDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.revokedTitle": { "type": "integer", "const": 500 },
              "hostedConsent.unavailableDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedConsent.unavailableTitle": {
                "type": "integer",
                "const": 500
              },
              "consent.cancelled": { "type": "integer", "const": 500 },
              "consent.confirmed": { "type": "integer", "const": 500 },
              "consent.expired": { "type": "integer", "const": 500 },
              "consent.failed": { "type": "integer", "const": 500 },
              "consent.guidance": { "type": "integer", "const": 500 },
              "consent.rebind": { "type": "integer", "const": 500 },
              "consent.replace": { "type": "integer", "const": 40 },
              "erasure.cancel": { "type": "integer", "const": 40 },
              "erasure.cancelled": { "type": "integer", "const": 500 },
              "erasure.completed": { "type": "integer", "const": 500 },
              "erasure.confirm": { "type": "integer", "const": 40 },
              "erasure.prompt": { "type": "integer", "const": 500 },
              "erasure.retry": { "type": "integer", "const": 500 },
              "management.activeStatus": { "type": "integer", "const": 40 },
              "management.empty": { "type": "integer", "const": 500 },
              "management.invalid": { "type": "integer", "const": 500 },
              "management.pageEmpty": { "type": "integer", "const": 500 },
              "management.pageEmptyControl": {
                "type": "integer",
                "const": 500
              },
              "management.paused": { "type": "integer", "const": 500 },
              "management.pausedStatus": { "type": "integer", "const": 40 },
              "management.resumed": { "type": "integer", "const": 500 },
              "management.unsubscribe": { "type": "integer", "const": 40 },
              "management.unsubscribed": { "type": "integer", "const": 500 },
              "management.unsupported": { "type": "integer", "const": 500 },
              "notification.input.empty": { "type": "integer", "const": 500 },
              "notification.input.inactive": {
                "type": "integer",
                "const": 500
              },
              "notification.input.malformed": {
                "type": "integer",
                "const": 500
              },
              "notification.input.oversized": {
                "type": "integer",
                "const": 500
              },
              "notification.input.replyRequired": {
                "type": "integer",
                "const": 500
              },
              "notification.input.unsupported": {
                "type": "integer",
                "const": 500
              },
              "notification.interaction.cancelled": {
                "type": "integer",
                "const": 500
              },
              "notification.interaction.expired": {
                "type": "integer",
                "const": 500
              },
              "notification.interaction.inactive": {
                "type": "integer",
                "const": 500
              },
              "notification.interaction.recorded": {
                "type": "integer",
                "const": 500
              },
              "notification.manage": { "type": "integer", "const": 40 },
              "notification.reply": { "type": "integer", "const": 40 },
              "notification.selectPlaceholder": {
                "type": "integer",
                "const": 40
              },
              "notification.source": { "type": "integer", "const": 500 },
              "gestures.hosted_page.anchored": {
                "type": "integer",
                "const": 500
              },
              "gestures.hosted_page.followUp": {
                "type": "integer",
                "const": 500
              },
              "gestures.hosted_page.followUpLead": {
                "type": "integer",
                "const": 500
              },
              "gestures.plain_reply.anchored": {
                "type": "integer",
                "const": 500
              },
              "gestures.plain_reply.followUp": {
                "type": "integer",
                "const": 500
              },
              "gestures.plain_reply.followUpLead": {
                "type": "integer",
                "const": 500
              },
              "gestures.quoted_reply.anchored": {
                "type": "integer",
                "const": 500
              },
              "gestures.quoted_reply.followUp": {
                "type": "integer",
                "const": 500
              },
              "gestures.quoted_reply.followUpLead": {
                "type": "integer",
                "const": 500
              },
              "gestures.threaded_reply.anchored": {
                "type": "integer",
                "const": 500
              },
              "gestures.threaded_reply.followUp": {
                "type": "integer",
                "const": 500
              },
              "gestures.threaded_reply.followUpLead": {
                "type": "integer",
                "const": 500
              },
              "panel.blockedPopup": { "type": "integer", "const": 500 },
              "panel.confirmUnsubscribe": { "type": "integer", "const": 40 },
              "panel.connectionDegraded": { "type": "integer", "const": 40 },
              "panel.connectionUnhealthy": { "type": "integer", "const": 40 },
              "panel.connectionUnknown": { "type": "integer", "const": 80 },
              "panel.expired": { "type": "integer", "const": 500 },
              "panel.handoffFailed": { "type": "integer", "const": 500 },
              "panel.notPreferred": { "type": "integer", "const": 40 },
              "panel.openInNewTab": { "type": "integer", "const": 40 },
              "panel.pause": { "type": "integer", "const": 40 },
              "panel.paused": { "type": "integer", "const": 40 },
              "panel.preferenceRefused": { "type": "integer", "const": 500 },
              "panel.preferenceUnavailableChoose": {
                "type": "integer",
                "const": 500
              },
              "panel.preferenceUnavailableConnect": {
                "type": "integer",
                "const": 500
              },
              "panel.preferenceUnavailablePaused": {
                "type": "integer",
                "const": 500
              },
              "panel.resume": { "type": "integer", "const": 40 },
              "panel.unavailable": { "type": "integer", "const": 500 },
              "panel.unsubscribe": { "type": "integer", "const": 40 },
              "panel.unsubscribeWarning": { "type": "integer", "const": 500 },
              "panel.channelNames.email": { "type": "integer", "const": 40 },
              "hostedInteraction.openPage": { "type": "integer", "const": 40 },
              "hostedInteraction.chosen": { "type": "integer", "const": 500 },
              "hostedInteraction.chosenDetail": {
                "type": "integer",
                "const": 500
              },
              "hostedInteraction.confirmChoice": {
                "type": "integer",
                "const": 40
              },
              "hostedInteraction.submit": { "type": "integer", "const": 40 },
              "hostedInteraction.answerLabel": {
                "type": "integer",
                "const": 500
              },
              "hostedInteraction.instructions": {
                "type": "integer",
                "const": 500
              },
              "hostedInteraction.reopen": { "type": "integer", "const": 500 },
              "emailSubscription.activatedDetail": {
                "type": "integer",
                "const": 500
              },
              "emailSubscription.addressLabel": {
                "type": "integer",
                "const": 40
              },
              "emailSubscription.checkInbox": {
                "type": "integer",
                "const": 500
              },
              "emailSubscription.confirm": { "type": "integer", "const": 500 },
              "emailSubscription.enterAddress": {
                "type": "integer",
                "const": 500
              },
              "emailSubscription.subjectPrefix": {
                "type": "integer",
                "const": 500
              },
              "emailSubscription.poweredBy": {
                "type": "integer",
                "const": 500
              },
              "hostedInteraction.completed": { "type": "integer", "const": 500 }
            },
            "additionalProperties": false
          },
          "supported_languages": {
            "type": "array",
            "description": "Every canonical recipient language independently addressable by the update endpoint.",
            "minItems": 16,
            "maxItems": 16,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/RecipientLanguage" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "UpdateRecipientCopyOverrideRequest": {
        "type": "object",
        "description": "Sets one exact project + language + string value. Delete the same address to restore the shipped default.",
        "required": ["value"],
        "properties": {
          "value": { "$ref": "#/components/schemas/RecipientCopyOverrideValue" }
        },
        "additionalProperties": false,
        "x-max-json-bytes": 2048
      },
      "CreateApiCredentialRequest": {
        "type": "object",
        "description": "Creates one credential inside the project environment selected by the authenticated administration path.",
        "required": ["label", "scopes"],
        "properties": {
          "label": { "type": "string", "minLength": 1, "maxLength": 100 },
          "scopes": { "$ref": "#/components/schemas/ApiCredentialScopeSet" }
        },
        "additionalProperties": false
      },
      "CreateOrganizationCredentialRequest": {
        "type": "object",
        "description": "Creates one credential against the whole organization rather than one project environment.",
        "required": ["label", "scopes"],
        "properties": {
          "label": { "type": "string", "minLength": 1, "maxLength": 100 },
          "scopes": {
            "$ref": "#/components/schemas/OrganizationCredentialScopeSet"
          }
        },
        "additionalProperties": false
      },
      "RotateOrganizationCredentialRequest": {
        "type": "object",
        "description": "Creates a replacement with the same label and scopes and schedules terminal revocation of the replaced credential after the declared overlap.",
        "required": ["overlap_seconds"],
        "properties": {
          "overlap_seconds": {
            "type": "integer",
            "minimum": 0,
            "maximum": 86400
          }
        },
        "additionalProperties": false
      },
      "OrganizationCredentialId": {
        "type": "string",
        "pattern": "^ocred_[A-Za-z0-9_-]{21}[AQgw]$",
        "description": "ocred_ followed by the canonical unpadded base64url encoding of exactly 16 random bytes."
      },
      "OrganizationCredential": {
        "type": "object",
        "description": "Safe organization-scoped API credential metadata. It carries no project or environment, because it names neither: a request does, in its path. It never contains a bearer secret, digest, Clerk identifier, or digest-key reference.",
        "required": [
          "id",
          "prefix",
          "label",
          "scopes",
          "created_by",
          "created_at",
          "status"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OrganizationCredentialId" },
          "prefix": {
            "$ref": "#/components/schemas/OrganizationCredentialPrefix"
          },
          "label": { "type": "string", "minLength": 1, "maxLength": 100 },
          "scopes": {
            "$ref": "#/components/schemas/OrganizationCredentialScopeSet"
          },
          "created_by": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "An opaque WhooshBang member identifier. It is never a Clerk user identifier."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_used_at": { "$ref": "#/components/schemas/Timestamp" },
          "scheduled_revocation_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When an active credential in a rotation overlap becomes terminally revoked."
          },
          "status": { "type": "string", "enum": ["active", "revoked"] },
          "revoked_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "revoked" } },
              "required": ["status"]
            },
            "then": {
              "required": ["revoked_at"],
              "properties": {
                "revoked_at": {},
                "scheduled_revocation_at": false
              }
            },
            "else": { "properties": { "revoked_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "OrganizationCredentialCollection": {
        "type": "object",
        "description": "A stable page of safe organization-credential metadata for one organization.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/OrganizationCredential" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "OrganizationCredentialSecretReveal": {
        "type": "object",
        "description": "The creation-only response. The secret is emitted in this response exactly once and is never available from list, rotate-target, revoke, or later read responses.",
        "required": ["credential", "secret"],
        "properties": {
          "credential": {
            "$ref": "#/components/schemas/OrganizationCredential"
          },
          "secret": {
            "$ref": "#/components/schemas/OrganizationCredentialSecret"
          }
        },
        "additionalProperties": false
      },
      "OrganizationCredentialRotation": {
        "type": "object",
        "description": "A creation-only replacement secret plus safe metadata for the credential it replaces.",
        "required": ["credential", "replaced_credential"],
        "properties": {
          "credential": {
            "$ref": "#/components/schemas/OrganizationCredentialSecretReveal"
          },
          "replaced_credential": {
            "$ref": "#/components/schemas/OrganizationCredential"
          }
        },
        "additionalProperties": false
      },
      "RotateApiCredentialRequest": {
        "type": "object",
        "description": "Creates a replacement with the same label and scopes and schedules terminal revocation of the replaced credential after the declared overlap.",
        "required": ["overlap_seconds"],
        "properties": {
          "overlap_seconds": {
            "type": "integer",
            "minimum": 0,
            "maximum": 86400
          }
        },
        "additionalProperties": false
      },
      "ApiCredentialId": {
        "type": "string",
        "pattern": "^pcred_[A-Za-z0-9_-]{21}[AQgw]$",
        "description": "pcred_ followed by the canonical unpadded base64url encoding of exactly 16 random bytes."
      },
      "ApiCredential": {
        "type": "object",
        "description": "Safe environment-scoped API credential metadata. It never contains a bearer secret, digest, Clerk identifier, or digest-key reference.",
        "required": [
          "id",
          "project_id",
          "environment_id",
          "environment",
          "prefix",
          "label",
          "scopes",
          "created_by",
          "created_at",
          "status"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/ApiCredentialId" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "prefix": { "$ref": "#/components/schemas/ApiCredentialPrefix" },
          "label": { "type": "string", "minLength": 1, "maxLength": 100 },
          "scopes": { "$ref": "#/components/schemas/ApiCredentialScopeSet" },
          "created_by": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "An opaque WhooshBang member identifier. It is never a Clerk user identifier."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_used_at": { "$ref": "#/components/schemas/Timestamp" },
          "scheduled_revocation_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When an active credential in a rotation overlap becomes terminally revoked."
          },
          "status": { "type": "string", "enum": ["active", "revoked"] },
          "revoked_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "revoked" } },
              "required": ["status"]
            },
            "then": {
              "required": ["revoked_at"],
              "properties": {
                "revoked_at": {},
                "scheduled_revocation_at": false
              }
            },
            "else": { "properties": { "revoked_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "ApiCredentialCollection": {
        "type": "object",
        "description": "A stable page of safe credential metadata in one project environment.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/ApiCredential" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "ApiCredentialSecretReveal": {
        "type": "object",
        "description": "The creation-only response. The secret is emitted in this response exactly once and is never available from list, rotate-target, revoke, or later read responses.",
        "required": ["credential", "secret"],
        "properties": {
          "credential": { "$ref": "#/components/schemas/ApiCredential" },
          "secret": { "$ref": "#/components/schemas/ApiCredentialSecret" }
        },
        "additionalProperties": false
      },
      "ApiCredentialRotation": {
        "type": "object",
        "description": "A creation-only replacement secret plus safe metadata for the credential it replaces.",
        "required": ["credential", "replaced_credential"],
        "properties": {
          "credential": {
            "$ref": "#/components/schemas/ApiCredentialSecretReveal"
          },
          "replaced_credential": {
            "$ref": "#/components/schemas/ApiCredential"
          }
        },
        "additionalProperties": false
      },
      "CreateCustomerEndpointRequest": {
        "type": "object",
        "description": "Creates one project/environment endpoint. The service validates the final normalized destination and never returns it from health or diagnostic reads.",
        "required": ["url"],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "minLength": 8,
            "maxLength": 2048,
            "pattern": "^https://[^\\s]+$"
          },
          "event_types": {
            "type": "array",
            "minItems": 1,
            "maxItems": 11,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/CustomerEventType" }
          },
          "local_test": {
            "type": "boolean",
            "default": false,
            "description": "Explicit local-tooling marker. Production deployments reject true even though local test tooling accepts loopback HTTP before persistence."
          }
        },
        "additionalProperties": false
      },
      "RotateCustomerEndpointRequest": {
        "type": "object",
        "required": [],
        "properties": {
          "overlap_seconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 86400,
            "default": 86400
          }
        },
        "additionalProperties": false
      },
      "CustomerEndpoint": {
        "type": "object",
        "description": "Safe endpoint lifecycle and health metadata. URL, signing material, event bodies, answers, and response bodies are structurally absent.",
        "required": [
          "id",
          "project_id",
          "environment_id",
          "environment",
          "status",
          "verification_status",
          "event_types",
          "secret_version",
          "health",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "status": { "$ref": "#/components/schemas/CustomerEndpointStatus" },
          "verification_status": {
            "type": "string",
            "enum": ["pending", "failed", "verified"]
          },
          "event_types": {
            "type": "array",
            "minItems": 1,
            "maxItems": 11,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/CustomerEventType" }
          },
          "secret_version": { "type": "integer", "minimum": 1 },
          "health": {
            "type": "string",
            "enum": ["never_delivered", "healthy", "failing"]
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "verification_attempted_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "verified_at": { "$ref": "#/components/schemas/Timestamp" },
          "rotated_at": { "$ref": "#/components/schemas/Timestamp" },
          "paused_at": { "$ref": "#/components/schemas/Timestamp" },
          "disabled_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_success_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_failure": {
            "$ref": "#/components/schemas/CustomerEndpointFailure"
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "pause_reason": {
            "type": "string",
            "enum": ["customer", "sustained_failure", "probe_failed"]
          },
          "next_probe_at": { "$ref": "#/components/schemas/Timestamp" },
          "recovery_pending": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "CustomerEndpointCollection": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/CustomerEndpoint" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "CustomerEndpointMutationResult": {
        "type": "object",
        "required": ["endpoint"],
        "properties": {
          "endpoint": { "$ref": "#/components/schemas/CustomerEndpoint" },
          "secret": { "$ref": "#/components/schemas/CustomerEndpointSecret" }
        },
        "additionalProperties": false,
        "description": "The initial create/rotate result includes secret. An equivalent idempotent replay returns the same logical endpoint without revealing the secret again."
      },
      "CustomerEndpointAttemptCollection": {
        "type": "object",
        "required": ["endpoint_id", "attempts"],
        "properties": {
          "endpoint_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "attempts": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/CustomerEndpointAttemptDiagnostic"
            }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "CustomerEndpointVerificationChallenge": {
        "type": "object",
        "required": ["schema", "endpoint_id", "challenge"],
        "properties": {
          "schema": { "const": "whooshbang.endpoint-verification.v1" },
          "endpoint_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "challenge": { "type": "string", "pattern": "^[A-Za-z0-9+/]{43}=$" }
        },
        "additionalProperties": false,
        "description": "Exact signed request bytes. A verifier echoes these exact bytes with valid webhook headers to prove it possesses the endpoint secret."
      },
      "BindingSummary": {
        "description": "A safe channel binding identity. Raw Telegram chat and user identifiers are never exposed. An email address is optional and appears only when the organization supplied it under asserted prior consent; shared recipient-observed addresses remain private. Legacy bindings may omit connection_id because no exact connection was recorded when they were authorized.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "status"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "enum": ["telegram", "slack"] },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier",
                "description": "The exact channel connection this binding was authorized through. Absent only on legacy bindings that predate channel connections."
              },
              "status": { "enum": ["active", "paused", "revoked"] }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "connection_id",
              "status",
              "consent"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "const": "email" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": { "enum": ["active", "paused", "revoked"] },
              "consent": {
                "type": "object",
                "required": ["kind", "observed_at"],
                "properties": {
                  "kind": { "const": "recipient_observed" },
                  "observed_at": { "$ref": "#/components/schemas/Timestamp" }
                },
                "additionalProperties": false
              },
              "masked_address": {
                "type": "string",
                "minLength": 3,
                "maxLength": 254,
                "description": "Masked recipient address. Never the full mailbox."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "connection_id",
              "status",
              "address",
              "consent"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "const": "email" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": { "enum": ["active", "paused", "revoked"] },
              "address": {
                "$ref": "#/components/schemas/EmailAddress",
                "description": "The email destination asserted by the organization under prior consent."
              },
              "consent": {
                "type": "object",
                "required": ["kind", "consented_at", "source"],
                "properties": {
                  "kind": { "const": "asserted_prior_consent" },
                  "consented_at": { "$ref": "#/components/schemas/Timestamp" },
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[^\u0000-\u001f-  ]+$"
                  },
                  "asserted_at": { "$ref": "#/components/schemas/Timestamp" },
                  "asserted_by": {
                    "type": "object",
                    "required": ["kind", "id"],
                    "properties": {
                      "kind": { "enum": ["credential", "grant", "session"] },
                      "id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
                    },
                    "additionalProperties": false
                  },
                  "domain_id": {
                    "$ref": "#/components/schemas/OpaqueIdentifier"
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "connection_id",
              "status",
              "consent"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "const": "email" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": { "enum": ["active", "paused", "revoked"] },
              "consent": {
                "type": "object",
                "required": [
                  "kind",
                  "consented_at",
                  "source",
                  "asserted_at",
                  "asserted_by",
                  "domain_id"
                ],
                "properties": {
                  "kind": { "const": "asserted_prior_consent" },
                  "consented_at": { "$ref": "#/components/schemas/Timestamp" },
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[^\u0000-\u001f-  ]+$"
                  },
                  "asserted_at": { "$ref": "#/components/schemas/Timestamp" },
                  "asserted_by": {
                    "type": "object",
                    "required": ["kind", "id"],
                    "properties": {
                      "kind": { "enum": ["credential", "grant", "session"] },
                      "id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
                    },
                    "additionalProperties": false
                  },
                  "domain_id": {
                    "$ref": "#/components/schemas/OpaqueIdentifier"
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false,
            "description": "Address-free asserted consent captured on a message. The snapshot survives binding deletion; it never claims recipient verification."
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "connection_id",
              "status",
              "address",
              "basis",
              "service"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "const": "email" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": { "enum": ["active", "paused", "revoked"] },
              "address": {
                "$ref": "#/components/schemas/EmailAddress",
                "description": "The application-verified email destination enrolled for service notices."
              },
              "basis": { "const": "service" },
              "service": {
                "type": "object",
                "required": [
                  "relationship_started_at",
                  "source",
                  "asserted_at",
                  "asserted_by",
                  "domain_id"
                ],
                "properties": {
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[^\u0000-\u001f-  ]+$"
                  },
                  "asserted_at": { "$ref": "#/components/schemas/Timestamp" },
                  "asserted_by": {
                    "type": "object",
                    "required": ["kind", "id"],
                    "properties": {
                      "kind": { "enum": ["credential", "grant", "session"] },
                      "id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
                    },
                    "additionalProperties": false
                  },
                  "domain_id": {
                    "$ref": "#/components/schemas/OpaqueIdentifier"
                  },
                  "relationship_started_at": {
                    "$ref": "#/components/schemas/Timestamp"
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false,
            "description": "Service relationship evidence. No consent claim. Address-free snapshots survive binding deletion."
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment",
              "subscriber_id",
              "notifier_id",
              "channel",
              "connection_id",
              "status",
              "basis",
              "service"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "channel": { "const": "email" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": { "enum": ["active", "paused", "revoked"] },
              "basis": { "const": "service" },
              "service": {
                "type": "object",
                "required": [
                  "relationship_started_at",
                  "source",
                  "asserted_at",
                  "asserted_by",
                  "domain_id"
                ],
                "properties": {
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[^\u0000-\u001f-  ]+$"
                  },
                  "asserted_at": { "$ref": "#/components/schemas/Timestamp" },
                  "asserted_by": {
                    "type": "object",
                    "required": ["kind", "id"],
                    "properties": {
                      "kind": { "enum": ["credential", "grant", "session"] },
                      "id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
                    },
                    "additionalProperties": false
                  },
                  "domain_id": {
                    "$ref": "#/components/schemas/OpaqueIdentifier"
                  },
                  "relationship_started_at": {
                    "$ref": "#/components/schemas/Timestamp"
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false,
            "description": "Service relationship evidence. No consent claim. Address-free snapshots survive binding deletion."
          }
        ]
      },
      "SubscriptionConnectionSummary": {
        "type": "object",
        "description": "The safe identity selected for this authorization. Installation identifiers, numeric provider identifiers, credential references, webhook routes, verifiers, and provider identity digests are never exposed.",
        "required": ["id", "mode", "display_name", "identity"],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "mode": { "$ref": "#/components/schemas/ChannelConnectionMode" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "identity": { "$ref": "#/components/schemas/ConnectionIdentity" }
        },
        "additionalProperties": false
      },
      "CreateSubscriptionLinkRequest": {
        "type": "object",
        "description": "Creates one project- and environment-scoped, single-use authorization link.",
        "required": ["subscriber_id"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "notifier_id": {
            "allOf": [{ "$ref": "#/components/schemas/OpaqueIdentifier" }],
            "default": "default"
          },
          "channels": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "connection_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "Optional exact connection. Otherwise the default or only compatible connection is used."
          },
          "address": {
            "$ref": "#/components/schemas/EmailAddress",
            "description": "The exact recipient address for a server-initiated email verification. It is accepted only when the selected channel is email, stored encrypted, and does not assert consent. Omit it when the recipient will enter the address on the hosted page."
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https?://[^\\s]+$",
            "anyOf": [
              { "type": "string", "pattern": "^https://" },
              {
                "type": "string",
                "pattern": "^http://[^/?#\\s]*\\.test(?::[0-9]{1,5})?(?:[/?#]|$)"
              }
            ],
            "maxLength": 2048,
            "description": "Untrusted redirect input. HTTPS is required outside synthetic .test fixtures; the service never fetches this URL."
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 604800,
            "default": 43200
          },
          "recipient_language": {
            "$ref": "#/components/schemas/RecipientLanguage",
            "description": "The customer application language preference. An administrator subscriber-language override takes precedence. When the application has not set a language, a supported channel-reported language is used before the project default."
          }
        },
        "allOf": [
          {
            "if": { "properties": { "address": {} }, "required": ["address"] },
            "then": { "properties": { "channels": { "const": ["email"] } } }
          }
        ],
        "additionalProperties": false
      },
      "SubscriptionLink": {
        "type": "object",
        "description": "A public subscription-link resource scoped to the authenticated project and environment.",
        "required": [
          "id",
          "project_id",
          "environment",
          "subscriber_id",
          "notifier_id",
          "channels",
          "recipient_language",
          "status",
          "created_at",
          "updated_at",
          "expires_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "channels": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "recipient_language": {
            "$ref": "#/components/schemas/RecipientLanguage"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "activated",
              "expired",
              "cancelled",
              "failed",
              "revoked"
            ]
          },
          "authorization_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 2048,
            "description": "The selected provider's native authorization URL. For newly issued Telegram links it is https://t.me/<selected_bot>?start=<43-character opaque token> and contains no tenant identifier or provider secret."
          },
          "connection": {
            "$ref": "#/components/schemas/SubscriptionConnectionSummary",
            "description": "The immutable connection selection rendered for this authorization. Absent only on legacy resources issued before channel connections were recorded."
          },
          "binding": { "$ref": "#/components/schemas/BindingSummary" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "classified_error": {
            "$ref": "#/components/schemas/ClassifiedError"
          },
          "cancellation_effective": {
            "type": "boolean",
            "description": "Present on cancellation responses; false never claims provider-side deletion."
          },
          "email_verification": {
            "$ref": "#/components/schemas/EmailVerificationSummary"
          }
        },
        "allOf": [
          {
            "if": {
              "type": "object",
              "properties": { "status": { "const": "pending" } },
              "required": ["status"]
            },
            "then": {
              "type": "object",
              "required": ["authorization_url"],
              "properties": { "authorization_url": {} }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "status": { "enum": ["activated", "revoked"] } },
              "required": ["status"]
            },
            "then": {
              "type": "object",
              "required": ["binding"],
              "properties": { "binding": {} }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "status": { "const": "failed" } },
              "required": ["status"]
            },
            "then": {
              "type": "object",
              "required": ["classified_error"],
              "properties": { "classified_error": {} }
            }
          }
        ],
        "additionalProperties": false
      },
      "CreateMessageRequest": {
        "type": "object",
        "description": "Creates one logical message for one subscriber and one resolved channel binding.",
        "required": ["to"],
        "properties": {
          "to": {
            "oneOf": [
              { "$ref": "#/components/schemas/MessageTarget" },
              { "$ref": "#/components/schemas/OpaqueIdentifier" }
            ]
          },
          "notifier_id": {
            "allOf": [{ "$ref": "#/components/schemas/OpaqueIdentifier" }],
            "default": "default"
          },
          "delivery_target": {
            "$ref": "#/components/schemas/MessageDeliveryTarget",
            "description": "Optional routing override. Simulator delivery and the reserved test: subscriber prefix are test-environment-only; live requests are refused with 400 request_invalid. Omit for connection delivery, or for the reserved test-environment simulator default."
          },
          "connection_id": {
            "allOf": [{ "$ref": "#/components/schemas/OpaqueIdentifier" }],
            "description": "Optional channel connection to send through, from the environment's connections. The subscriber must be connected through it; the service never substitutes another connection or provider. A connection the subscriber has not connected through is refused as `subscriber_not_connected` when they are connected through another, and as an unchosen send would be (`subscriber_unbound` or `preferred_binding_unavailable`) when no connected channel can take the message. Omitted, the service chooses: the subscriber's preferred channel when they set one, otherwise the default connection when they are connected there, otherwise the connection they connected through most recently. The accepted message's `binding.connection_id` records the connection used. Implies `delivery_target: connection`."
          },
          "content": { "$ref": "#/components/schemas/MessageContentInput" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "Optional server-authoritative expiry after acceptance, through year 9999. Omit for 24 hours."
          },
          "correlation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "metadata": { "$ref": "#/components/schemas/Metadata" },
          "interaction": {
            "$ref": "#/components/schemas/InteractionSendRequest"
          },
          "purpose": {
            "enum": ["service", "marketing"],
            "default": "service",
            "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
          },
          "category_key": {
            "$ref": "#/components/schemas/MessageCategoryKey",
            "description": "Optional project category. Omitted service sends use Updates; omitted marketing sends use Marketing."
          }
        },
        "allOf": [
          {
            "if": {
              "required": ["connection_id"],
              "properties": { "connection_id": true }
            },
            "then": {
              "properties": { "delivery_target": { "const": "connection" } }
            }
          },
          {
            "anyOf": [
              {
                "required": ["content"],
                "properties": {
                  "content": {
                    "$ref": "#/components/schemas/MessageContentInput"
                  }
                },
                "additionalProperties": true
              },
              {
                "required": ["interaction"],
                "properties": {
                  "interaction": {
                    "$ref": "#/components/schemas/InteractionSendRequest"
                  }
                },
                "additionalProperties": true
              }
            ]
          }
        ],
        "additionalProperties": false
      },
      "DeliveryAttemptSummary": {
        "type": "object",
        "description": "A safe aggregate of delivery attempts. Protected provider responses are excluded.",
        "required": [
          "attempt_count",
          "highest_proven_provider_state",
          "retry_scheduled"
        ],
        "properties": {
          "attempt_count": { "type": "integer", "minimum": 0 },
          "highest_proven_provider_state": {
            "$ref": "#/components/schemas/HighestProvenProviderState"
          },
          "provider_outcome": {
            "type": "string",
            "enum": [
              "delivered",
              "delayed",
              "hard_bounce",
              "complained",
              "suppressed",
              "failed"
            ],
            "description": "The latest authenticated post-acceptance provider outcome. Absence means no such outcome has been recorded."
          },
          "retry_scheduled": { "type": "boolean" },
          "retry_at": { "$ref": "#/components/schemas/Timestamp" },
          "classified_error": { "$ref": "#/components/schemas/ClassifiedError" }
        },
        "allOf": [
          {
            "if": {
              "type": "object",
              "properties": { "retry_scheduled": { "const": true } },
              "required": ["retry_scheduled"]
            },
            "then": {
              "type": "object",
              "required": ["retry_at"],
              "properties": { "retry_at": {} }
            },
            "else": { "type": "object", "properties": { "retry_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "Message": {
        "type": "object",
        "description": "A project- and environment-scoped logical message and its highest proven delivery outcome.",
        "required": [
          "id",
          "project_id",
          "environment",
          "subscriber_id",
          "notifier_id",
          "binding",
          "delivery_target",
          "state",
          "accepted_at",
          "updated_at",
          "expires_at",
          "delivery",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "subscriber_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 254,
            "description": "What to call the subscriber, resolved as on the subscriber's `name`: your display name, otherwise the channel's own name where the privacy setting keeps it. Absent when there is neither."
          },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "category": {
            "$ref": "#/components/schemas/MessageCategorySnapshot",
            "description": "Category as accepted. Absent on messages accepted before categories existed."
          },
          "binding": { "$ref": "#/components/schemas/BindingSummary" },
          "binding_resolution": {
            "type": "string",
            "enum": ["preferred", "notifier_default"],
            "description": "How the exact binding was selected. A present but unavailable preference refuses message creation and therefore never appears as notifier_default fallback."
          },
          "broadcast": {
            "$ref": "#/components/schemas/BroadcastMessageProvenance"
          },
          "delivery_target": {
            "$ref": "#/components/schemas/MessageDeliveryTarget"
          },
          "state": { "$ref": "#/components/schemas/MessageState" },
          "accepted_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" },
          "delivery": { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "correlation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "metadata": { "$ref": "#/components/schemas/Metadata" },
          "interaction": { "$ref": "#/components/schemas/InteractionSummary" },
          "cancellation_effective": {
            "type": "boolean",
            "description": "Present on cancellation responses. False means the provider call was already owned and no deletion is claimed."
          },
          "connection_test_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The connection test that sent this message, when one did. A `subscriber_message` test is a real message and is recorded in the history as one, marked by this field. Absent on every ordinary send."
          },
          "outcome_guidance": {
            "type": "string",
            "const": "Delivery may have been accepted by the provider. No automatic retry is scheduled; create a new message explicitly if another attempt is appropriate."
          },
          "purpose": {
            "enum": ["service", "marketing"],
            "default": "service",
            "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
          }
        },
        "allOf": [
          {
            "if": {
              "type": "object",
              "properties": { "state": { "const": "outcome_unknown" } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "required": ["outcome_guidance"],
              "properties": {
                "outcome_guidance": {},
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "required": ["classified_error"],
                      "properties": {
                        "attempt_count": { "type": "integer", "minimum": 1 },
                        "highest_proven_provider_state": { "const": "none" },
                        "retry_scheduled": { "const": false },
                        "classified_error": {
                          "allOf": [
                            { "$ref": "#/components/schemas/ClassifiedError" },
                            {
                              "type": "object",
                              "properties": {
                                "code": { "const": "provider_outcome_unknown" },
                                "retryable": { "const": false }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": {
                "state": {
                  "enum": [
                    "accepted",
                    "dispatch_pending",
                    "queued",
                    "sending",
                    "provider_accepted",
                    "cancelled",
                    "expired"
                  ]
                }
              },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "properties": { "classified_error": false }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": {
                "state": { "not": { "const": "provider_accepted" } }
              },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "properties": {
                        "highest_proven_provider_state": { "const": "none" }
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "state": { "not": { "const": "retry_wait" } } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "properties": { "retry_scheduled": { "const": false } }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "state": { "const": "provider_accepted" } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "properties": {
                        "attempt_count": { "type": "integer", "minimum": 1 },
                        "highest_proven_provider_state": {
                          "const": "provider_accepted"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "state": { "const": "retry_wait" } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "required": ["classified_error"],
                      "properties": {
                        "attempt_count": { "type": "integer", "minimum": 1 },
                        "retry_scheduled": { "const": true },
                        "classified_error": {
                          "allOf": [
                            { "$ref": "#/components/schemas/ClassifiedError" },
                            {
                              "type": "object",
                              "properties": {
                                "code": { "const": "provider_retryable" },
                                "retryable": { "const": true }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "state": { "const": "terminal_failed" } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "required": ["classified_error"],
                      "properties": {
                        "classified_error": {
                          "allOf": [
                            { "$ref": "#/components/schemas/ClassifiedError" },
                            {
                              "type": "object",
                              "properties": {
                                "code": {
                                  "enum": [
                                    "provider_terminal",
                                    "not_consented_for_marketing",
                                    "category_turned_off"
                                  ]
                                },
                                "retryable": { "const": false }
                              }
                            }
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "if": {
                            "type": "object",
                            "properties": {
                              "classified_error": {
                                "type": "object",
                                "properties": {
                                  "code": { "const": "provider_terminal" }
                                },
                                "required": ["code"]
                              }
                            },
                            "required": ["classified_error"]
                          },
                          "then": {
                            "properties": {
                              "attempt_count": {
                                "type": "integer",
                                "minimum": 1
                              }
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": { "state": { "const": "sending" } },
              "required": ["state"]
            },
            "then": {
              "type": "object",
              "properties": {
                "delivery": {
                  "allOf": [
                    { "$ref": "#/components/schemas/DeliveryAttemptSummary" },
                    {
                      "type": "object",
                      "properties": {
                        "attempt_count": { "type": "integer", "minimum": 1 }
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "properties": {
                "state": {
                  "enum": ["sending", "provider_accepted", "outcome_unknown"]
                },
                "cancellation_effective": { "type": "boolean" }
              },
              "required": ["state", "cancellation_effective"]
            },
            "then": {
              "type": "object",
              "properties": { "cancellation_effective": { "const": false } }
            }
          }
        ],
        "additionalProperties": false
      },
      "Problem": {
        "type": "object",
        "description": "Safe RFC 9457-style Problem Details for the WhooshBang API.",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "diagnostic_id",
          "retryable"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://whooshbang\\.flowxo\\.com/problems/[a-z][a-z0-9_]*$"
          },
          "title": { "type": "string", "minLength": 1, "maxLength": 128 },
          "status": { "type": "integer", "minimum": 400, "maximum": 599 },
          "detail": { "type": "string", "minLength": 1, "maxLength": 1024 },
          "code": { "$ref": "#/components/schemas/ProblemCode" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "retryable": { "type": "boolean" },
          "retry_at": { "$ref": "#/components/schemas/Timestamp" },
          "field_errors": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "#/components/schemas/ProblemFieldError" }
          },
          "provider_failure": {
            "$ref": "#/components/schemas/ProviderFailure",
            "description": "Present only when a provider operation caused the problem. Safe guidance stays in `detail`; provider wire detail is structurally absent."
          },
          "subscriber_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The subscriber a `subscriber_not_connected` problem is about."
          },
          "channel": {
            "$ref": "#/components/schemas/Channel",
            "description": "The channel that subscriber has not connected through the named connection, on `subscriber_not_connected`."
          }
        },
        "allOf": [
          {
            "if": {
              "type": "object",
              "properties": { "retryable": { "const": false } },
              "required": ["retryable"]
            },
            "then": { "type": "object", "properties": { "retry_at": false } }
          }
        ],
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/authentication_required"
              },
              "title": { "const": "Authentication required" },
              "status": { "const": 401 },
              "code": { "const": "authentication_required" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/replay_unavailable"
              },
              "title": { "const": "Replay unavailable" },
              "status": { "const": 409 },
              "code": { "const": "replay_unavailable" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/endpoint_rotation_conflict"
              },
              "title": { "const": "Endpoint rotation conflict" },
              "status": { "const": 409 },
              "code": { "const": "endpoint_rotation_conflict" },
              "retryable": { "const": true }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/project_slug_conflict"
              },
              "title": { "const": "Project slug conflict" },
              "status": { "const": 409 },
              "code": { "const": "project_slug_conflict" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/credential_invalid"
              },
              "title": { "const": "Credential invalid" },
              "status": { "const": 401 },
              "code": { "const": "credential_invalid" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/scope_forbidden"
              },
              "title": { "const": "Scope forbidden" },
              "status": { "const": 403 },
              "code": { "const": "scope_forbidden" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/environment_mismatch"
              },
              "title": { "const": "Environment mismatch" },
              "status": { "const": 403 },
              "code": { "const": "environment_mismatch" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/idempotency_key_required"
              },
              "title": {
                "enum": ["Invalid idempotency key", "Idempotency key required"]
              },
              "status": { "const": 400 },
              "code": { "const": "idempotency_key_required" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/idempotency_conflict"
              },
              "title": { "const": "Idempotency conflict" },
              "status": { "const": 409 },
              "code": { "const": "idempotency_conflict" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/privacy_operation_in_progress"
              },
              "title": { "const": "Privacy operation in progress" },
              "status": { "const": 409 },
              "code": { "const": "privacy_operation_in_progress" },
              "retryable": { "const": true }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/request_invalid"
              },
              "title": { "const": "Request invalid" },
              "status": { "const": 400 },
              "code": { "const": "request_invalid" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/subscriber_unbound"
              },
              "title": { "const": "Subscriber unbound" },
              "status": { "const": 422 },
              "code": { "const": "subscriber_unbound" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/subscriber_not_connected"
              },
              "title": { "const": "Subscriber not connected" },
              "status": { "const": 422 },
              "code": { "const": "subscriber_not_connected" },
              "retryable": { "const": false },
              "subscriber_id": {},
              "channel": {}
            },
            "required": ["subscriber_id", "channel"]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/recipient_configuration_invalid"
              },
              "title": { "const": "Recipient configuration invalid" },
              "status": { "const": 409 },
              "code": { "const": "recipient_configuration_invalid" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/recipient_origin_forbidden"
              },
              "title": { "const": "Recipient origin forbidden" },
              "status": { "const": 403 },
              "code": { "const": "recipient_origin_forbidden" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/return_destination_not_found"
              },
              "title": { "const": "Return destination not found" },
              "status": { "const": 422 },
              "code": { "const": "return_destination_not_found" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/recipient_capability_invalid"
              },
              "title": { "const": "Recipient capability invalid" },
              "status": { "const": 401 },
              "code": { "const": "recipient_capability_invalid" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/recipient_handoff_invalid"
              },
              "title": { "const": "Recipient handoff invalid" },
              "status": { "const": 404 },
              "code": { "const": "recipient_handoff_invalid" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/preferred_binding_conflict"
              },
              "title": { "const": "Preferred binding conflict" },
              "status": { "const": 409 },
              "code": { "const": "preferred_binding_conflict" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/preferred_binding_unavailable"
              },
              "title": { "const": "Preferred binding unavailable" },
              "status": { "const": 422 },
              "code": { "const": "preferred_binding_unavailable" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/subscriber_conflict"
              },
              "title": { "const": "Subscriber conflict" },
              "status": { "const": 409 },
              "code": { "const": "subscriber_conflict" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/subscriber_group_conflict"
              },
              "title": { "const": "Subscriber group conflict" },
              "status": { "const": 409 },
              "code": { "const": "subscriber_group_conflict" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/subscriber_group_archived"
              },
              "title": { "const": "Subscriber group archived" },
              "status": { "const": 409 },
              "code": { "const": "subscriber_group_archived" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/resource_not_found"
              },
              "title": { "const": "Resource not found" },
              "status": { "const": 404 },
              "code": { "const": "resource_not_found" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/resource_expired"
              },
              "title": { "const": "Resource expired" },
              "status": { "const": 404 },
              "code": { "const": "resource_expired" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/cancellation_too_late"
              },
              "title": { "const": "Cancellation too late" },
              "status": { "const": 409 },
              "code": { "const": "cancellation_too_late" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/credential_organization_mismatch"
              },
              "title": { "const": "Credential organization mismatch" },
              "status": { "const": 403 },
              "code": { "const": "credential_organization_mismatch" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/rate_limited"
              },
              "title": { "const": "Rate limited" },
              "status": { "const": 429 },
              "code": { "const": "rate_limited" },
              "retryable": { "const": true }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/provider_retryable"
              },
              "title": { "const": "Provider retryable failure" },
              "status": { "const": 503 },
              "code": { "const": "provider_retryable" },
              "retryable": { "const": true }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/provider_terminal"
              },
              "title": { "const": "Provider terminal failure" },
              "status": { "const": 502 },
              "code": { "const": "provider_terminal" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/provider_outcome_unknown"
              },
              "title": { "const": "Provider outcome unknown" },
              "status": { "const": 502 },
              "code": { "const": "provider_outcome_unknown" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/internal_error"
              },
              "title": { "const": "Internal error" },
              "status": { "const": 500 },
              "code": { "const": "internal_error" },
              "retryable": { "const": true }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/not_consented_for_marketing"
              },
              "title": { "const": "Marketing consent required" },
              "status": { "const": 422 },
              "code": { "const": "not_consented_for_marketing" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/category_not_found"
              },
              "title": { "const": "Message category not found" },
              "status": { "const": 404 },
              "code": { "const": "category_not_found" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/category_purpose_mismatch"
              },
              "title": { "const": "Purpose and category do not match" },
              "status": { "const": 422 },
              "code": { "const": "category_purpose_mismatch" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/category_turned_off"
              },
              "title": { "const": "Message category turned off" },
              "status": { "const": 422 },
              "code": { "const": "category_turned_off" },
              "retryable": { "const": false }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "https://whooshbang.flowxo.com/problems/category_conflict"
              },
              "title": { "const": "Message category conflict" },
              "status": { "const": 409 },
              "code": { "const": "category_conflict" },
              "retryable": { "const": false }
            }
          }
        ],
        "additionalProperties": false
      },
      "InteractionSendRequest": {
        "description": "Options infer select; otherwise confirm. Typed replies require type: input. Omit expiry for 24 hours.",
        "oneOf": [
          { "$ref": "#/components/schemas/ConfirmInteractionSendRequest" },
          { "$ref": "#/components/schemas/SelectInteractionSendRequest" },
          { "$ref": "#/components/schemas/InputInteractionSendRequest" }
        ]
      },
      "InteractionRequest": {
        "description": "A required-type tagged union. C0 supports confirm, single-select, and input only.",
        "oneOf": [
          { "$ref": "#/components/schemas/ConfirmInteractionRequest" },
          { "$ref": "#/components/schemas/SelectInteractionRequest" },
          { "$ref": "#/components/schemas/InputInteractionRequest" }
        ]
      },
      "InteractionSummary": {
        "type": "object",
        "description": "The hosted interaction identity and first-terminal-writer state.",
        "required": ["id", "type", "state", "expires_at"],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier-2" },
          "type": { "type": "string", "enum": ["confirm", "select", "input"] },
          "state": { "$ref": "#/components/schemas/InteractionState" },
          "expires_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          },
          "answered_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "answer_retained": {
            "type": "boolean",
            "description": "Whether the typed answer remains available inside its content-retention window. False preserves the answered terminal fact after answer deletion."
          },
          "answer": {
            "oneOf": [
              { "type": "boolean" },
              { "type": "string", "minLength": 1, "maxLength": 4000 }
            ]
          }
        },
        "allOf": [
          {
            "if": {
              "properties": { "state": { "const": "answered" } },
              "required": ["state"]
            },
            "then": {
              "required": ["answered_at", "answer_retained"],
              "properties": {
                "answered_at": {},
                "answer_retained": {},
                "answer": {}
              },
              "allOf": [
                {
                  "if": {
                    "properties": { "answer_retained": { "const": true } },
                    "required": ["answer_retained"]
                  },
                  "then": {
                    "required": ["answer"],
                    "properties": { "answer": {} }
                  },
                  "else": { "properties": { "answer": false } }
                }
              ]
            },
            "else": {
              "properties": {
                "answered_at": false,
                "answer_retained": false,
                "answer": false
              }
            }
          },
          {
            "if": {
              "properties": { "type": { "const": "confirm" } },
              "required": ["type"]
            },
            "then": { "properties": { "answer": { "type": "boolean" } } }
          },
          {
            "if": {
              "properties": { "type": { "const": "select" } },
              "required": ["type"]
            },
            "then": {
              "properties": {
                "answer": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128,
                  "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
                }
              }
            }
          },
          {
            "if": {
              "properties": { "type": { "const": "input" } },
              "required": ["type"]
            },
            "then": {
              "properties": {
                "answer": { "$ref": "#/components/schemas/TrimmedInputAnswer" }
              }
            }
          }
        ],
        "additionalProperties": false
      },
      "InteractionEvent": {
        "type": "object",
        "description": "An authenticated, immutable human-answer fact. It is data for the consumer and never a command or proof of business success.",
        "required": [
          "schema",
          "id",
          "cursor",
          "type",
          "message_id",
          "interaction_id",
          "channel_context",
          "occurred_at",
          "expires_at"
        ],
        "properties": {
          "schema": { "const": "whooshbang.interaction-event.v1" },
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier-2" },
          "cursor": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128,
            "pattern": "^mcur_[A-Za-z0-9_-]+$",
            "description": "The opaque position of this event in the authenticated machine stream."
          },
          "type": { "const": "interaction.received" },
          "message_id": { "$ref": "#/components/schemas/OpaqueIdentifier-2" },
          "interaction_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier-2"
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          },
          "response": { "$ref": "#/components/schemas/InteractionResponse" },
          "answer_retained": {
            "type": "boolean",
            "description": "False means the content window closed and response was removed. New retained events publish true; a retained legacy event may omit this member during rolling deployment."
          },
          "channel_context": {
            "$ref": "#/components/schemas/SafeChannelContext"
          },
          "occurred_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "expires_at": { "$ref": "#/components/schemas/Timestamp-2" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "answer_retained": { "const": false } },
              "required": ["answer_retained"]
            },
            "then": { "properties": { "response": false } },
            "else": {
              "properties": {
                "response": {
                  "$ref": "#/components/schemas/InteractionResponse"
                }
              },
              "required": ["response"]
            }
          }
        ],
        "additionalProperties": false
      },
      "CreateMachineClientRequest": {
        "type": "object",
        "required": ["machine_id", "notifier_id", "subscriber_id"],
        "properties": {
          "machine_id": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
          },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "subscriber_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier-3"
          },
          "display_name": { "type": "string", "minLength": 1, "maxLength": 120 }
        },
        "additionalProperties": false
      },
      "MachineClient": {
        "type": "object",
        "required": [
          "id",
          "project_id",
          "environment",
          "machine_id",
          "notifier_id",
          "subscriber_id",
          "binding_id",
          "status",
          "scope_summary",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "environment": { "$ref": "#/components/schemas/Environment-2" },
          "machine_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "subscriber_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier-3"
          },
          "binding_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "status": {
            "type": "string",
            "enum": ["provisioning", "active", "revoked"]
          },
          "scope_summary": {
            "$ref": "#/components/schemas/MachineScopeSummary"
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "last_used_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "revoked_at": { "$ref": "#/components/schemas/Timestamp-2" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "revoked" } },
              "required": ["status"]
            },
            "then": {
              "required": ["revoked_at"],
              "properties": { "revoked_at": {} }
            },
            "else": { "properties": { "revoked_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "MachineCredentialId": {
        "type": "string",
        "pattern": "^mcred_[A-Za-z0-9_-]{21}[AQgw]$",
        "description": "mcred_ followed by the canonical unpadded base64url encoding of exactly 16 random bytes."
      },
      "RegisterMachineCredentialRequest": {
        "type": "object",
        "required": ["credential_id", "secret_sha256"],
        "properties": {
          "credential_id": {
            "$ref": "#/components/schemas/MachineCredentialId"
          },
          "secret_sha256": {
            "$ref": "#/components/schemas/MachineSecretDigest"
          }
        },
        "additionalProperties": false
      },
      "MachineCredential": {
        "type": "object",
        "required": [
          "credential_id",
          "machine_client_id",
          "status",
          "scope_summary",
          "created_at"
        ],
        "properties": {
          "credential_id": {
            "$ref": "#/components/schemas/MachineCredentialId"
          },
          "machine_client_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier-3"
          },
          "status": { "type": "string", "enum": ["active", "revoked"] },
          "scope_summary": {
            "$ref": "#/components/schemas/MachineScopeSummary"
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "last_used_at": { "$ref": "#/components/schemas/Timestamp-2" },
          "revoked_at": { "$ref": "#/components/schemas/Timestamp-2" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "revoked" } },
              "required": ["status"]
            },
            "then": {
              "required": ["revoked_at"],
              "properties": { "revoked_at": {} }
            },
            "else": { "properties": { "revoked_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "MachineCursor": {
        "type": "string",
        "minLength": 8,
        "maxLength": 128,
        "pattern": "^mcur_[A-Za-z0-9_-]+$",
        "description": "An opaque position within only the authenticated machine stream."
      },
      "MachineEventPollResponse": {
        "type": "object",
        "required": ["schema", "events", "committed_cursor", "server_time"],
        "properties": {
          "schema": { "const": "whooshbang.machine-events.v1" },
          "events": {
            "type": "array",
            "maxItems": 50,
            "x-unique-property": "cursor",
            "items": { "$ref": "#/components/schemas/InteractionEvent" }
          },
          "committed_cursor": {
            "oneOf": [
              { "$ref": "#/components/schemas/MachineCursor" },
              { "type": "null" }
            ]
          },
          "server_time": { "$ref": "#/components/schemas/Timestamp-2" }
        },
        "additionalProperties": false
      },
      "MachineEventAckRequest": {
        "type": "object",
        "required": ["cursor", "disposition"],
        "properties": {
          "cursor": { "$ref": "#/components/schemas/MachineCursor" },
          "disposition": {
            "$ref": "#/components/schemas/MachineEventAckDisposition"
          },
          "reason_code": {
            "oneOf": [
              { "$ref": "#/components/schemas/QuarantineReasonCode" },
              { "type": "null" }
            ]
          }
        },
        "allOf": [
          {
            "if": {
              "properties": { "disposition": { "const": "quarantined" } },
              "required": ["disposition"]
            },
            "then": {
              "required": ["reason_code"],
              "properties": {
                "reason_code": {
                  "$ref": "#/components/schemas/QuarantineReasonCode"
                }
              }
            },
            "else": { "properties": { "reason_code": { "type": "null" } } }
          }
        ],
        "additionalProperties": false
      },
      "MachineEventAckResponse": {
        "type": "object",
        "required": [
          "event_id",
          "cursor",
          "disposition",
          "acknowledgement_status",
          "committed_cursor",
          "advanced"
        ],
        "properties": {
          "event_id": { "$ref": "#/components/schemas/OpaqueIdentifier-3" },
          "cursor": { "$ref": "#/components/schemas/MachineCursor" },
          "disposition": {
            "$ref": "#/components/schemas/MachineEventAckDisposition"
          },
          "reason_code": {
            "$ref": "#/components/schemas/QuarantineReasonCode"
          },
          "acknowledgement_status": {
            "type": "string",
            "enum": ["recorded", "existing"]
          },
          "committed_cursor": {
            "oneOf": [
              { "$ref": "#/components/schemas/MachineCursor" },
              { "type": "null" }
            ]
          },
          "advanced": { "type": "boolean" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "disposition": { "const": "quarantined" } },
              "required": ["disposition"]
            },
            "then": {
              "required": ["reason_code"],
              "properties": { "reason_code": {} }
            },
            "else": { "properties": { "reason_code": false } }
          }
        ],
        "additionalProperties": false
      },
      "ProviderCapabilities": {
        "$ref": "#/components/schemas/provider-capabilities-v1.schema"
      },
      "ProviderCapabilitiesCollection": {
        "type": "object",
        "required": ["schema", "providers"],
        "properties": {
          "schema": {
            "const": "whooshbang.provider-capabilities-collection.v1"
          },
          "providers": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/provider-capabilities-v1.schema"
            },
            "x-unique-property": "provider"
          },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "ProviderInstallationCollection": {
        "type": "object",
        "required": ["authorization_available", "items", "total"],
        "properties": {
          "authorization_available": {
            "type": "boolean",
            "description": "Whether this deployment is configured to start or reconnect customer-owned provider authorization. False is a deployment capability, never evidence about a tenant or credential."
          },
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/ProviderInstallation" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "ProviderInstallation": {
        "type": "object",
        "description": "An account-owned provider installation. Its WhooshBang id is safe to use only under the authenticated organization scope; provider team ids, OAuth grants, scopes and credentials are absent.",
        "required": [
          "id",
          "provider",
          "display_name",
          "status",
          "health",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "provider": { "const": "email" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": {
            "$ref": "#/components/schemas/ProviderInstallationStatus"
          },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" },
          "failure": { "$ref": "#/components/schemas/ProviderFailure" },
          "authorization_setup": {
            "$ref": "#/components/schemas/ProviderAuthorizationSetup",
            "description": "Short-lived, credential-free OAuth progress for this account installation. Present only while an authorization or reauthorization attempt is resumable or needs a bounded explanation."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "CreateProviderInstallationRequest": {
        "type": "object",
        "description": "Starts a customer-owned email provider authorization. The display name is WhooshBang-local presentation and is never sent to the provider.",
        "required": ["display_name"],
        "properties": {
          "display_name": { "type": "string", "minLength": 1, "maxLength": 100 }
        },
        "additionalProperties": false
      },
      "EmailDomainCollection": {
        "type": "object",
        "required": ["items", "total"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/EmailDomain" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "EmailDomain": {
        "type": "object",
        "description": "An account-owned email domain. Every identifier is a WhooshBang identifier checked under the authenticated organization; provider domain and team identifiers, credentials, raw events and provider errors are absent.",
        "required": [
          "id",
          "installation_id",
          "domain",
          "lifecycle",
          "capabilities",
          "dns_records",
          "guide",
          "health",
          "delivery_policy",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "installation_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "authorized_connection_ids": {
            "type": "array",
            "maxItems": 100,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" },
            "description": "The project/environment connections currently authorized through tenant-checked edges to use this domain. One verified domain may authorize distinct test and live connections without repeating DNS setup."
          },
          "domain": { "$ref": "#/components/schemas/EmailDomainName" },
          "lifecycle": { "$ref": "#/components/schemas/EmailDomainLifecycle" },
          "capabilities": {
            "$ref": "#/components/schemas/EmailDomainCapabilities"
          },
          "dns_records": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "#/components/schemas/EmailDnsRecord" }
          },
          "guide": { "$ref": "#/components/schemas/EmailDomainGuide" },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" },
          "delivery_policy": {
            "$ref": "#/components/schemas/EmailDeliveryPolicy"
          },
          "failure": { "$ref": "#/components/schemas/ProviderFailure" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "CreateEmailDomainRequest": {
        "type": "object",
        "description": "Creates or safely adopts one dedicated domain inside an authorized account-owned installation. No provider team id, API key or OAuth credential can be supplied.",
        "required": ["installation_id", "domain"],
        "properties": {
          "installation_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "domain": { "$ref": "#/components/schemas/EmailDomainName" },
          "tls": {
            "enum": ["opportunistic", "enforced"],
            "default": "opportunistic"
          }
        },
        "additionalProperties": false
      },
      "CreateEmailBindingImportRequest": {
        "type": "object",
        "description": "Creates one durable import scoped by the authenticated organization and the project/environment route. Every row delegates to the ordinary binding operation so imports cannot bypass consent, uniqueness, hold or tenant checks.",
        "required": ["connection_id", "rows"],
        "properties": {
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "rows": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": { "$ref": "#/components/schemas/EmailBindingImportRow" }
          }
        },
        "additionalProperties": false
      },
      "EmailBindingImportJob": {
        "type": "object",
        "required": [
          "id",
          "organization_id",
          "project_id",
          "environment_id",
          "environment",
          "connection_id",
          "status",
          "total_rows",
          "processed_rows",
          "succeeded_rows",
          "failed_rows",
          "failures",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "organization_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier"
          },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "status": {
            "enum": ["pending", "running", "completed", "failed", "cancelled"]
          },
          "total_rows": { "type": "integer", "minimum": 1, "maximum": 1000 },
          "processed_rows": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          },
          "succeeded_rows": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          },
          "failed_rows": { "type": "integer", "minimum": 0, "maximum": 1000 },
          "failures": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "type": "object",
              "description": "One rejected import row. The zero-based row index lets a caller correct and retry only that row; the bounded code and detail use the same safe vocabulary as ordinary request field errors.",
              "required": ["row_index", "code", "detail"],
              "properties": {
                "row_index": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 999
                },
                "code": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-z][a-z0-9_]*$"
                },
                "detail": { "type": "string", "minLength": 1, "maxLength": 512 }
              },
              "additionalProperties": false
            },
            "description": "Bounded row-level refusals. Completed imports report enough detail to identify and correct each rejected row without resubmitting successful rows."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "ProjectRecipientExperience": {
        "type": "object",
        "description": "The project-owned recipient identity, fallback locale, and email answer behavior. Email answers use one click when no setting has been saved.",
        "required": [
          "project_id",
          "default_locale",
          "brand",
          "row_version",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "default_locale": {
            "$ref": "#/components/schemas/RecipientLanguage"
          },
          "brand": { "$ref": "#/components/schemas/RecipientBrand" },
          "email_answer_confirmation": {
            "type": "string",
            "enum": ["one_click", "confirm"],
            "description": "How an email confirm or select button records its bound answer. Defaults to one_click for existing and new projects; free-text answers always use a form."
          },
          "row_version": { "type": "integer", "minimum": 1 },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "RecipientBrandAssetId": {
        "type": "string",
        "pattern": "^asset_[0-9a-f]{32}$",
        "description": "An opaque identifier for one normalized project-owned recipient brand logo."
      },
      "RecipientBrandLogoAsset": {
        "type": "object",
        "description": "Metadata for normalized PNG bytes hosted by WhooshBang. Original upload bytes are never served.",
        "required": [
          "id",
          "content_type",
          "width",
          "height",
          "sha256",
          "created_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/RecipientBrandAssetId" },
          "content_type": { "type": "string", "const": "image/png" },
          "width": { "type": "integer", "minimum": 1, "maximum": 512 },
          "height": { "type": "integer", "minimum": 1, "maximum": 512 },
          "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "RecipientBrandLogoUpload": {
        "type": "object",
        "description": "The normalized asset and project configuration atomically updated to use it.",
        "required": ["asset", "configuration"],
        "properties": {
          "asset": { "$ref": "#/components/schemas/RecipientBrandLogoAsset" },
          "configuration": {
            "$ref": "#/components/schemas/ProjectRecipientExperience"
          }
        },
        "additionalProperties": false
      },
      "NotificationImageAssetId": {
        "type": "string",
        "pattern": "^asset_[0-9a-f]{32}$",
        "description": "An opaque immutable version identity for one environment-owned notification image."
      },
      "NotificationImage": {
        "type": "object",
        "description": "One optional provider-neutral illustrative image. The notification content remains complete without the pixels.",
        "required": ["asset_id", "purpose"],
        "properties": {
          "asset_id": {
            "$ref": "#/components/schemas/NotificationImageAssetId"
          },
          "purpose": { "const": "illustration" },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "pattern": "^(?=.*\\S)[^\\u0000-\\u001F\\u007F]+$",
            "x-max-utf8-bytes": 4000,
            "description": "Optional accessible description preserved by every adapter. Omit it for a decorative illustration; notification text must remain complete without the image."
          }
        },
        "additionalProperties": false
      },
      "TextContent": {
        "type": "object",
        "required": ["type", "text"],
        "properties": {
          "type": { "const": "text" },
          "format": {
            "type": "string",
            "enum": ["plain", "markdown"],
            "description": "Text format. Omitted means plain text. Markdown supports headings, paragraphs, emphasis, strong emphasis, code, lists, quotes and safe HTTP(S) links; raw HTML and remote images are never executed or fetched."
          },
          "text": {
            "description": "The complete notification content. This remains authoritative and sufficient when an adapter cannot render optional structure.",
            "type": "string",
            "minLength": 1,
            "maxLength": 8192,
            "x-max-utf8-bytes": 8192
          },
          "title": {
            "description": "An optional semantic title. The adapter chooses its native presentation.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "sections": {
            "description": "Optional ordered semantic sections that enhance, but never replace, the complete text.",
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "items": { "$ref": "#/components/schemas/StructuredTextSection" }
          },
          "image": { "$ref": "#/components/schemas/NotificationImage" }
        },
        "additionalProperties": false
      },
      "NotificationImageAsset": {
        "type": "object",
        "description": "Safe metadata for one immutable canonical PNG held in the exact project environment. Original upload bytes are never served.",
        "required": [
          "id",
          "content_type",
          "byte_size",
          "width",
          "height",
          "sha256",
          "created_at",
          "expires_at"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/NotificationImageAssetId" },
          "content_type": { "type": "string", "const": "image/png" },
          "byte_size": { "type": "integer", "minimum": 1, "maximum": 524288 },
          "width": { "type": "integer", "minimum": 1, "maximum": 512 },
          "height": { "type": "integer", "minimum": 1, "maximum": 512 },
          "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "The end of the 30-day admission window for new notification references."
          }
        },
        "additionalProperties": false
      },
      "UpdateProjectRecipientExperienceRequest": {
        "type": "object",
        "description": "Replaces the project-owned recipient brand and fallback locale under the last observed row version. Omission of email_answer_confirmation preserves its current value, or one_click for an unwritten project.",
        "required": ["default_locale", "brand", "row_version"],
        "properties": {
          "default_locale": {
            "$ref": "#/components/schemas/RecipientLanguage"
          },
          "brand": { "$ref": "#/components/schemas/RecipientBrand" },
          "email_answer_confirmation": {
            "type": "string",
            "enum": ["one_click", "confirm"],
            "description": "Optional project-wide email answer behavior. Omission preserves the current value."
          },
          "row_version": { "type": "integer", "minimum": 1 }
        },
        "additionalProperties": false
      },
      "EnvironmentRecipientExperience": {
        "type": "object",
        "description": "One revisioned environment's recipient-connectable channels and exact browser return policy.",
        "required": [
          "project_id",
          "environment_id",
          "environment",
          "revision",
          "enabled_channels",
          "connectable_channels",
          "allowed_origins",
          "return_destinations",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "revision": { "type": "integer", "minimum": 1 },
          "enabled_channels": {
            "type": "array",
            "maxItems": 8,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "connectable_channels": {
            "type": "array",
            "maxItems": 8,
            "uniqueItems": true,
            "description": "The channels a recipient can complete an authorization on right now: the environment's default notifier routes to a working connection for each. Resolved when this is read, the same way a recipient session resolves it. An enabled channel missing from this list is not offered to recipients until it has a working connection again.",
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "allowed_origins": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/ExactOrigin" }
          },
          "return_destinations": {
            "type": "array",
            "maxItems": 20,
            "x-unique-property": "key",
            "items": { "$ref": "#/components/schemas/ReturnDestination" }
          },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "UpdateEnvironmentRecipientExperienceRequest": {
        "type": "object",
        "description": "Replaces one complete environment recipient policy under its last observed revision.",
        "required": [
          "revision",
          "enabled_channels",
          "allowed_origins",
          "return_destinations"
        ],
        "properties": {
          "revision": { "type": "integer", "minimum": 1 },
          "enabled_channels": {
            "type": "array",
            "maxItems": 8,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "allowed_origins": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/ExactOrigin" }
          },
          "return_destinations": {
            "type": "array",
            "maxItems": 20,
            "x-unique-property": "key",
            "items": { "$ref": "#/components/schemas/ReturnDestination" }
          }
        },
        "additionalProperties": false
      },
      "SubscriberChannelSettings": {
        "type": "object",
        "description": "Safe channel settings for one subscriber in the authorized project environment. Management never establishes or revives revoked consent.",
        "required": ["subscriber_id", "channels", "diagnostic_id"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "channels": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/RecipientChannelSummary" }
          },
          "preference": { "$ref": "#/components/schemas/PreferredBinding" },
          "send_route": {
            "type": "object",
            "description": "The connection a message to this subscriber goes through when the sender names none, chosen exactly as a send made now would choose it. Absent when no connected channel can take a message, which a send refuses as `subscriber_unbound`, or when the subscriber's preferred channel cannot, which a send refuses as `preferred_binding_unavailable`.",
            "required": ["binding_id", "channel", "reason"],
            "properties": {
              "binding_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier",
                "description": "Absent only on a legacy binding that predates channel connections."
              },
              "channel": { "$ref": "#/components/schemas/Channel" },
              "reason": {
                "type": "string",
                "enum": [
                  "preferred",
                  "default_connection",
                  "most_recently_connected"
                ],
                "description": "Why this connection: the subscriber's preferred channel, the default connection, or, when the subscriber is not connected through the default, the connection they connected through most recently."
              }
            },
            "additionalProperties": false
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "AcknowledgeEmailRemediationRequest": {
        "type": "object",
        "description": "An organization administrator acknowledges that the cause of the email sending hold has been remediated. This never reactivates revoked or suppressed recipients.",
        "required": ["acknowledged"],
        "properties": { "acknowledged": { "const": true } },
        "additionalProperties": false
      },
      "CreateRecipientSessionRequest": {
        "type": "object",
        "description": "Creates one short-lived browser capability for the authenticated project environment and one subscriber. Configuration, channel selection, groups, messages, and arbitrary return URLs are structurally absent.",
        "required": ["subscriber_id"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "locale": { "$ref": "#/components/schemas/RecipientLanguage" },
          "return_to": { "$ref": "#/components/schemas/DeveloperKey" },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 300,
            "maximum": 3600,
            "default": 900
          }
        },
        "additionalProperties": false
      },
      "CreateRecipientSessionResponse": {
        "type": "object",
        "description": "The only response that reveals the recipient capability. The hosted URL itself carries no capability in its query string.",
        "required": ["session", "browser_capability", "hosted_url"],
        "properties": {
          "session": { "$ref": "#/components/schemas/RecipientSession" },
          "browser_capability": {
            "$ref": "#/components/schemas/RecipientSessionCapability"
          },
          "hosted_url": {
            "type": "string",
            "format": "uri",
            "const": "https://connect.whooshbang.com/recipient-settings",
            "maxLength": 2048,
            "description": "The capability-free exact WhooshBang hosted entry point. The reusable browser capability is never placed in this or any other URL."
          }
        },
        "additionalProperties": false
      },
      "RecipientSession": {
        "type": "object",
        "description": "A browser-safe projection for the exact subscriber selected when the session was created. Organization, project, environment, subscriber, origin, resolved return URL, provider identity, credentials, and group state are structurally absent.",
        "required": [
          "id",
          "capability_prefix",
          "state",
          "configuration_revision",
          "locale",
          "brand",
          "panel_copy",
          "channels",
          "operations",
          "expires_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "capability_prefix": {
            "$ref": "#/components/schemas/RecipientSessionCapabilityPrefix"
          },
          "state": {
            "type": "string",
            "enum": ["active", "expired", "revoked"]
          },
          "configuration_revision": { "type": "integer", "minimum": 1 },
          "locale": { "$ref": "#/components/schemas/RecipientLanguage" },
          "brand": { "$ref": "#/components/schemas/RecipientBrand" },
          "panel_copy": {
            "$ref": "#/components/schemas/RecipientPanelCopyOverrides"
          },
          "channels": {
            "type": "array",
            "maxItems": 8,
            "x-unique-property": "channel",
            "items": { "$ref": "#/components/schemas/RecipientChannelSummary" }
          },
          "preference": {
            "$ref": "#/components/schemas/PreferredBinding",
            "description": "The current exact preference and row version, when one exists. Tenant and subscriber identifiers remain absent."
          },
          "operations": {
            "type": "array",
            "minItems": 1,
            "maxItems": 6,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/RecipientSessionOperation"
            }
          },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "RecipientPanelCopyOverrides": {
        "type": "object",
        "description": "Sparse recipient panel text for the session locale. Every displayed string is customizable; pause, resume and unsubscribe capability semantics stay fixed.",
        "properties": {
          "heading": { "type": "string", "minLength": 1, "maxLength": 80 },
          "empty": { "type": "string", "minLength": 1, "maxLength": 500 },
          "connect": { "type": "string", "minLength": 1, "maxLength": 40 },
          "connected": { "type": "string", "minLength": 1, "maxLength": 40 },
          "handoffCancelled": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "loading": { "type": "string", "minLength": 1, "maxLength": 500 },
          "prefer": { "type": "string", "minLength": 1, "maxLength": 40 },
          "preferenceMoved": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "preferred": { "type": "string", "minLength": 1, "maxLength": 40 },
          "waiting": { "type": "string", "minLength": 1, "maxLength": 500 },
          "blockedPopup": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "confirmUnsubscribe": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "connectionDegraded": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "connectionUnhealthy": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "connectionUnknown": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "expired": { "type": "string", "minLength": 1, "maxLength": 500 },
          "handoffFailed": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "notPreferred": { "type": "string", "minLength": 1, "maxLength": 40 },
          "openInNewTab": { "type": "string", "minLength": 1, "maxLength": 40 },
          "pause": { "type": "string", "minLength": 1, "maxLength": 40 },
          "paused": { "type": "string", "minLength": 1, "maxLength": 40 },
          "preferenceRefused": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "preferenceUnavailableChoose": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "preferenceUnavailableConnect": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "preferenceUnavailablePaused": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "resume": { "type": "string", "minLength": 1, "maxLength": 40 },
          "unavailable": { "type": "string", "minLength": 1, "maxLength": 500 },
          "unsubscribe": { "type": "string", "minLength": 1, "maxLength": 40 },
          "unsubscribeWarning": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "channelNames": {
            "type": "object",
            "properties": {
              "email": { "type": "string", "minLength": 1, "maxLength": 40 }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "CreateProviderHandoffRequest": {
        "type": "object",
        "description": "Requests one single-use provider handoff for a channel already enabled by the session's pinned configuration revision.",
        "required": ["channel", "completion"],
        "properties": {
          "channel": { "$ref": "#/components/schemas/Channel" },
          "completion": {
            "$ref": "#/components/schemas/ProviderHandoffCompletionMode"
          }
        },
        "additionalProperties": false
      },
      "ProviderHandoff": {
        "type": "object",
        "description": "One independently expiring, opaque, single-use provider handoff. Callback/provider selection is bound server-side and cannot be substituted by a browser field.",
        "required": [
          "id",
          "channel",
          "state",
          "handoff_url",
          "completion",
          "expires_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "channel": { "$ref": "#/components/schemas/Channel" },
          "state": {
            "type": "string",
            "enum": ["pending", "completed", "expired", "consumed"]
          },
          "handoff_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://connect\\.whooshbang\\.com/handoffs/wb_rh1\\.rhc_[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}$",
            "maxLength": 2048,
            "description": "A WhooshBang-hosted exact handoff URL containing an independently random single-use capability. It contains neither the public handoff id, recipient-session capability, nor a caller-selected callback."
          },
          "completion": {
            "$ref": "#/components/schemas/ProviderHandoffCompletionMode"
          },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "RecipientHandoffCompletion": {
        "type": "object",
        "description": "The closed popup/redirect completion payload. A popup accepts it only from WhooshBang's exact hosted origin and after matching the opener nonce.",
        "required": ["schema", "session_id", "handoff_id", "status", "mode"],
        "properties": {
          "schema": { "const": "whooshbang.recipient-handoff-completion.v1" },
          "session_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "handoff_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "status": {
            "type": "string",
            "enum": ["connected", "cancelled", "failed"]
          },
          "mode": { "type": "string", "enum": ["popup", "redirect"] },
          "opener_nonce": {
            "type": "string",
            "minLength": 22,
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_-]+$"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": { "mode": { "const": "popup" } },
              "required": ["mode"]
            },
            "then": {
              "required": ["opener_nonce"],
              "properties": { "opener_nonce": {} }
            },
            "else": { "properties": { "opener_nonce": false } }
          }
        ],
        "additionalProperties": false
      },
      "SetPreferredBindingRequest": {
        "type": "object",
        "description": "Selects one exact active binding already owned by this session's subscriber and offered by this notifier/environment.",
        "required": ["binding_id", "row_version"],
        "properties": {
          "binding_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "row_version": { "type": "integer", "minimum": 0 }
        },
        "additionalProperties": false
      },
      "PreferredBinding": {
        "type": "object",
        "description": "The recipient's one exact preferred binding for the session's subscriber/notifier. Subscriber and tenant identifiers are intentionally absent from the browser projection.",
        "required": [
          "notifier_id",
          "binding_id",
          "connection_id",
          "channel",
          "row_version",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "binding_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "channel": { "$ref": "#/components/schemas/Channel" },
          "row_version": { "type": "integer", "minimum": 1 },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "AssertEmailConsentRequest": {
        "description": "Assert prior consent or enroll an application-verified user for service email on an exact customer-owned connection. Revocation and sending restrictions always win.",
        "oneOf": [
          {
            "type": "object",
            "description": "Atomically create or resolve one subscriber and assert existing consent for an exact customer-owned email connection and domain. No verification message is sent. Revocation, suppression, recipient pause, holds and unhealthy authority take precedence. An omitted source is recorded as customer.",
            "required": [
              "subscriber_id",
              "address",
              "consented",
              "consented_at"
            ],
            "properties": {
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier",
                "default": "default"
              },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "domain_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "address": { "$ref": "#/components/schemas/EmailAddress" },
              "consented": { "const": true },
              "consented_at": {
                "$ref": "#/components/schemas/Timestamp",
                "description": "When the application obtained consent; must not be in the future."
              },
              "source": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "pattern": "^[^\u0000-\u001f-  ]+$",
                "description": "A bounded customer description of where consent was collected. The authenticated asserting actor is recorded by the service, never accepted from this object."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "description": "Enroll an application-verified user for service email. This is relationship evidence, never consent or WhooshBang mailbox verification. An existing prior-consent binding with the same subscriber, address, notifier, connection and domain is reused with its original evidence and status.",
            "required": [
              "subscriber_id",
              "address",
              "basis",
              "source",
              "relationship_started_at"
            ],
            "properties": {
              "subscriber_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "notifier_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier",
                "default": "default"
              },
              "connection_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "domain_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "address": { "$ref": "#/components/schemas/EmailAddress" },
              "source": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "pattern": "^[^\u0000-\u001f-  ]+$",
                "description": "A bounded customer description of the service relationship. The authenticated asserting actor is recorded by the service, never accepted from this object."
              },
              "basis": { "const": "service" },
              "relationship_started_at": {
                "$ref": "#/components/schemas/Timestamp",
                "description": "When the verified user relationship began; must not be in the future."
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "CreateSubscriberRequest": {
        "type": "object",
        "description": "Creates one subscriber and optional initial static-group memberships in one idempotent transaction. Groups are creation-only input, not a membership replacement operation.",
        "required": ["subscriber_id"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The name your application knows this subscriber by, shown in the dashboard wherever the subscriber appears. Kept on every privacy setting, because you chose to send it, and sealed like the subscriber ID."
          },
          "locale": { "$ref": "#/components/schemas/RecipientLanguage" },
          "time_zone": { "$ref": "#/components/schemas/TimeZone" },
          "groups": {
            "type": "array",
            "maxItems": 50,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/GroupKey" }
          }
        },
        "additionalProperties": false
      },
      "Subscriber": {
        "type": "object",
        "description": "An application subscriber with no provider identity or group-member expansion embedded in the resource.",
        "required": [
          "subscriber_id",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The name your application knows this subscriber by, shown in the dashboard wherever the subscriber appears. Kept on every privacy setting, because you chose to send it, and sealed like the subscriber ID."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 254,
            "description": "What to call this subscriber: `display_name` when your application sent one, otherwise the name their channel gave when they connected (a Telegram username, a Slack display name, an email address), which is kept only on the standard privacy setting. Absent when there is neither; show `subscriber_id` then."
          },
          "team_member": {
            "type": "boolean",
            "const": true,
            "description": "Present when this subscriber is someone on your WhooshBang team, messaged through the operators group. `name` is then their WhooshBang account name. They manage their own channels in notification preferences, so the subscriber can be read but not renamed, paused or erased."
          },
          "locale": { "$ref": "#/components/schemas/RecipientLanguage" },
          "time_zone": { "$ref": "#/components/schemas/TimeZone" },
          "channels": {
            "type": "array",
            "maxItems": 3,
            "uniqueItems": true,
            "description": "The channels this subscriber can be reached on in the environment asked about: those with an active or paused connection. Present on reads that name an environment.",
            "items": { "$ref": "#/components/schemas/Channel" }
          },
          "profiles": {
            "type": "array",
            "maxItems": 3,
            "description": "Channel-provided profile details captured on connect in a Standard privacy project. Present on one-subscriber reads that name an environment; empty on Minimal and Private. Photos are embedded image data, never provider URLs or credentials.",
            "items": {
              "type": "object",
              "required": ["channel"],
              "properties": {
                "channel": { "type": "string", "enum": ["slack", "telegram"] },
                "name": { "type": "string", "minLength": 1, "maxLength": 254 },
                "username": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "language": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 64
                },
                "time_zone": { "$ref": "#/components/schemas/TimeZone" },
                "photo_data_url": {
                  "type": "string",
                  "maxLength": 180000,
                  "pattern": "^data:image/(jpeg|png|webp);base64,[A-Za-z0-9+/]+={0,2}$"
                }
              },
              "additionalProperties": false
            }
          },
          "groups": {
            "type": "array",
            "maxItems": 200,
            "uniqueItems": true,
            "description": "The keys of the static groups this subscriber belongs to in the environment asked about. Present when one subscriber is read.",
            "items": { "$ref": "#/components/schemas/GroupKey" }
          },
          "last_activity_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When the subscriber last had a message accepted for them, or a channel connected, paused or resumed, in the environment asked about. Absent when nothing has happened yet."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "effective_locale": {
            "$ref": "#/components/schemas/RecipientLanguage",
            "description": "Language used by WhooshBang: administrator override, then application locale, then channel language, then project default."
          },
          "locale_source": {
            "type": "string",
            "enum": [
              "administrator",
              "application",
              "slack",
              "telegram",
              "project"
            ]
          },
          "locale_override": {
            "$ref": "#/components/schemas/RecipientLanguage",
            "description": "Forced language set by an administrator. Absent when no override is set."
          },
          "effective_time_zone": {
            "$ref": "#/components/schemas/TimeZone",
            "description": "Administrator time-zone override, then application time zone, then the Slack profile on Standard privacy."
          },
          "time_zone_override": {
            "$ref": "#/components/schemas/TimeZone",
            "description": "Forced canonical IANA time zone. Absent when no override is set."
          },
          "time_zone_source": {
            "type": "string",
            "enum": ["administrator", "application", "slack"]
          }
        },
        "additionalProperties": false
      },
      "UpdateSubscriberRequest": {
        "type": "object",
        "description": "Change subscriber display name, forced language or forced time zone. Null removes the corresponding override.",
        "properties": {
          "display_name": {
            "oneOf": [
              { "type": "string", "minLength": 1, "maxLength": 100 },
              { "type": "null" }
            ]
          },
          "locale_override": {
            "oneOf": [
              { "$ref": "#/components/schemas/RecipientLanguage" },
              { "type": "null" }
            ],
            "description": "Force a language, or clear the override with null. Dashboard-session writes require an administrator."
          },
          "time_zone_override": {
            "oneOf": [
              { "$ref": "#/components/schemas/TimeZone" },
              { "type": "null" }
            ],
            "description": "Force a canonical IANA time zone ahead of the application and Slack profile, or clear the override with null. Dashboard-session writes require an administrator."
          }
        },
        "additionalProperties": false,
        "minProperties": 1
      },
      "SubscriberCollection": {
        "type": "object",
        "description": "One page of a project's subscribers, newest first, with how many match the search and filters.",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/Subscriber" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 8,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$",
            "description": "Present when another page exists; send it as `after` for the next one."
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "SubscriberDataExport": {
        "type": "object",
        "description": "A complete customer-controller access artifact for one subscriber across every environment in one project. provided_by_subscriber is the Article 20 portable subset; all three record groups together are the Article 15 access copy. WhooshBang-controller records are named but never mixed into the customer export.",
        "required": [
          "format",
          "generated_at",
          "controller_scope",
          "project_id",
          "environment_ids",
          "subscriber_id",
          "provided_by_subscriber",
          "provided_by_customer",
          "derived_by_service",
          "excluded_controller_data"
        ],
        "properties": {
          "format": {
            "type": "string",
            "const": "whooshbang.subscriber-data-export.v1"
          },
          "generated_at": { "$ref": "#/components/schemas/Timestamp" },
          "controller_scope": { "type": "string", "const": "customer" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_ids": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" }
          },
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "provided_by_subscriber": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriberDataExportRecord"
            }
          },
          "provided_by_customer": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriberDataExportRecord"
            }
          },
          "derived_by_service": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriberDataExportRecord"
            }
          },
          "excluded_controller_data": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SubscriberDataExportExcludedControllerData"
            }
          }
        },
        "additionalProperties": false
      },
      "CloseOrganizationRequest": {
        "type": "object",
        "description": "Exact, explicit confirmation that the current organization administrator intends to close the whole organization.",
        "required": ["confirmation"],
        "properties": {
          "confirmation": { "type": "string", "const": "close-organization" }
        },
        "additionalProperties": false
      },
      "OrganizationClosureResult": {
        "type": "object",
        "description": "Terminal organization-closure result. Repeating closure returns the same closed_at and any provider-owned resources that still require manual retirement.",
        "required": ["status", "closed_at", "provider_actions_required"],
        "properties": {
          "status": { "type": "string", "const": "closed" },
          "closed_at": { "$ref": "#/components/schemas/Timestamp" },
          "provider_actions_required": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/OrganizationClosureProviderAction"
            }
          }
        },
        "additionalProperties": false
      },
      "CreateSubscriberGroupRequest": {
        "type": "object",
        "description": "Creates one static, developer-managed subscriber group.",
        "required": ["key"],
        "properties": {
          "key": { "$ref": "#/components/schemas/GroupKey" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": { "type": "string", "maxLength": 500 }
        },
        "additionalProperties": false
      },
      "UpdateSubscriberGroupRequest": {
        "type": "object",
        "description": "Renames or redescribes an active group. Its key and static membership model cannot change.",
        "required": [],
        "minProperties": 1,
        "properties": {
          "row_version": { "type": "integer", "minimum": 1 },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": { "type": ["string", "null"], "maxLength": 500 }
        },
        "additionalProperties": false,
        "anyOf": [
          {
            "required": ["display_name"],
            "properties": { "display_name": {} }
          },
          { "required": ["description"], "properties": { "description": {} } }
        ]
      },
      "SubscriberGroup": {
        "type": "object",
        "description": "An environment-scoped static group. Deletion is terminal and reserves the immutable key for history.",
        "required": [
          "id",
          "project_id",
          "environment",
          "key",
          "display_name",
          "status",
          "membership_revision",
          "row_version",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "active_broadcast_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Broadcasts with work still pending at the time this group was read. Present on the group detail response."
          },
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "key": { "$ref": "#/components/schemas/GroupKey" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": { "type": "string", "maxLength": 500 },
          "status": { "type": "string", "enum": ["active", "archived"] },
          "membership_revision": { "type": "integer", "minimum": 0 },
          "row_version": { "type": "integer", "minimum": 1 },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "archived_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "archived" } },
              "required": ["status"]
            },
            "then": {
              "required": ["archived_at"],
              "properties": { "archived_at": {} }
            },
            "else": { "properties": { "archived_at": false } }
          }
        ],
        "additionalProperties": false
      },
      "SubscriberGroupCollection": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": { "$ref": "#/components/schemas/SubscriberGroup" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 8,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "SubscriberGroupMembership": {
        "type": "object",
        "description": "One historical membership generation. Re-adding a removed subscriber creates a larger generation and never revives this one.",
        "required": [
          "group_id",
          "group_key",
          "subscriber_id",
          "generation",
          "added_revision",
          "status",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "group_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "group_key": { "$ref": "#/components/schemas/GroupKey" },
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "subscriber_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 254,
            "description": "What to call the subscriber, resolved as on the subscriber's `name`: your display name, otherwise the channel's own name where the privacy setting keeps it. Absent when there is neither."
          },
          "generation": { "type": "integer", "minimum": 1 },
          "added_revision": { "type": "integer", "minimum": 1 },
          "removed_revision": { "type": "integer", "minimum": 2 },
          "status": { "type": "string", "enum": ["active", "removed"] },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "status": { "const": "removed" } },
              "required": ["status"]
            },
            "then": {
              "required": ["removed_revision"],
              "properties": { "removed_revision": {} }
            }
          },
          {
            "if": {
              "properties": { "status": { "const": "active" } },
              "required": ["status"]
            },
            "then": { "properties": { "removed_revision": false } }
          }
        ],
        "additionalProperties": false
      },
      "SubscriberGroupMembershipCollection": {
        "type": "object",
        "required": ["group_key", "membership_revision", "items"],
        "properties": {
          "group_key": { "$ref": "#/components/schemas/GroupKey" },
          "membership_revision": { "type": "integer", "minimum": 0 },
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/SubscriberGroupMembership"
            }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 8,
            "maxLength": 256,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "page": { "$ref": "#/components/schemas/ListPageNumber" },
          "page_size": { "$ref": "#/components/schemas/ListPageSize" },
          "total": { "$ref": "#/components/schemas/ListTotal" }
        },
        "additionalProperties": false
      },
      "CreateGroupBroadcastRequest": {
        "type": "object",
        "description": "Creates one group broadcast using the existing ordinary message envelope. The group target comes only from the path.",
        "required": [],
        "properties": {
          "notifier_id": {
            "allOf": [{ "$ref": "#/components/schemas/OpaqueIdentifier" }],
            "default": "default"
          },
          "content": { "$ref": "#/components/schemas/MessageContentInput" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "Optional server-authoritative expiry after acceptance, through year 9999. Omit for 24 hours."
          },
          "correlation_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "metadata": { "$ref": "#/components/schemas/Metadata" },
          "interaction": {
            "$ref": "#/components/schemas/InteractionSendRequest"
          },
          "purpose": {
            "enum": ["service", "marketing"],
            "default": "service",
            "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
          },
          "category_key": {
            "$ref": "#/components/schemas/MessageCategoryKey",
            "description": "Optional project category. Omitted service sends use Updates; omitted marketing sends use Marketing."
          }
        },
        "additionalProperties": false,
        "allOf": [
          {
            "anyOf": [
              {
                "required": ["content"],
                "properties": {
                  "content": {
                    "$ref": "#/components/schemas/MessageContentInput"
                  }
                },
                "additionalProperties": true
              },
              {
                "required": ["interaction"],
                "properties": {
                  "interaction": {
                    "$ref": "#/components/schemas/InteractionSendRequest"
                  }
                },
                "additionalProperties": true
              }
            ]
          }
        ]
      },
      "GroupBroadcast": {
        "type": "object",
        "description": "One durable acceptance against an exact group membership revision. Delivery remains represented by ordinary child messages.",
        "required": [
          "id",
          "project_id",
          "environment",
          "group_id",
          "group_key",
          "audience_revision",
          "status",
          "aggregate",
          "accepted_at",
          "updated_at",
          "expires_at",
          "diagnostic_id"
        ],
        "properties": {
          "stopped_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "The broadcast was stopped. Remaining expansion and sends are cancelled; sends already in flight cannot be recalled."
          },
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "group_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "group_key": { "$ref": "#/components/schemas/GroupKey" },
          "audience_revision": { "type": "integer", "minimum": 0 },
          "status": {
            "type": "string",
            "enum": ["accepted", "expanding", "expanded", "complete"]
          },
          "aggregate": { "$ref": "#/components/schemas/BroadcastAggregate" },
          "accepted_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
          "interaction_expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "Authoritatively resolved answer deadline shared by this broadcast’s interactions, independent of delivery expires_at."
          }
        },
        "additionalProperties": false
      },
      "ListTotal": {
        "type": "integer",
        "minimum": 0,
        "description": "How many records the list holds in total, not only on this page. Counted while the page was read, so a write landing between the count and the page can leave it a record or two out of step with `items`. That is noise on an inspection surface; it never changes which records a page addresses."
      },
      "ProblemCode": {
        "type": "string",
        "enum": [
          "authentication_required",
          "credential_invalid",
          "scope_forbidden",
          "environment_mismatch",
          "idempotency_key_required",
          "idempotency_conflict",
          "privacy_operation_in_progress",
          "project_slug_conflict",
          "request_invalid",
          "replay_unavailable",
          "subscriber_unbound",
          "subscriber_not_connected",
          "recipient_configuration_invalid",
          "recipient_origin_forbidden",
          "return_destination_not_found",
          "recipient_capability_invalid",
          "recipient_handoff_invalid",
          "preferred_binding_conflict",
          "preferred_binding_unavailable",
          "subscriber_conflict",
          "subscriber_group_conflict",
          "subscriber_group_archived",
          "resource_not_found",
          "resource_expired",
          "cancellation_too_late",
          "credential_organization_mismatch",
          "endpoint_rotation_conflict",
          "rate_limited",
          "provider_retryable",
          "provider_terminal",
          "provider_outcome_unknown",
          "internal_error",
          "not_consented_for_marketing",
          "category_purpose_mismatch",
          "category_turned_off",
          "category_conflict",
          "category_not_found"
        ]
      },
      "ProblemFieldError": {
        "type": "object",
        "required": ["field", "code", "detail"],
        "properties": {
          "field": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "A bounded JSON Pointer or request field identifier."
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_]*$"
          },
          "detail": { "type": "string", "minLength": 1, "maxLength": 512 }
        },
        "additionalProperties": false
      },
      "ProviderFailure": {
        "description": "A provider-neutral failure whose code is valid for the named public operation. The discriminated arms keep machine handling reliable without exposing provider wire vocabulary.",
        "oneOf": [
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "setup" },
              "code": {
                "enum": [
                  "capability_missing",
                  "installation_invalid",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "authorization" },
              "code": {
                "enum": [
                  "authorization_denied",
                  "authorization_expired",
                  "authorization_pending_approval",
                  "authorization_permission_missing",
                  "installation_invalid",
                  "connection_removed",
                  "whooshbang_configuration",
                  "workspace_mismatch",
                  "refresh_outcome_unknown",
                  "reauthorization_required",
                  "installation_revoked",
                  "provider_cleanup_required",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "domain" },
              "code": {
                "enum": [
                  "authorization_permission_missing",
                  "installation_invalid",
                  "refresh_outcome_unknown",
                  "reauthorization_required",
                  "installation_revoked",
                  "domain_invalid",
                  "domain_conflict",
                  "dns_verification_failed",
                  "provider_action_required",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "webhook" },
              "code": {
                "enum": [
                  "authorization_permission_missing",
                  "installation_invalid",
                  "refresh_outcome_unknown",
                  "reauthorization_required",
                  "installation_revoked",
                  "provider_cleanup_required",
                  "webhook_reconciliation_failed",
                  "provider_action_required",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "delivery" },
              "code": {
                "enum": [
                  "authorization_permission_missing",
                  "installation_invalid",
                  "refresh_outcome_unknown",
                  "reauthorization_required",
                  "installation_revoked",
                  "destination_invalid",
                  "destination_suppressed",
                  "hard_bounce",
                  "delivery_held",
                  "provider_action_required",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "code"],
            "properties": {
              "operation": { "const": "interaction" },
              "code": {
                "enum": [
                  "authorization_permission_missing",
                  "installation_invalid",
                  "refresh_outcome_unknown",
                  "reauthorization_required",
                  "installation_revoked",
                  "provider_cleanup_required",
                  "interaction_invalid",
                  "provider_unavailable",
                  "provider_rate_limited",
                  "provider_rejected",
                  "provider_outcome_unknown"
                ]
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "Channel": {
        "type": "string",
        "enum": ["telegram", "slack", "email"],
        "description": "A provider-neutral delivery channel. Adding a member makes it representable; it does not claim that every deployment has registered an executable adapter."
      },
      "StructuredTextSection": {
        "type": "object",
        "required": ["text"],
        "properties": {
          "heading": {
            "description": "An optional semantic heading for this section.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "text": {
            "description": "The section body, also represented in the complete fallback text.",
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "x-max-utf8-bytes": 4000
          }
        },
        "additionalProperties": false
      },
      "NotificationImageInput": {
        "type": "object",
        "description": "One optional provider-neutral illustrative image. The notification content remains complete without the pixels.",
        "required": ["asset_id"],
        "properties": {
          "asset_id": {
            "$ref": "#/components/schemas/NotificationImageAssetId"
          },
          "purpose": { "const": "illustration", "default": "illustration" },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "pattern": "^(?=.*\\S)[^\\u0000-\\u001F\\u007F]+$",
            "x-max-utf8-bytes": 4000,
            "description": "Optional accessible description preserved by every adapter. Omit it for a decorative illustration; notification text must remain complete without the image."
          }
        },
        "additionalProperties": false
      },
      "TextContentInput": {
        "type": "object",
        "required": ["text"],
        "properties": {
          "type": { "const": "text" },
          "format": {
            "type": "string",
            "enum": ["plain", "markdown"],
            "description": "Text format. Omitted means plain text. Markdown supports headings, paragraphs, emphasis, strong emphasis, code, lists, quotes and safe HTTP(S) links; raw HTML and remote images are never executed or fetched."
          },
          "text": {
            "description": "The complete notification content. This remains authoritative and sufficient when an adapter cannot render optional structure.",
            "type": "string",
            "minLength": 1,
            "maxLength": 8192,
            "x-max-utf8-bytes": 8192
          },
          "title": {
            "description": "An optional semantic title. The adapter chooses its native presentation.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "sections": {
            "description": "Optional ordered semantic sections that enhance, but never replace, the complete text.",
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "items": { "$ref": "#/components/schemas/StructuredTextSection" }
          },
          "image": { "$ref": "#/components/schemas/NotificationImageInput" }
        },
        "additionalProperties": false
      },
      "DocumentSectionBlock": {
        "description": "One prose section in an ordered portable document.",
        "type": "object",
        "required": ["type", "text"],
        "properties": {
          "type": { "const": "section" },
          "heading": {
            "description": "An optional semantic heading for this section.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "text": {
            "description": "The section prose.",
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "x-max-utf8-bytes": 4000
          }
        },
        "additionalProperties": false
      },
      "DocumentFact": {
        "type": "object",
        "required": ["label", "value"],
        "properties": {
          "label": {
            "description": "The semantic label for this fact.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "value": {
            "description": "The semantic value for this fact.",
            "type": "string",
            "minLength": 1,
            "maxLength": 1000,
            "x-max-utf8-bytes": 4000
          }
        },
        "additionalProperties": false
      },
      "DocumentFactsBlock": {
        "description": "One ordered group of semantic label/value facts.",
        "type": "object",
        "required": ["type", "items"],
        "properties": {
          "type": { "const": "facts" },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 24,
            "items": { "$ref": "#/components/schemas/DocumentFact" }
          }
        },
        "additionalProperties": false
      },
      "DocumentTableCell": {
        "type": "string",
        "minLength": 1,
        "maxLength": 500,
        "x-max-utf8-bytes": 2000
      },
      "DocumentTableRow": {
        "type": "array",
        "minItems": 2,
        "maxItems": 8,
        "items": { "$ref": "#/components/schemas/DocumentTableCell" }
      },
      "DocumentTableBlock": {
        "description": "One small semantic table. Every row must have exactly one cell for each column.",
        "type": "object",
        "required": ["type", "heading", "columns", "rows"],
        "properties": {
          "type": { "const": "table" },
          "heading": {
            "description": "The semantic heading for this table.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "columns": {
            "description": "The ordered column headings.",
            "type": "array",
            "minItems": 2,
            "maxItems": 8,
            "items": { "$ref": "#/components/schemas/DocumentTableCell" }
          },
          "rows": {
            "description": "The ordered table rows.",
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": { "$ref": "#/components/schemas/DocumentTableRow" }
          }
        },
        "x-rows-match-columns": true,
        "additionalProperties": false
      },
      "DocumentDetailsBlock": {
        "description": "One supporting disclosure in an ordered portable document.",
        "type": "object",
        "required": ["type", "summary", "text"],
        "properties": {
          "type": { "const": "details" },
          "summary": {
            "description": "The always-visible semantic summary.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "text": {
            "description": "The supporting prose.",
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "x-max-utf8-bytes": 8000
          }
        },
        "additionalProperties": false
      },
      "DocumentBlock": {
        "oneOf": [
          { "$ref": "#/components/schemas/DocumentSectionBlock" },
          { "$ref": "#/components/schemas/DocumentFactsBlock" },
          { "$ref": "#/components/schemas/DocumentTableBlock" },
          { "$ref": "#/components/schemas/DocumentDetailsBlock" }
        ]
      },
      "DocumentContentInput": {
        "description": "An authoritative ordered portable notification document that every delivery adapter renders faithfully.",
        "type": "object",
        "required": ["blocks"],
        "properties": {
          "type": { "const": "document" },
          "title": {
            "description": "An optional semantic document title. The adapter chooses its native presentation.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "blocks": {
            "description": "The complete portable document in exact authored order.",
            "type": "array",
            "minItems": 1,
            "maxItems": 24,
            "items": { "$ref": "#/components/schemas/DocumentBlock" }
          },
          "image": { "$ref": "#/components/schemas/NotificationImageInput" }
        },
        "additionalProperties": false
      },
      "MessageContentInput": {
        "oneOf": [
          {
            "type": "string",
            "minLength": 1,
            "maxLength": 8192,
            "x-max-utf8-bytes": 8192
          },
          { "$ref": "#/components/schemas/TextContentInput" },
          { "$ref": "#/components/schemas/DocumentContentInput" }
        ]
      },
      "InteractionPrompt": {
        "type": "string",
        "minLength": 1,
        "maxLength": 1000
      },
      "Timestamp-2": {
        "type": "string",
        "format": "date-time",
        "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$"
      },
      "InteractionCorrelationId": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
        "description": "Caller-owned opaque correlation returned as data, never treated as execution authority."
      },
      "ConfirmInteractionSendRequest": {
        "type": "object",
        "required": ["prompt"],
        "properties": {
          "type": { "const": "confirm" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "confirm_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "deny_label": { "type": "string", "minLength": 1, "maxLength": 40 },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "Absolute RFC3339 deadline with an explicit timezone and at most millisecond precision. At least 30 seconds after server acceptance. Mutually exclusive with expires_in_seconds."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 30,
            "description": "Whole seconds from server acceptance. No fixed maximum; the resolved timestamp must be representable through year 9999. Mutually exclusive with expires_at. Omit both for 86400 seconds (24 hours)."
          }
        },
        "additionalProperties": false,
        "not": {
          "required": ["expires_at", "expires_in_seconds"],
          "properties": { "expires_at": {}, "expires_in_seconds": {} }
        }
      },
      "InteractionOptionInput": {
        "oneOf": [
          {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
          },
          {
            "type": "object",
            "required": ["label"],
            "properties": {
              "value": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128,
                "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
                "description": "Defaults to label. Opaque customer data, never a command."
              },
              "label": { "type": "string", "minLength": 1, "maxLength": 120 },
              "intent": {
                "type": "string",
                "enum": ["accept", "destructive", "informational", "neutral"],
                "default": "neutral",
                "description": "What choosing this option does, so a channel can present it accordingly. Describes consequence rather than appearance: a channel renders `accept` green where it can, `destructive` red, `informational` prominent, and `neutral` plainly. A channel that cannot colour a control ignores this and the option still renders. Omitted means `neutral`."
              }
            },
            "additionalProperties": false,
            "allOf": [
              {
                "if": { "properties": { "value": {} }, "required": ["value"] },
                "else": {
                  "properties": {
                    "label": {
                      "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
                      "type": "string"
                    }
                  }
                }
              }
            ],
            "$comment": "The conditional constraint applies only when the label is used as the value. Keep the TypeScript input shape explicit because the generator omits object properties for conditional schemas.",
            "x-typescript-type": "{ label: string; value?: string; intent?: \"accept\" | \"destructive\" | \"informational\" | \"neutral\" }"
          }
        ]
      },
      "SelectInteractionSendRequest": {
        "type": "object",
        "required": ["prompt", "options"],
        "properties": {
          "type": { "const": "select" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "options": {
            "type": "array",
            "minItems": 2,
            "maxItems": 6,
            "items": { "$ref": "#/components/schemas/InteractionOptionInput" },
            "x-unique-property": "value"
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "Absolute RFC3339 deadline with an explicit timezone and at most millisecond precision. At least 30 seconds after server acceptance. Mutually exclusive with expires_in_seconds."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 30,
            "description": "Whole seconds from server acceptance. No fixed maximum; the resolved timestamp must be representable through year 9999. Mutually exclusive with expires_at. Omit both for 86400 seconds (24 hours)."
          }
        },
        "additionalProperties": false,
        "not": {
          "required": ["expires_at", "expires_in_seconds"],
          "properties": { "expires_at": {}, "expires_in_seconds": {} }
        }
      },
      "InputInteractionSendRequest": {
        "type": "object",
        "required": ["type", "prompt"],
        "properties": {
          "type": { "const": "input" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "Absolute RFC3339 deadline with an explicit timezone and at most millisecond precision. At least 30 seconds after server acceptance. Mutually exclusive with expires_in_seconds."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 30,
            "description": "Whole seconds from server acceptance. No fixed maximum; the resolved timestamp must be representable through year 9999. Mutually exclusive with expires_at. Omit both for 86400 seconds (24 hours)."
          }
        },
        "additionalProperties": false,
        "not": {
          "required": ["expires_at", "expires_in_seconds"],
          "properties": { "expires_at": {}, "expires_in_seconds": {} }
        }
      },
      "MetadataValue": {
        "oneOf": [
          { "type": "string" },
          { "type": "number" },
          { "type": "boolean" },
          { "type": "null" }
        ]
      },
      "Metadata": {
        "type": "object",
        "description": "Bounded customer correlation data. Do not include secrets or personal data.",
        "maxProperties": 20,
        "propertyNames": { "minLength": 1, "maxLength": 64 },
        "additionalProperties": {
          "$ref": "#/components/schemas/MetadataValue"
        },
        "x-max-json-bytes": 4096
      },
      "HighestProvenProviderState": {
        "type": "string",
        "enum": ["none", "provider_accepted"],
        "description": "The strongest provider assertion the service can prove; it is not an end-device delivery receipt."
      },
      "ClassifiedError": {
        "type": "object",
        "description": "A stable, safe error classification with no provider response or credential material.",
        "required": ["code", "retryable"],
        "properties": {
          "code": { "$ref": "#/components/schemas/ProblemCode" },
          "retryable": { "type": "boolean" },
          "detail": { "type": "string", "minLength": 1, "maxLength": 1024 },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "Environment": {
        "type": "string",
        "enum": ["test", "live"],
        "description": "The single environment selected by the authenticated credential."
      },
      "MessageCategorySnapshot": {
        "type": "object",
        "description": "The category settings recorded when the message was accepted.",
        "required": ["key", "name", "purpose", "level", "can_turn_off"],
        "properties": {
          "key": { "$ref": "#/components/schemas/MessageCategoryKey" },
          "name": { "type": "string", "minLength": 1, "maxLength": 100 },
          "purpose": { "enum": ["service", "marketing"] },
          "level": { "enum": ["low", "normal", "high", "critical"] },
          "can_turn_off": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "EmailAddress": {
        "type": "string",
        "minLength": 3,
        "maxLength": 254,
        "pattern": "^(?=[^@]{1,64}@)(?!\\.)(?![^@]*\\.@)(?![^@]*\\.\\.)[A-Za-z0-9!#$%&'*+/=?^_`{|}~.-]+@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$",
        "description": "Exactly one mailbox: an unquoted ASCII dot-atom local part plus a canonical lower-case IDNA domain. The comparison key preserves local-part bytes and case and lower-cases only the domain; dot, plus-tag, alias and provider equivalence are never inferred."
      },
      "BroadcastMessageProvenance": {
        "type": "object",
        "description": "Provenance carried by an ordinary message created during group expansion. The broadcast, message subscriber_id, and exact historical membership generation form the child uniqueness boundary.",
        "required": ["broadcast_id", "group_id", "membership_generation"],
        "properties": {
          "broadcast_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "group_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "membership_generation": { "type": "integer", "minimum": 1 }
        },
        "additionalProperties": false
      },
      "MessageDeliveryTarget": {
        "type": "string",
        "enum": ["connection", "simulator"],
        "description": "The effective provider boundary selected for a message. Connection delivery uses the exact authorized environment connection; simulator delivery never calls a provider."
      },
      "TrimmedInputAnswer": {
        "type": "string",
        "minLength": 1,
        "maxLength": 4000,
        "pattern": "^\\S(?:[\\s\\S]*\\S)?$",
        "description": "Untrusted input text after leading and trailing whitespace is removed."
      },
      "OpaqueIdentifier-2": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
        "description": "An opaque identifier whose internal encoding is not a public promise."
      },
      "InteractionState": {
        "type": "string",
        "enum": ["open", "answered", "expired", "cancelled", "retired"]
      },
      "GroupKey": {
        "type": "string",
        "minLength": 1,
        "maxLength": 63,
        "pattern": "^[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*$",
        "description": "A stable, case-sensitive subscriber group key. Existing keys are preserved exactly."
      },
      "BroadcastAggregate": {
        "type": "object",
        "description": "A projection over expansion and ordinary child-message states, not an independent delivery state machine.",
        "required": [
          "audience",
          "expanded",
          "pending",
          "provider_accepted",
          "delivered",
          "skipped",
          "failed",
          "cancelled",
          "expired"
        ],
        "properties": {
          "audience": { "type": "integer", "minimum": 0 },
          "expanded": { "type": "integer", "minimum": 0 },
          "pending": { "type": "integer", "minimum": 0 },
          "provider_accepted": { "type": "integer", "minimum": 0 },
          "delivered": { "type": "integer", "minimum": 0 },
          "skipped": { "type": "integer", "minimum": 0 },
          "failed": { "type": "integer", "minimum": 0 },
          "cancelled": { "type": "integer", "minimum": 0 },
          "expired": { "type": "integer", "minimum": 0 }
        },
        "additionalProperties": false
      },
      "EmailBindingConsent": {
        "description": "How consent for this exact subscriber, notifier and connection was established. A customer assertion never becomes recipient-observed verification. Complaint, unsubscribe and suppression override either arm.",
        "oneOf": [
          {
            "type": "object",
            "required": ["kind", "observed_at"],
            "properties": {
              "kind": { "const": "recipient_observed" },
              "observed_at": { "$ref": "#/components/schemas/Timestamp" }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["kind", "consented_at", "source"],
            "properties": {
              "kind": { "const": "asserted_prior_consent" },
              "consented_at": { "$ref": "#/components/schemas/Timestamp" },
              "source": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "pattern": "^[^\u0000-\u001f-  ]+$",
                "description": "A bounded customer description of where consent was collected. The authenticated asserting actor is recorded by the service, never accepted from this object."
              },
              "asserted_at": { "$ref": "#/components/schemas/Timestamp" },
              "asserted_by": {
                "type": "object",
                "required": ["kind", "id"],
                "properties": {
                  "kind": { "enum": ["credential", "grant", "session"] },
                  "id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
                },
                "additionalProperties": false
              },
              "domain_id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
            },
            "additionalProperties": false
          }
        ]
      },
      "RecipientChannelSummary": {
        "type": "object",
        "description": "Safe state for one configured channel. Provider identities, credentials, callback state, and other subscribers are absent.",
        "required": ["channel", "state", "preferred"],
        "properties": {
          "channel": { "$ref": "#/components/schemas/Channel" },
          "state": {
            "type": "string",
            "enum": ["available", "connected", "paused"]
          },
          "binding_id": {
            "$ref": "#/components/schemas/OpaqueIdentifier",
            "description": "The exact binding owned by this session's subscriber. Present only for connected or paused state."
          },
          "preferred": { "type": "boolean" },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "masked_address": {
            "type": "string",
            "minLength": 3,
            "maxLength": 254,
            "description": "Masked recipient address. Never the full mailbox."
          },
          "consent": { "$ref": "#/components/schemas/EmailBindingConsent" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "state": { "enum": ["connected", "paused"] } },
              "required": ["state"]
            },
            "then": {
              "required": ["binding_id"],
              "properties": { "binding_id": {} }
            }
          },
          {
            "if": {
              "properties": { "state": { "const": "available" } },
              "required": ["state"]
            },
            "then": {
              "properties": {
                "binding_id": false,
                "preferred": { "const": false }
              }
            }
          }
        ],
        "additionalProperties": false
      },
      "ConnectionIdentity": {
        "type": "object",
        "description": "The identity a subscriber will see, named the way its provider names it. Carries the provider so a reader knows what kind of handle it is holding, rather than inferring it from the field's name. One shape for every provider: what differs between them is the handle's own format, which is stated here as a rule rather than as a separate type per provider.",
        "required": ["provider", "handle"],
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/ChannelConnectionProvider"
          },
          "handle": {
            "type": "string",
            "minLength": 1,
            "description": "The visible provider handle without a provider-specific sigil — a bot username, a workspace or app display name, a sender address. Never a credential, installation identifier or provider-native identity reference."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": { "provider": { "const": "email" } },
              "required": ["provider"]
            },
            "then": {
              "properties": {
                "handle": { "$ref": "#/components/schemas/EmailAddress" }
              }
            },
            "else": {
              "properties": { "handle": { "type": "string", "maxLength": 128 } }
            }
          }
        ],
        "additionalProperties": false
      },
      "EmailVerificationSummary": {
        "type": "object",
        "required": ["status", "masked_address", "expires_at"],
        "properties": {
          "status": { "enum": ["pending", "verified", "failed", "expired"] },
          "masked_address": {
            "type": "string",
            "minLength": 3,
            "maxLength": 254,
            "description": "Masked recipient address. Never the full mailbox."
          },
          "expires_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "OrganizationRole": {
        "type": "string",
        "enum": ["admin", "member", "messenger"],
        "description": "The person's WhooshBang role in the organization. `admin` does everything, including billing, API keys and teammates. `member` runs the projects they were given: channels, subscribers, messages and project settings. `messenger` sends messages and reads replies in the projects they were given. Clients must tolerate roles added later."
      },
      "OrganizationMembershipSummary": {
        "type": "object",
        "required": ["role"],
        "properties": {
          "role": { "$ref": "#/components/schemas/OrganizationRole" }
        },
        "additionalProperties": false
      },
      "OrganizationClosureProviderAction": {
        "type": "object",
        "description": "One provider-owned resource the customer must retire outside WhooshBang after organization closure. It contains safe identifiers only, never provider credentials.",
        "required": ["provider", "action", "connection_id"],
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/ChannelConnectionProvider"
          },
          "action": {
            "type": "string",
            "enum": ["revoke_bot_token", "delete_provider_application"]
          },
          "connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        },
        "additionalProperties": false
      },
      "TeammateStatus": {
        "type": "string",
        "enum": ["active", "invited"],
        "description": "`active` has joined. `invited` has an invitation they have not accepted."
      },
      "TeammateProjectAccess": {
        "type": "object",
        "description": "Which projects the teammate can see. An admin sees every project, including ones created later.",
        "required": ["all", "project_ids"],
        "properties": {
          "all": { "type": "boolean" },
          "project_ids": {
            "type": "array",
            "maxItems": 1000,
            "uniqueItems": true,
            "items": { "$ref": "#/components/schemas/OpaqueIdentifier" },
            "description": "The projects given to this teammate. Empty when `all` is true."
          }
        },
        "additionalProperties": false
      },
      "ProviderInstallationStatus": {
        "type": "string",
        "enum": [
          "pending",
          "active",
          "reauthorization_required",
          "revoked",
          "invalid"
        ],
        "description": "The safe customer-facing lifecycle of a provider installation. Credential and provider-native state stay private."
      },
      "ProviderAuthorizationSetup": {
        "description": "A credential-free provider authorization handoff for one exact connection. The URL is short-lived and safe to render, but never contains a provider credential, team identifier or raw authorization code; actual OAuth state and callback handling remain service-private.",
        "oneOf": [
          {
            "type": "object",
            "required": ["status", "authorization_url", "expires_at"],
            "properties": {
              "status": { "const": "awaiting_authorization" },
              "authorization_url": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://[^\\s]+$",
                "maxLength": 2048,
                "description": "The short-lived HTTPS authorization handoff for this connection. It carries opaque state, not provider credentials or a raw authorization code."
              },
              "expires_at": { "$ref": "#/components/schemas/Timestamp" }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["status", "expires_at"],
            "properties": {
              "status": { "const": "provisioning" },
              "expires_at": { "$ref": "#/components/schemas/Timestamp" }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["status", "expires_at", "failure"],
            "properties": {
              "status": { "const": "failed" },
              "expires_at": { "$ref": "#/components/schemas/Timestamp" },
              "failure": { "$ref": "#/components/schemas/ProviderFailure" }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["status", "expires_at"],
            "properties": {
              "status": { "const": "expired" },
              "expires_at": { "$ref": "#/components/schemas/Timestamp" }
            },
            "additionalProperties": false
          }
        ]
      },
      "EmailDomainName": {
        "type": "string",
        "minLength": 4,
        "maxLength": 253,
        "pattern": "^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.){2,}[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$",
        "description": "A canonical lower-case IDNA ASCII customer sending domain with its trailing dot removed. It must be a dedicated subdomain below the registrable domain; runtime validation uses the public suffix list so a registrable root such as example.co.uk is still rejected. URLs, ports, wildcards and mailbox addresses are invalid."
      },
      "EmailDomainLifecycle": {
        "type": "string",
        "enum": [
          "requested",
          "creating",
          "dns_required",
          "verifying",
          "testing",
          "active",
          "provider_action_required",
          "dns_failed",
          "oauth_required",
          "held",
          "deleting",
          "deleted"
        ],
        "description": "The provider-neutral domain lifecycle. Sending and receiving capabilities are reported separately because they verify on different clocks."
      },
      "EmailDomainCapabilityState": {
        "type": "string",
        "enum": ["pending", "verified", "failed", "unsupported"]
      },
      "EmailDomainCapabilities": {
        "type": "object",
        "required": [
          "sending",
          "receiving",
          "delivery",
          "link_interactions",
          "free_text_reply"
        ],
        "properties": {
          "sending": {
            "$ref": "#/components/schemas/EmailDomainCapabilityState"
          },
          "receiving": {
            "$ref": "#/components/schemas/EmailDomainCapabilityState"
          },
          "delivery": { "type": "boolean" },
          "link_interactions": { "type": "boolean" },
          "free_text_reply": {
            "type": "boolean",
            "description": "False when free-text replies cannot be lowered: receiving may not be verified yet, or the provider team may have message-content storage disabled. Delivery and link-based interaction remain independently available; no undocumented eligibility or storage-state endpoint is assumed."
          }
        },
        "additionalProperties": false
      },
      "EmailDnsRecord": {
        "description": "One exact neutral DNS record. `name` is preserved exactly as the provider returns it and is relative to the registrable domain (for example `send.notify`, not `send.notify.example.com`).",
        "oneOf": [
          {
            "type": "object",
            "required": ["type", "name", "value", "priority", "status"],
            "properties": {
              "type": { "const": "MX" },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 253,
                "pattern": "^[^\u0000-\u001f-  ]+$"
              },
              "value": {
                "type": "string",
                "minLength": 1,
                "maxLength": 2048,
                "pattern": "^[^\u0000-\u001f-  ]+$"
              },
              "priority": { "type": "integer", "minimum": 0, "maximum": 65535 },
              "status": {
                "enum": [
                  "not_started",
                  "pending",
                  "verified",
                  "failed",
                  "temporary_failure"
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["type", "name", "value", "status"],
            "properties": {
              "type": { "enum": ["TXT", "CNAME"] },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 253,
                "pattern": "^[^\u0000-\u001f-  ]+$"
              },
              "value": {
                "type": "string",
                "minLength": 1,
                "maxLength": 2048,
                "pattern": "^[^\u0000-\u001f-  ]+$"
              },
              "status": {
                "enum": [
                  "not_started",
                  "pending",
                  "verified",
                  "failed",
                  "temporary_failure"
                ]
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "EmailDomainGuide": {
        "type": "object",
        "required": ["state"],
        "properties": {
          "state": {
            "enum": [
              "detecting",
              "guided",
              "domain_connect_available",
              "complete",
              "unavailable"
            ]
          },
          "dns_provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "pattern": "^[^\u0000-\u001f-  ]+$"
          },
          "instructions_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 2048,
            "description": "A short-lived secret-free instruction link for a DNS administrator. It contains no WhooshBang session or provider OAuth material."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "state": {
                  "enum": ["guided", "domain_connect_available", "complete"]
                }
              },
              "required": ["state"]
            },
            "then": {
              "properties": { "dns_provider": true },
              "required": ["dns_provider"]
            },
            "else": { "properties": { "dns_provider": false } }
          }
        ],
        "additionalProperties": false
      },
      "EmailSubjectPolicy": {
        "type": "object",
        "description": "The fixed subject rendering contract. Notification title wins; otherwise localized copy equivalent to `Notification from {notifier display name}` is used. Whitespace is normalized and the final value is capped at 200 Unicode code points.",
        "required": ["fallback", "maximum_code_points", "normalize_whitespace"],
        "properties": {
          "fallback": { "const": "localized_notifier_name" },
          "maximum_code_points": { "const": 200 },
          "normalize_whitespace": { "const": true }
        },
        "additionalProperties": false
      },
      "EmailDeliveryPolicy": {
        "type": "object",
        "description": "Privacy-safe email defaults. Return-Path and Message-ID remain provider-owned, arbitrary headers are unsupported, and every ordinary message carries a visible management route plus safe one-click unsubscribe semantics when custom headers are available. A GET never mutates consent; the matching POST resolves the exact binding.",
        "required": [
          "open_tracking",
          "click_tracking",
          "tls",
          "unsubscribe",
          "subject"
        ],
        "properties": {
          "open_tracking": { "const": false },
          "click_tracking": { "const": false },
          "tls": {
            "enum": ["opportunistic", "enforced"],
            "default": "opportunistic"
          },
          "unsubscribe": { "const": "visible_and_one_click_where_supported" },
          "subject": { "$ref": "#/components/schemas/EmailSubjectPolicy" }
        },
        "additionalProperties": false
      },
      "OrganizationCredentialPrefix": {
        "type": "string",
        "pattern": "^wb_oc1\\.ocred_[A-Za-z0-9_-]{8}$",
        "description": "A safe display prefix containing the organization-credential format marker and first eight base64url identity characters, never secret bytes."
      },
      "OrganizationCredentialScope": {
        "type": "string",
        "enum": [
          "organization:read",
          "projects:write",
          "projects:read",
          "messages:write",
          "messages:read",
          "subscriptions:write",
          "subscriptions:read",
          "machine-clients:write",
          "machine-clients:read",
          "capabilities:read",
          "connections:write",
          "connections:read"
        ],
        "description": "One organization-credential capability. `organization:read` is the organization's project directory — listing the organization's projects and reading one — and is the only scope here a project credential can never carry; it authorizes nothing below the organization. Every other name is the project-credential vocabulary unchanged, and is exercised only on the environment-scoped routes, where the project and environment come from the path and the credential's authority is the intersection of these scopes with the project-credential vocabulary. An organization credential is therefore never wider than a project credential would have been for the same project environment."
      },
      "OrganizationCredentialScopeSet": {
        "type": "array",
        "minItems": 1,
        "maxItems": 12,
        "uniqueItems": true,
        "items": { "$ref": "#/components/schemas/OrganizationCredentialScope" }
      },
      "OrganizationCredentialSecret": {
        "type": "string",
        "pattern": "^wb_oc1\\.ocred_[A-Za-z0-9_-]{21}[AQgw]\\.[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
        "description": "The exact one-time runtime bearer syntax. The final segment is canonical unpadded base64url for exactly 32 random secret bytes."
      },
      "RecipientCopyOverrideValue": {
        "type": "string",
        "minLength": 1,
        "maxLength": 500,
        "description": "Customer-authored plain text with optional plain template placeholders. The service enforces key-specific length and rejects invisible controls. Rendering escapes text; changing labels does not change recipient control actions."
      },
      "ApiCredentialPrefix": {
        "type": "string",
        "pattern": "^wb_pc1\\.pcred_[A-Za-z0-9_-]{8}$",
        "description": "A safe display prefix containing the credential format marker and first eight base64url identity characters, never secret bytes."
      },
      "ApiCredentialScope": {
        "type": "string",
        "enum": [
          "projects:write",
          "projects:read",
          "messages:write",
          "messages:read",
          "subscriptions:write",
          "subscriptions:read",
          "machine-clients:write",
          "machine-clients:read",
          "capabilities:read",
          "connections:write",
          "connections:read"
        ],
        "description": "One project-credential capability. Environment authority always comes from the credential record, never a scope or request field. `projects:write` configures the credential's own project and environment; it never creates a project, which remains an organization authority. The project-wide singletons — brand, default locale, logo and recipient copy — are what a live recipient sees, so writing them requires a live credential; a test credential may read them and may write its own environment's policy."
      },
      "ApiCredentialScopeSet": {
        "type": "array",
        "minItems": 1,
        "maxItems": 11,
        "uniqueItems": true,
        "items": { "$ref": "#/components/schemas/ApiCredentialScope" }
      },
      "ApiCredentialSecret": {
        "type": "string",
        "pattern": "^wb_pc1\\.pcred_[A-Za-z0-9_-]{21}[AQgw]\\.[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
        "description": "The exact one-time runtime bearer syntax. The final segment is canonical unpadded base64url for exactly 32 random secret bytes."
      },
      "MessageTarget": {
        "type": "object",
        "required": ["subscriber_id"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
        },
        "additionalProperties": false
      },
      "OpaqueIdentifier-3": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
      },
      "Environment-2": { "type": "string", "enum": ["test", "live"] },
      "MachineScope": {
        "type": "string",
        "enum": [
          "machine-messages:write",
          "machine-messages:read",
          "machine-events:read",
          "machine-events:ack"
        ]
      },
      "MachineScopeSummary": {
        "type": "array",
        "items": { "$ref": "#/components/schemas/MachineScope" },
        "minItems": 4,
        "maxItems": 4,
        "uniqueItems": true,
        "description": "Fixed least-privilege capabilities, each constrained to this client's bound destination or stream."
      },
      "MachineSecretDigest": {
        "type": "string",
        "pattern": "^sha256:[a-f0-9]{64}$",
        "description": "The only secret-derived value accepted by the administration API."
      },
      "ConfirmInteractionResponse": {
        "type": "object",
        "required": ["type", "value"],
        "properties": {
          "type": { "const": "confirm" },
          "value": { "type": "boolean" }
        },
        "additionalProperties": false
      },
      "SelectInteractionResponse": {
        "type": "object",
        "required": ["type", "value"],
        "properties": {
          "type": { "const": "select" },
          "value": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
          }
        },
        "additionalProperties": false
      },
      "InputInteractionResponse": {
        "type": "object",
        "required": ["type", "value"],
        "properties": {
          "type": { "const": "input" },
          "value": { "$ref": "#/components/schemas/TrimmedInputAnswer" }
        },
        "additionalProperties": false
      },
      "InteractionResponse": {
        "oneOf": [
          { "$ref": "#/components/schemas/ConfirmInteractionResponse" },
          { "$ref": "#/components/schemas/SelectInteractionResponse" },
          { "$ref": "#/components/schemas/InputInteractionResponse" }
        ]
      },
      "SafeChannelContext": {
        "type": "object",
        "required": ["binding_id", "channel", "conversation_kind"],
        "properties": {
          "binding_id": { "$ref": "#/components/schemas/OpaqueIdentifier-2" },
          "channel": {
            "type": "string",
            "enum": ["telegram"],
            "description": "Which channel the person answered on. An enum rather than a fixed value, so that a second channel adds a member instead of changing the type every generated client holds. The vocabulary grows additively; a consumer that meets a member it does not know should treat the answer as valid and the channel as unfamiliar rather than refusing it."
          },
          "conversation_kind": {
            "type": "string",
            "enum": ["private_chat", "thread", "group"]
          },
          "display_name": { "type": "string", "minLength": 1, "maxLength": 120 }
        },
        "additionalProperties": false
      },
      "QuarantineReasonCode": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[a-z0-9][a-z0-9._-]*$"
      },
      "MachineEventAckDisposition": {
        "type": "string",
        "enum": ["processed", "quarantined"]
      },
      "CustomerEndpointStatus": {
        "type": "string",
        "enum": ["unverified", "active", "paused", "disabled"]
      },
      "CustomerEventType": {
        "type": "string",
        "enum": [
          "subscription.activated",
          "subscription.revoked",
          "message.provider_accepted",
          "message.delivered",
          "message.failed",
          "message.expired",
          "interaction.received",
          "interaction.expired",
          "agent_binding.degraded",
          "subscription.asserted",
          "subscription.asserted_revoked"
        ]
      },
      "CustomerEndpointFailure": {
        "type": "object",
        "required": ["at", "category"],
        "properties": {
          "at": { "$ref": "#/components/schemas/Timestamp" },
          "category": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9_]+$"
          }
        },
        "additionalProperties": false
      },
      "CustomerEndpointSecret": {
        "type": "string",
        "pattern": "^whsec_[A-Za-z0-9+/]{43}=$",
        "description": "Exactly 32 random bytes in the Standard Webhooks secret format. Returned only by the first successful create or rotate response."
      },
      "CustomerEndpointAttemptDiagnostic": {
        "type": "object",
        "description": "Content-free per-attempt timing and failure classification.",
        "required": ["id", "event_id", "attempt", "status", "created_at"],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "event_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "attempt": { "type": "integer", "minimum": 1, "maximum": 8 },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "attempting",
              "delivered",
              "retry_wait",
              "terminal_failed",
              "paused"
            ]
          },
          "diagnostic_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9_]+$"
          },
          "http_status": { "type": "integer", "minimum": 100, "maximum": 599 },
          "started_at": { "$ref": "#/components/schemas/Timestamp" },
          "completed_at": { "$ref": "#/components/schemas/Timestamp" },
          "created_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "ChannelConnectionSetupStatus": {
        "type": "string",
        "enum": [
          "awaiting_handoff",
          "awaiting_creation",
          "provisioning",
          "failed",
          "expired"
        ],
        "description": "How far a guided setup has reached, which is the only thing a caller can act on while a connection is still `pending`. `awaiting_handoff` waits for the administrator to open the link on the Telegram account that will own the bot; `awaiting_creation` means that Telegram account is bound and the bot does not exist yet; `provisioning` means the bot exists and WhooshBang is installing delivery on it. `failed` and `expired` end the attempt without ending the connection — another attempt can be started on the same `pending` connection — and neither withdraws a bot Telegram has already created, because no provider API can delete one."
      },
      "SuggestedBotUsername": {
        "type": "string",
        "minLength": 5,
        "maxLength": 32,
        "pattern": "^[A-Za-z][A-Za-z0-9_]{1,28}[Bb][Oo][Tt]$",
        "description": "The @username Telegram's own creation dialog is prefilled with, constrained to Telegram's own rule: 5 to 32 characters, a letter first, letters, digits, and underscores after it, ending in `bot` in any case. The caller proposes it because it is the handle every subscriber sees forever and it cannot be changed once the bot exists — a WhooshBang-generated handle would permanently brand a customer's own bot with our naming, which is the one thing customer-owned modes exist to prevent. It is a suggestion and not a reservation: the administrator can type a different handle into Telegram's dialog, which validates the shape and refuses a handle somebody already holds."
      },
      "ChannelConnectionSetup": {
        "type": "object",
        "description": "The unfinished half of a customer-managed connection: what the administrator still has to do, and by when. It is deliberately incapable of carrying a secret. The new bot's token travels from Telegram to WhooshBang server to server, so nothing here is credential material and nothing here references any — which is what makes this object safe to poll, render in a dashboard, or hand to whoever is doing the setup.",
        "required": [
          "status",
          "handoff_url",
          "expires_at",
          "suggested_bot_username"
        ],
        "properties": {
          "status": {
            "$ref": "#/components/schemas/ChannelConnectionSetupStatus"
          },
          "handoff_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 2048,
            "description": "The link the administrator opens to put their own Telegram account behind this setup; for Telegram it is `https://t.me/<manager>?start=<payload>`. It is a capability for exactly one setup session and nothing else: it names no organization, no project, and no environment, it stops working at `expires_at`, and only the first Telegram account to open it is bound. It is not credential material, so displaying it costs nothing beyond letting whoever sees it first become the owner of the bot this setup creates. After `expired` or `failed` it binds nothing, and restarting the setup issues a new one rather than reviving this."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When an unfinished setup stops being usable. The window is short on purpose: an unopened link is an outstanding invitation to own a bot in this environment, and a caller who lets it lapse restarts rather than inherits."
          },
          "suggested_bot_username": {
            "$ref": "#/components/schemas/SuggestedBotUsername",
            "description": "The suggestion this attempt was started with, echoed so a caller can show the administrator what Telegram will prefill. It records what was asked for and never what exists: the administrator may override it in Telegram's dialog, and `identity` on the connection is the only description of the bot that was actually created."
          },
          "failure_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Why this attempt ended, in terms the administrator can act on. Absent when there is nothing both safe and useful to say: an attempt refused because that Telegram account already holds a live setup says only that, because naming the organization, project, or environment holding the other one would disclose another customer."
          }
        },
        "additionalProperties": false
      },
      "TelegramChannelConnection": {
        "type": "object",
        "description": "An existing Telegram connection. Its public shape remains unchanged.",
        "required": [
          "id",
          "project_id",
          "environment_id",
          "environment",
          "provider",
          "mode",
          "display_name",
          "status",
          "health",
          "row_version",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "provider": { "const": "telegram" },
          "mode": {
            "enum": ["whooshbang_shared", "customer_managed", "customer_byok"]
          },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": { "$ref": "#/components/schemas/ChannelConnectionStatus" },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" },
          "identity": { "$ref": "#/components/schemas/ConnectionIdentity" },
          "setup": { "$ref": "#/components/schemas/ChannelConnectionSetup" },
          "authorization_setup": false,
          "app_setup": false,
          "installation": false,
          "row_version": {
            "type": "integer",
            "minimum": 1,
            "description": "Send this back on an update. A stale value is refused rather than silently overwriting a change made in between."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "archived_at": { "$ref": "#/components/schemas/Timestamp" },
          "health_checked_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "HostedConnectionCapability": {
        "type": "string",
        "enum": ["send_messages"],
        "description": "A safe capability granted to this exact hosted connection. It is product vocabulary, never a raw provider scope."
      },
      "ProviderInstallationSummary": {
        "type": "object",
        "description": "A safe summary projected only through an exact authorized connection. Internal installation ids, provider-native workspace ids, scope arrays, grant metadata and credentials are absent.",
        "required": ["display_name", "status", "health"],
        "properties": {
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": {
            "$ref": "#/components/schemas/ProviderInstallationStatus"
          },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" }
        },
        "additionalProperties": false
      },
      "HostedConnectionRecoveryAction": {
        "type": "string",
        "enum": [
          "none",
          "complete_authorization",
          "wait_for_admin_approval",
          "retry_authorization",
          "reinstall",
          "retry_later",
          "contact_support"
        ],
        "description": "The exact safe next action for the current hosted lifecycle state. Provider wire errors and secret material never occupy this field."
      },
      "HostedChannelConnection": {
        "type": "object",
        "description": "A WhooshBang-owned application installed at one provider authority — a workspace, a tenant, a server — and referenced by one exact environment connection.",
        "required": [
          "id",
          "project_id",
          "environment_id",
          "environment",
          "provider",
          "mode",
          "display_name",
          "status",
          "health",
          "capabilities",
          "recovery_action",
          "row_version",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "provider": {
            "$ref": "#/components/schemas/ChannelConnectionProvider"
          },
          "mode": { "const": "whooshbang_hosted" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": { "$ref": "#/components/schemas/ChannelConnectionStatus" },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" },
          "capabilities": {
            "type": "array",
            "maxItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/HostedConnectionCapability"
            }
          },
          "identity": { "$ref": "#/components/schemas/ConnectionIdentity" },
          "setup": false,
          "app_setup": false,
          "authorization_setup": {
            "$ref": "#/components/schemas/ProviderAuthorizationSetup",
            "description": "The additive hosted authorization state. Older tolerant readers discard this unknown field rather than interpreting it as Telegram setup."
          },
          "installation": {
            "$ref": "#/components/schemas/ProviderInstallationSummary",
            "description": "The safe installation authorized for this exact connection. It is never caller-selectable and exposes no provider-native identifier or credential reference."
          },
          "management_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^(?!(?:javascript|data|vbscript|file|blob):)[a-z][a-z0-9+.-]*:[^\\s]+$",
            "maxLength": 2048,
            "description": "A provider-owned link that opens this application where the provider's own client presents it, for the exact authorized authority and WhooshBang application. It may use the provider's own URI scheme, never a scheme a browser would execute or read locally. It is not a caller-supplied return URL."
          },
          "recovery_action": {
            "$ref": "#/components/schemas/HostedConnectionRecoveryAction"
          },
          "last_successful_verification_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "last_successful_delivery_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "row_version": {
            "type": "integer",
            "minimum": 1,
            "description": "Send this back on an update. A stale value is refused rather than silently overwriting a change made in between."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "archived_at": { "$ref": "#/components/schemas/Timestamp" },
          "health_checked_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "CustomerApplicationSetupStatus": {
        "type": "string",
        "enum": [
          "awaiting_app_creation",
          "awaiting_authorities",
          "awaiting_authorization",
          "awaiting_ingress_proof",
          "provisioning",
          "failed",
          "expired"
        ],
        "description": "How far the setup of an application the customer creates and owns has reached, which is the only thing a caller can act on while the connection is still `pending`. Each verification state names a different authority, because a provider may hand an application's secrets over together but exercise them at different moments: `awaiting_authorization` has the authorities and is waiting for the install, `awaiting_ingress_proof` has an installation the provider confirmed and is waiting for the first request the provider itself signs. Collapsing them would let a connection report a verified ingress it has never verified."
      },
      "CustomerApplicationAuthority": {
        "type": "string",
        "enum": [
          "application_identity",
          "application_secret",
          "ingress_secret"
        ],
        "description": "One application-specific authority the owner hands over, named for what it is for rather than for what one provider's console calls it. `application_identity` identifies the application and is safe metadata; `application_secret` is what the application authenticates with; `ingress_secret` is what proves an inbound request came from the provider. The last two are write-only, and none of them is ever a value here."
      },
      "CustomerApplicationConnectionSetup": {
        "type": "object",
        "description": "The unfinished half of a connection through an application the customer creates and owns: what the owner still has to do at the provider, and by when.\n\nIt is deliberately incapable of carrying a secret. The creation link contains configuration and nothing else, the secrets the owner supplies are write-only and have no field here or on the connection, and the installation grant never travels through a browser at all — WhooshBang obtains it from the provider's own installation exchange. Everything here is therefore safe to poll, render, and hand to whoever is doing the setup.",
        "required": [
          "status",
          "creation_url",
          "expires_at",
          "app_name",
          "bot_display_name",
          "outstanding_authorities"
        ],
        "properties": {
          "status": {
            "$ref": "#/components/schemas/CustomerApplicationSetupStatus"
          },
          "creation_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 8192,
            "description": "The provider's own application-creation flow, opened with this application's configuration already filled in where the provider allows it, so the owner reviews and confirms rather than writing configuration by hand. The URL carries configuration only: it names no organization, project, or environment and contains no credential. Any opaque handle it carries selects candidate setup state and authorizes nothing."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp",
            "description": "When an unfinished setup stops being usable. A setup that already produced an application stays recoverable past this, because the application exists whether or not the browser came back."
          },
          "authorization_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://[^\\s]+$",
            "maxLength": 2048,
            "description": "The short-lived handoff that installs the owner's application, present once its authorities have arrived and an installation has been started. It carries opaque state, never a provider credential or a raw authorization code, and the grant it produces is returned to WhooshBang by the provider rather than to the browser."
          },
          "app_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 35,
            "description": "The name the owner chose, echoed so a resumed session shows the same application it started with."
          },
          "bot_display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "The bot display name the owner chose, echoed for the same reason."
          },
          "outstanding_authorities": {
            "type": "array",
            "maxItems": 3,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/CustomerApplicationAuthority"
            },
            "description": "Which application-specific values this setup is still waiting for. Empty once they have all arrived; it never says what any of them are."
          },
          "failure_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Why this attempt ended, in terms the owner can act on. It never echoes a submitted secret, whole or in part, and never names another customer: an application already connected elsewhere says only that."
          }
        },
        "additionalProperties": false
      },
      "CustomerApplicationChannelConnection": {
        "type": "object",
        "description": "An application the customer created and owns at the provider, referenced by one exact environment connection.\n\nIt differs from the hosted arm in who owns the application and its lifecycle, not in what a notification can do. WhooshBang custodies the application-specific authorities the provider makes unavoidable and none of them appears here or in any other read: absence, not redaction, is the mechanism.",
        "required": [
          "id",
          "project_id",
          "environment_id",
          "environment",
          "provider",
          "mode",
          "display_name",
          "status",
          "health",
          "capabilities",
          "recovery_action",
          "row_version",
          "created_at",
          "updated_at",
          "diagnostic_id"
        ],
        "properties": {
          "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "environment": { "$ref": "#/components/schemas/Environment" },
          "provider": {
            "$ref": "#/components/schemas/ChannelConnectionProvider"
          },
          "mode": { "const": "customer_managed" },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "status": { "$ref": "#/components/schemas/ChannelConnectionStatus" },
          "health": { "$ref": "#/components/schemas/ProviderHealthState" },
          "capabilities": {
            "type": "array",
            "maxItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/HostedConnectionCapability"
            }
          },
          "identity": { "$ref": "#/components/schemas/ConnectionIdentity" },
          "setup": false,
          "authorization_setup": false,
          "app_setup": {
            "$ref": "#/components/schemas/CustomerApplicationConnectionSetup",
            "description": "The guided customer-owned setup state. A distinct field from Telegram's `setup` and the hosted arm's `authorization_setup` so a tolerant reader can never mistake one journey's progress for another's."
          },
          "installation": {
            "$ref": "#/components/schemas/ProviderInstallationSummary",
            "description": "The safe installation this exact connection owns. It exposes no provider-native identifier and no credential reference."
          },
          "management_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^(?!(?:javascript|data|vbscript|file|blob):)[a-z][a-z0-9+.-]*:[^\\s]+$",
            "maxLength": 2048,
            "description": "A provider-owned link that opens the customer's own application where the provider's own client presents it, at the authority it is installed at. It may use the provider's own URI scheme, never a scheme a browser would execute or read locally. It is not a caller-supplied return URL."
          },
          "recovery_action": {
            "$ref": "#/components/schemas/HostedConnectionRecoveryAction"
          },
          "last_successful_verification_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "last_successful_delivery_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "row_version": {
            "type": "integer",
            "minimum": 1,
            "description": "Send this back on an update. A stale value is refused rather than silently overwriting a change made in between."
          },
          "created_at": { "$ref": "#/components/schemas/Timestamp" },
          "updated_at": { "$ref": "#/components/schemas/Timestamp" },
          "archived_at": { "$ref": "#/components/schemas/Timestamp" },
          "health_checked_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_at": { "$ref": "#/components/schemas/Timestamp" },
          "last_transition_reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
        },
        "additionalProperties": false
      },
      "SharedEmailStatus": {
        "type": "object",
        "description": "Safe state of the exact shared sender generation and this organization’s domain hold. It conveys no recipient consent and never authorizes fallback.",
        "required": [
          "sender_generation",
          "sender_state",
          "hold",
          "recovery_action"
        ],
        "properties": {
          "sender_generation": { "type": "integer", "minimum": 1 },
          "sender_state": { "enum": ["active", "draining", "held", "retired"] },
          "hold": { "enum": ["clear", "held"] },
          "recovery_action": {
            "enum": [
              "none",
              "resume_connection",
              "acknowledge_remediation",
              "retry_later"
            ]
          },
          "policy_version": { "type": "integer", "minimum": 1 },
          "held_at": { "$ref": "#/components/schemas/Timestamp" }
        },
        "additionalProperties": false
      },
      "EmailLocalPart": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^(?!\\.)(?!.*\\.$)(?!.*\\.\\.)[A-Za-z0-9!#$%&'*+/=?^_`{|}~.-]+$",
        "description": "One unquoted ASCII dot-atom local part. Its bytes and case are preserved exactly; quoted and SMTPUTF8 local parts are unsupported."
      },
      "EmailDisplayName": {
        "type": "string",
        "minLength": 1,
        "maxLength": 100,
        "pattern": "^[^\u0000-\u001f-  ]+$",
        "description": "A sender display name without control characters. It is encoded safely as a structured address field and never accepted as a raw header."
      },
      "EmailChannelConnection": {
        "description": "An email connection in one exact project environment. Provider authority and resource identifiers are represented only by organization-scoped WhooshBang ids; credentials and provider-native ids are structurally absent.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment_id",
              "environment",
              "provider",
              "mode",
              "display_name",
              "shared_identity_id",
              "status",
              "health",
              "delivery_policy",
              "row_version",
              "created_at",
              "updated_at",
              "diagnostic_id"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "provider": { "const": "email" },
              "mode": { "const": "whooshbang_shared" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "shared_identity_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "status": {
                "$ref": "#/components/schemas/ChannelConnectionStatus"
              },
              "health": { "$ref": "#/components/schemas/ProviderHealthState" },
              "setup": false,
              "app_setup": false,
              "authorization_setup": false,
              "installation": false,
              "domain_id": false,
              "sender_local_part": false,
              "sender_display_name": false,
              "delivery_policy": {
                "$ref": "#/components/schemas/EmailDeliveryPolicy"
              },
              "identity": { "$ref": "#/components/schemas/ConnectionIdentity" },
              "health_checked_at": { "$ref": "#/components/schemas/Timestamp" },
              "last_transition_at": {
                "$ref": "#/components/schemas/Timestamp"
              },
              "last_transition_reason": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "row_version": { "type": "integer", "minimum": 1 },
              "created_at": { "$ref": "#/components/schemas/Timestamp" },
              "updated_at": { "$ref": "#/components/schemas/Timestamp" },
              "archived_at": { "$ref": "#/components/schemas/Timestamp" },
              "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
              "email_status": {
                "$ref": "#/components/schemas/SharedEmailStatus"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "id",
              "project_id",
              "environment_id",
              "environment",
              "provider",
              "mode",
              "display_name",
              "status",
              "health",
              "installation",
              "domain_id",
              "sender_local_part",
              "sender_display_name",
              "delivery_policy",
              "row_version",
              "created_at",
              "updated_at",
              "diagnostic_id"
            ],
            "properties": {
              "id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
              "environment_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier"
              },
              "environment": { "$ref": "#/components/schemas/Environment" },
              "provider": { "const": "email" },
              "mode": { "const": "customer_managed" },
              "display_name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "status": {
                "$ref": "#/components/schemas/ChannelConnectionStatus"
              },
              "health": { "$ref": "#/components/schemas/ProviderHealthState" },
              "shared_identity_id": false,
              "setup": false,
              "app_setup": false,
              "authorization_setup": {
                "$ref": "#/components/schemas/ProviderAuthorizationSetup"
              },
              "installation": {
                "$ref": "#/components/schemas/ProviderInstallationSummary"
              },
              "domain_id": {
                "$ref": "#/components/schemas/OpaqueIdentifier",
                "description": "The organization-owned domain authorized to this connection. It is resolved under the authenticated organization and cannot select another tenant's resource; another connection may hold its own authorization edge to the same domain."
              },
              "sender_local_part": {
                "$ref": "#/components/schemas/EmailLocalPart"
              },
              "sender_display_name": {
                "$ref": "#/components/schemas/EmailDisplayName"
              },
              "delivery_policy": {
                "$ref": "#/components/schemas/EmailDeliveryPolicy",
                "description": "A read-only projection of the authorized domain's delivery policy. The domain is the sole mutation authority for TLS."
              },
              "identity": { "$ref": "#/components/schemas/ConnectionIdentity" },
              "health_checked_at": { "$ref": "#/components/schemas/Timestamp" },
              "last_transition_at": {
                "$ref": "#/components/schemas/Timestamp"
              },
              "last_transition_reason": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "row_version": { "type": "integer", "minimum": 1 },
              "created_at": { "$ref": "#/components/schemas/Timestamp" },
              "updated_at": { "$ref": "#/components/schemas/Timestamp" },
              "archived_at": { "$ref": "#/components/schemas/Timestamp" },
              "diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
            },
            "additionalProperties": false
          }
        ]
      },
      "DocumentContent": {
        "description": "An authoritative ordered portable notification document that every delivery adapter renders faithfully.",
        "type": "object",
        "required": ["type", "blocks"],
        "properties": {
          "type": { "const": "document" },
          "title": {
            "description": "An optional semantic document title. The adapter chooses its native presentation.",
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "x-max-utf8-bytes": 800
          },
          "blocks": {
            "description": "The complete portable document in exact authored order.",
            "type": "array",
            "minItems": 1,
            "maxItems": 24,
            "items": { "$ref": "#/components/schemas/DocumentBlock" }
          },
          "image": { "$ref": "#/components/schemas/NotificationImage" }
        },
        "additionalProperties": false
      },
      "MessageContent": {
        "oneOf": [
          { "$ref": "#/components/schemas/TextContent" },
          { "$ref": "#/components/schemas/DocumentContent" }
        ]
      },
      "RecipientBrand": {
        "type": "object",
        "description": "Constrained recipient-facing brand tokens. Arbitrary markup, CSS, scripts, remote assets, fonts, and tracking inputs are structurally absent.",
        "required": ["display_name", "accent_color", "color_scheme"],
        "properties": {
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "logo_asset_id": {
            "$ref": "#/components/schemas/RecipientBrandAssetId",
            "description": "A normalized asset already hosted by WhooshBang, never a caller-supplied URL."
          },
          "accent_color": { "type": "string", "pattern": "^#[0-9A-F]{6}$" },
          "color_scheme": {
            "type": "string",
            "enum": ["light", "dark", "system"]
          }
        },
        "additionalProperties": false
      },
      "ExactOrigin": {
        "type": "string",
        "format": "uri",
        "minLength": 8,
        "maxLength": 255,
        "pattern": "^https?://[^/?#*\\s]+(?::[0-9]{1,5})?/?$",
        "description": "One exact scheme, host, and optional port, in any spelling that means that same origin. A trailing slash, an uppercase host, and an explicitly written default port are accepted and stored in canonical form. Paths, queries, fragments, credentials, and wildcards are forbidden; HTTP is accepted only for localhost or synthetic .test configuration."
      },
      "DeveloperKey": {
        "type": "string",
        "minLength": 1,
        "maxLength": 63,
        "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
        "description": "A stable, lowercase developer key used by registered return destinations and subscriber groups."
      },
      "RegisteredReturnUrl": {
        "type": "string",
        "format": "uri",
        "minLength": 8,
        "maxLength": 2048,
        "pattern": "^https?://[^\\s{}]+$",
        "description": "An exact registered return destination. Templates, credentials, and fragments are forbidden; HTTP is accepted only for localhost or synthetic .test configuration."
      },
      "ReturnDestination": {
        "type": "object",
        "required": ["key", "url"],
        "properties": {
          "key": { "$ref": "#/components/schemas/DeveloperKey" },
          "url": { "$ref": "#/components/schemas/RegisteredReturnUrl" }
        },
        "additionalProperties": false
      },
      "RecipientSessionCapabilityPrefix": {
        "type": "string",
        "minLength": 33,
        "maxLength": 33,
        "pattern": "^wb_rs1\\.rsc_[A-Za-z0-9_-]{22}$",
        "description": "A non-secret prefix safe for later session projection and support correlation."
      },
      "RecipientSessionOperation": {
        "type": "string",
        "enum": [
          "session:read",
          "handoff:create",
          "binding:pause",
          "binding:resume",
          "binding:revoke",
          "preference:write"
        ]
      },
      "RecipientSessionCapability": {
        "type": "string",
        "minLength": 77,
        "maxLength": 77,
        "pattern": "^wb_rs1\\.rsc_[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}$",
        "writeOnly": true,
        "description": "Creation-only opaque recipient capability. It is stored by digest and is never accepted as an application bearer credential."
      },
      "ProviderHandoffCompletionMode": {
        "oneOf": [
          {
            "type": "object",
            "required": ["mode", "target_origin", "opener_nonce"],
            "properties": {
              "mode": { "const": "popup" },
              "target_origin": { "$ref": "#/components/schemas/ExactOrigin" },
              "opener_nonce": {
                "type": "string",
                "minLength": 22,
                "maxLength": 64,
                "pattern": "^[A-Za-z0-9_-]+$"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["mode"],
            "properties": { "mode": { "const": "redirect" } },
            "additionalProperties": false
          }
        ]
      },
      "TimeZone": {
        "type": "string",
        "minLength": 3,
        "maxLength": 255,
        "pattern": "^(?:UTC|[A-Za-z][A-Za-z0-9._+-]*(?:/[A-Za-z][A-Za-z0-9._+-]*)+)$",
        "description": "A named IANA time-zone identifier. Numeric offsets, abbreviations and display labels are invalid; recognized aliases normalize to the runtime's canonical identifier before persistence. Providers may leave it absent."
      },
      "SafeExplanation": { "type": "string", "minLength": 1, "maxLength": 500 },
      "InteractionCapability": {
        "type": "object",
        "required": ["mode"],
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["native", "fallback", "unsupported", "conditional"]
          },
          "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "mode": { "enum": ["fallback", "conditional"] } },
              "required": ["mode"]
            },
            "then": {
              "required": ["explanation"],
              "properties": { "explanation": {} }
            }
          }
        ],
        "additionalProperties": false
      },
      "ContextSupport": {
        "type": "object",
        "required": ["mode"],
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["supported", "unsupported", "conditional"]
          },
          "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "mode": { "const": "conditional" } },
              "required": ["mode"]
            },
            "then": {
              "required": ["explanation"],
              "properties": { "explanation": {} }
            }
          }
        ],
        "additionalProperties": false
      },
      "Degradation": {
        "type": "object",
        "required": ["active"],
        "properties": {
          "active": { "type": "boolean" },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9][a-z0-9._-]*$"
          },
          "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
        },
        "allOf": [
          {
            "if": {
              "properties": { "active": { "const": true } },
              "required": ["active"]
            },
            "then": {
              "required": ["code", "explanation"],
              "properties": { "code": {}, "explanation": {} }
            },
            "else": { "properties": { "code": false, "explanation": false } }
          }
        ],
        "additionalProperties": false
      },
      "provider-capabilities-v1.schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "https://whooshbang.flowxo.com/schemas/provider-capabilities-v1.schema.json",
        "x-contract-version": "3.2.0",
        "title": "ProviderCapabilitiesV1",
        "description": "Provider-neutral, renderer-facing delivery and interaction capabilities with explicit degradation.",
        "type": "object",
        "required": [
          "schema",
          "provider",
          "text",
          "interaction",
          "streaming",
          "edit",
          "receipts",
          "contexts",
          "rate_limit",
          "degradation"
        ],
        "properties": {
          "schema": { "const": "whooshbang.provider-capabilities.v1" },
          "provider": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z][a-z0-9_-]*$"
          },
          "text": {
            "type": "object",
            "required": ["supported", "maximum_bytes"],
            "properties": {
              "supported": { "type": "boolean" },
              "maximum_bytes": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1048576
              }
            },
            "additionalProperties": false
          },
          "interaction": {
            "type": "object",
            "required": ["confirm", "select", "input"],
            "properties": {
              "confirm": {
                "$ref": "#/components/schemas/InteractionCapability"
              },
              "select": {
                "$ref": "#/components/schemas/InteractionCapability"
              },
              "input": { "$ref": "#/components/schemas/InteractionCapability" }
            },
            "additionalProperties": false
          },
          "streaming": {
            "type": "object",
            "required": ["mode"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "native",
                  "edit",
                  "typing_then_final",
                  "final_only",
                  "unsupported"
                ]
              },
              "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
            },
            "additionalProperties": false
          },
          "edit": {
            "type": "object",
            "required": ["supported"],
            "properties": { "supported": { "type": "boolean" } },
            "additionalProperties": false
          },
          "receipts": {
            "type": "object",
            "required": ["provider_accepted", "delivered", "read"],
            "properties": {
              "provider_accepted": { "type": "boolean" },
              "delivered": { "type": "boolean" },
              "read": { "type": "boolean" }
            },
            "additionalProperties": false
          },
          "contexts": {
            "type": "object",
            "required": ["private_chat", "thread", "group"],
            "properties": {
              "private_chat": { "$ref": "#/components/schemas/ContextSupport" },
              "thread": { "$ref": "#/components/schemas/ContextSupport" },
              "group": { "$ref": "#/components/schemas/ContextSupport" }
            },
            "additionalProperties": false
          },
          "rate_limit": {
            "type": "object",
            "required": ["strategy"],
            "properties": {
              "strategy": {
                "type": "string",
                "enum": [
                  "provider_retry_after",
                  "token_bucket",
                  "fixed_window",
                  "adaptive",
                  "unknown"
                ]
              },
              "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
            },
            "additionalProperties": false
          },
          "degradation": { "$ref": "#/components/schemas/Degradation" }
        },
        "$defs": {
          "SafeExplanation": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "InteractionCapability": {
            "type": "object",
            "required": ["mode"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["native", "fallback", "unsupported", "conditional"]
              },
              "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "mode": { "enum": ["fallback", "conditional"] }
                  },
                  "required": ["mode"]
                },
                "then": {
                  "required": ["explanation"],
                  "properties": { "explanation": {} }
                }
              }
            ],
            "additionalProperties": false
          },
          "ContextSupport": {
            "type": "object",
            "required": ["mode"],
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["supported", "unsupported", "conditional"]
              },
              "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
            },
            "allOf": [
              {
                "if": {
                  "properties": { "mode": { "const": "conditional" } },
                  "required": ["mode"]
                },
                "then": {
                  "required": ["explanation"],
                  "properties": { "explanation": {} }
                }
              }
            ],
            "additionalProperties": false
          },
          "Degradation": {
            "type": "object",
            "required": ["active"],
            "properties": {
              "active": { "type": "boolean" },
              "code": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "pattern": "^[a-z0-9][a-z0-9._-]*$"
              },
              "explanation": { "$ref": "#/components/schemas/SafeExplanation" }
            },
            "allOf": [
              {
                "if": {
                  "properties": { "active": { "const": true } },
                  "required": ["active"]
                },
                "then": {
                  "required": ["code", "explanation"],
                  "properties": { "code": {}, "explanation": {} }
                },
                "else": {
                  "properties": { "code": false, "explanation": false }
                }
              }
            ],
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "UsageGroupCount": {
        "type": "object",
        "description": "How many of a day's messages fall in one group. `key` is a `MessageState` when grouping by state, a `Channel` when grouping by channel, and a channel connection id when grouping by connection. Groups with no messages are omitted, and a list holds at most the 200 largest groups, largest first.",
        "required": ["key", "count"],
        "properties": {
          "key": { "$ref": "#/components/schemas/GroupKey" },
          "count": { "type": "integer", "minimum": 1 }
        },
        "additionalProperties": false
      },
      "UsageBucket": {
        "type": "object",
        "description": "One UTC day of an environment's accepted messages. `accepted` comes from the usage ledger, which is kept for as long as the environment exists. `groups` comes from the messages themselves, which are kept for 90 days, so a day older than `UsageReport.breakdown_retained_from` has an empty or partial breakdown. Messages sent before channel connections existed carry no connection, so a connection breakdown can sum to less than `accepted`.",
        "required": ["day", "accepted", "groups"],
        "properties": {
          "day": { "$ref": "#/components/schemas/UsageDate" },
          "accepted": { "type": "integer", "minimum": 0 },
          "groups": {
            "type": "array",
            "maxItems": 200,
            "items": { "$ref": "#/components/schemas/UsageGroupCount" }
          }
        },
        "additionalProperties": false
      },
      "SubscriberDataExportRecord": {
        "type": "object",
        "description": "One semantic record held about the subscriber. The source names the durable store or recovered semantic value; data contains plaintext business fields and excludes custody metadata and secrets.",
        "required": ["source", "data"],
        "properties": {
          "source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 96,
            "pattern": "^[a-z][a-z0-9_.-]*$"
          },
          "data": { "type": "object", "additionalProperties": true }
        },
        "additionalProperties": false
      },
      "SubscriberDataExportExcludedControllerData": {
        "type": "object",
        "description": "A category deliberately outside the customer-controller artifact because WhooshBang is controller for it.",
        "required": ["category", "controller", "access"],
        "properties": {
          "category": {
            "type": "string",
            "enum": ["consent_lifecycle_audit", "service_logs"]
          },
          "controller": { "type": "string", "const": "whooshbang" },
          "access": {
            "type": "string",
            "const": "separate_recipient_request_required"
          }
        },
        "additionalProperties": false
      },
      "ConfirmInteractionRequest": {
        "type": "object",
        "required": ["type", "prompt", "expires_at"],
        "properties": {
          "type": { "const": "confirm" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "confirm_label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "deny_label": { "type": "string", "minLength": 1, "maxLength": 40 },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "At least 30 seconds after server acceptance; no fixed maximum. A resolved RFC3339 deadline with millisecond precision, no later than 9999-12-31T23:59:59.999Z."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          }
        },
        "additionalProperties": false
      },
      "InteractionOption": {
        "type": "object",
        "required": ["value", "label"],
        "properties": {
          "value": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
            "description": "Opaque customer data. It is never interpreted as a command."
          },
          "label": { "type": "string", "minLength": 1, "maxLength": 120 },
          "intent": {
            "type": "string",
            "enum": ["accept", "destructive", "informational", "neutral"],
            "default": "neutral",
            "description": "What choosing this option does, so a channel can present it accordingly. Describes consequence rather than appearance: a channel renders `accept` green where it can, `destructive` red, `informational` prominent, and `neutral` plainly. A channel that cannot colour a control ignores this and the option still renders. Omitted means `neutral`."
          }
        },
        "additionalProperties": false
      },
      "SelectInteractionRequest": {
        "type": "object",
        "required": ["type", "prompt", "options", "expires_at"],
        "properties": {
          "type": { "const": "select" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "options": {
            "type": "array",
            "minItems": 2,
            "maxItems": 6,
            "items": { "$ref": "#/components/schemas/InteractionOption" },
            "x-unique-property": "value"
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "At least 30 seconds after server acceptance; no fixed maximum. A resolved RFC3339 deadline with millisecond precision, no later than 9999-12-31T23:59:59.999Z."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          }
        },
        "additionalProperties": false
      },
      "InputInteractionRequest": {
        "type": "object",
        "required": ["type", "prompt", "expires_at"],
        "properties": {
          "type": { "const": "input" },
          "prompt": { "$ref": "#/components/schemas/InteractionPrompt" },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp-2",
            "description": "At least 30 seconds after server acceptance; no fixed maximum. A resolved RFC3339 deadline with millisecond precision, no later than 9999-12-31T23:59:59.999Z."
          },
          "correlation_id": {
            "$ref": "#/components/schemas/InteractionCorrelationId"
          }
        },
        "additionalProperties": false
      },
      "EmailBindingImportRow": {
        "type": "object",
        "required": ["subscriber_id", "notifier_id", "address", "consent"],
        "properties": {
          "subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "notifier_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
          "address": { "$ref": "#/components/schemas/EmailAddress" },
          "consent": { "$ref": "#/components/schemas/EmailBindingConsent" }
        },
        "additionalProperties": false
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request or required idempotency key is invalid.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "requestInvalid": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/request_invalid",
                  "title": "Request invalid",
                  "status": 400,
                  "detail": "One or more request fields are invalid.",
                  "code": "request_invalid",
                  "diagnostic_id": "diag_request_invalid_001",
                  "retryable": false,
                  "field_errors": [
                    {
                      "field": "/content/text",
                      "code": "utf8_bytes_exceeded",
                      "detail": "Text must contain at most 8192 UTF-8 bytes."
                    }
                  ]
                }
              },
              "idempotencyKeyRequired": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/idempotency_key_required",
                  "title": "Invalid idempotency key",
                  "status": 400,
                  "detail": "Idempotency-Key must be 8 to 255 visible ASCII characters.",
                  "code": "idempotency_key_required",
                  "diagnostic_id": "diag_idem_required_001",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "A bearer credential is absent, malformed, invalid, or revoked.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "authenticationRequired": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/authentication_required",
                  "title": "Authentication required",
                  "status": 401,
                  "detail": "Provide a bearer credential.",
                  "code": "authentication_required",
                  "diagnostic_id": "diag_auth_required_001",
                  "retryable": false
                }
              },
              "credentialInvalid": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/credential_invalid",
                  "title": "Credential invalid",
                  "status": 401,
                  "detail": "The bearer credential is malformed, invalid, or revoked.",
                  "code": "credential_invalid",
                  "diagnostic_id": "diag_credential_invalid_001",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential lacks scope or cannot address the requested environment.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "scopeForbidden": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/scope_forbidden",
                  "title": "Scope forbidden",
                  "status": 403,
                  "detail": "The credential does not grant the required operation scope.",
                  "code": "scope_forbidden",
                  "diagnostic_id": "diag_scope_forbidden_001",
                  "retryable": false
                }
              },
              "environmentMismatch": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/environment_mismatch",
                  "title": "Environment mismatch",
                  "status": 403,
                  "detail": "The credential cannot address a binding in another environment.",
                  "code": "environment_mismatch",
                  "diagnostic_id": "diag_environment_001",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource is absent or outside the authenticated project/environment.\nThe response never confirms cross-tenant existence.\n",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "resourceNotFound": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/resource_not_found",
                  "title": "Resource not found",
                  "status": 404,
                  "detail": "The resource was not found.",
                  "code": "resource_not_found",
                  "diagnostic_id": "diag_not_found_001",
                  "retryable": false
                }
              },
              "resourceExpired": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/resource_expired",
                  "title": "Resource expired",
                  "status": 404,
                  "detail": "The resource is no longer available.",
                  "code": "resource_expired",
                  "diagnostic_id": "diag_resource_expired_001",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "Conflict": {
        "description": "An idempotency key, project slug, credential identity, existing\nacknowledgement, or resource state conflicts with the authorized\norganization or request.\n",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "idempotencyConflict": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/idempotency_conflict",
                  "title": "Idempotency conflict",
                  "status": 409,
                  "detail": "The key was already accepted with materially different validated input.",
                  "code": "idempotency_conflict",
                  "diagnostic_id": "diag_idem_conflict_001",
                  "retryable": false
                }
              },
              "projectSlugConflict": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/project_slug_conflict",
                  "title": "Project slug conflict",
                  "status": 409,
                  "detail": "That project slug is already used in this organization.",
                  "code": "project_slug_conflict",
                  "diagnostic_id": "diag_project_slug_conflict_001",
                  "retryable": false,
                  "field_errors": [
                    {
                      "field": "/slug",
                      "code": "already_exists",
                      "detail": "Choose a different project slug."
                    }
                  ]
                }
              },
              "replayUnavailable": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/replay_unavailable",
                  "title": "Replay unavailable",
                  "status": 409,
                  "detail": "Replay is available only after the latest delivery sequence reaches terminal failure.",
                  "code": "replay_unavailable",
                  "diagnostic_id": "diag_replay_unavailable_not_terminal_001",
                  "retryable": false,
                  "field_errors": [
                    {
                      "field": "/",
                      "code": "not_terminal",
                      "detail": "Replay is available only after the latest delivery sequence reaches terminal failure."
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "Unprocessable": {
        "description": "The request is valid in shape but names no usable authorized binding or registered return destination.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "subscriberUnbound": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/subscriber_unbound",
                  "title": "Subscriber unbound",
                  "status": 422,
                  "detail": "No authorized channel binding is available for this subscriber and notifier.",
                  "code": "subscriber_unbound",
                  "diagnostic_id": "diag_subscriber_unbound_001",
                  "retryable": false
                }
              },
              "preferredBindingUnavailable": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/preferred_binding_unavailable",
                  "title": "Preferred binding unavailable",
                  "status": 422,
                  "detail": "The subscriber's preferred binding cannot accept this operation.",
                  "code": "preferred_binding_unavailable",
                  "diagnostic_id": "diag_n17_preference_unavailable",
                  "retryable": false
                }
              },
              "returnDestinationNotFound": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/return_destination_not_found",
                  "title": "Return destination not found",
                  "status": 422,
                  "detail": "The registered return destination is unavailable in this environment.",
                  "code": "return_destination_not_found",
                  "diagnostic_id": "diag_n17_return_not_found",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "RecipientCapabilityInvalid": {
        "description": "The recipient capability is absent, malformed, expired, revoked, or otherwise invalid; no session existence is disclosed.",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "invalid": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/recipient_capability_invalid",
                  "title": "Recipient capability invalid",
                  "status": 401,
                  "detail": "The recipient capability is invalid or no longer active.",
                  "code": "recipient_capability_invalid",
                  "diagnostic_id": "diag_n17_capability_invalid",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "RecipientOriginForbidden": {
        "description": "The presenting exact origin is not allowed by the session's pinned environment configuration.",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "forbidden": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/recipient_origin_forbidden",
                  "title": "Recipient origin forbidden",
                  "status": 403,
                  "detail": "The presenting browser origin is not authorized for this recipient session.",
                  "code": "recipient_origin_forbidden",
                  "diagnostic_id": "diag_n17_origin_forbidden",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "ProviderTerminal": {
        "description": "The endpoint challenge failed in a way that requires developer action.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "providerTerminal": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/provider_terminal",
                  "title": "Provider terminal failure",
                  "status": 502,
                  "detail": "The provider rejected the operation and no automatic retry is scheduled.",
                  "code": "provider_terminal",
                  "diagnostic_id": "diag_provider_terminal_001",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "ProviderOutcomeUnknown": {
        "description": "The provider could not be reached, so whether it applied the operation\nis genuinely unknown. Nothing is retried automatically; read the\nresource before deciding what to do.\n",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "providerOutcomeUnknown": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/provider_outcome_unknown",
                  "title": "Provider outcome unknown",
                  "status": 502,
                  "detail": "The provider may have accepted the operation; no automatic retry is scheduled.",
                  "code": "provider_outcome_unknown",
                  "diagnostic_id": "diag_provider_unknown_002",
                  "retryable": false
                }
              }
            }
          }
        }
      },
      "ProviderRetryable": {
        "description": "The endpoint challenge failed transiently and can be retried safely.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "providerRetryable": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/provider_retryable",
                  "title": "Provider retryable failure",
                  "status": 503,
                  "detail": "The provider call failed before acceptance and may be retried by the service.",
                  "code": "provider_retryable",
                  "diagnostic_id": "diag_provider_retry_001",
                  "retryable": true,
                  "retry_at": "2026-07-25T17:46:00Z"
                }
              }
            }
          }
        }
      },
      "EndpointRotationConflict": {
        "description": "A previous signing-secret overlap must finish before another rotation.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "endpointRotationConflict": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/endpoint_rotation_conflict",
                  "title": "Endpoint rotation conflict",
                  "status": 409,
                  "detail": "A prior signing-secret overlap is still active. Retry after that overlap expires.",
                  "code": "endpoint_rotation_conflict",
                  "diagnostic_id": "diag_endpoint_rotation_conflict_001",
                  "retryable": true,
                  "retry_at": "2026-08-06T14:00:00.000Z"
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "A project or operation rate limit was exceeded.",
        "headers": {
          "WhooshBang-Diagnostic-Id": {
            "$ref": "#/components/headers/DiagnosticId"
          },
          "Retry-After": {
            "description": "Safe delay in seconds when known.",
            "schema": { "type": "integer", "minimum": 1 }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "examples": {
              "rateLimited": {
                "value": {
                  "type": "https://whooshbang.flowxo.com/problems/rate_limited",
                  "title": "Rate limited",
                  "status": 429,
                  "detail": "The project or operation rate limit was exceeded.",
                  "code": "rate_limited",
                  "diagnostic_id": "diag_rate_limited_001",
                  "retryable": true,
                  "retry_at": "2026-07-25T17:46:00Z"
                }
              }
            }
          }
        }
      }
    }
  },
  "x-contract-version": "3.2.0"
}
