{
  "openapi": "3.1.0",
  "info": {
    "title": "GatherCloud API",
    "description": "GatherCloud management REST API (v1 surface).",
    "version": "1.0.0"
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {}
  },
  "paths": {
    "/v1/accounts/signup": {
      "post": {
        "summary": "Sign up a new account",
        "tags": [
          "accounts"
        ],
        "description": "Create an email+password account, provision its first workspace, send a verification email, and set the account session cookie.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Account email address."
                  },
                  "password": {
                    "type": "string",
                    "description": "Account password (min 8 chars)."
                  },
                  "name": {
                    "type": "string",
                    "description": "Account display name."
                  }
                },
                "additionalProperties": true,
                "description": "Account signup credentials."
              }
            }
          },
          "description": "Account signup credentials."
        },
        "responses": {
          "201": {
            "description": "Created account with its workspaces (and a verifyUrl in email dev mode).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created account with its workspaces (and a verifyUrl in email dev mode)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/login": {
      "post": {
        "summary": "Log in to an account",
        "tags": [
          "accounts"
        ],
        "description": "Verify email+password credentials and set the account session cookie.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Account email address."
                  },
                  "password": {
                    "type": "string",
                    "description": "Account password."
                  }
                },
                "additionalProperties": true,
                "description": "Account login credentials."
              }
            }
          },
          "description": "Account login credentials."
        },
        "responses": {
          "200": {
            "description": "Authenticated account with its workspaces.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Authenticated account with its workspaces."
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/logout": {
      "post": {
        "summary": "Log out",
        "tags": [
          "accounts"
        ],
        "description": "Clear the account session cookie.",
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/accounts/me": {
      "get": {
        "summary": "Get the current account",
        "tags": [
          "accounts"
        ],
        "description": "Return the session account with its emails and workspaces.",
        "responses": {
          "200": {
            "description": "The current account, its emails, and its workspaces.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "The current account, its emails, and its workspaces."
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/verify": {
      "post": {
        "summary": "Verify an email address",
        "tags": [
          "accounts"
        ],
        "description": "Mark an account email verified given a valid verification token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Email verification token."
                  }
                },
                "additionalProperties": true,
                "description": "Email verification request."
              }
            }
          },
          "description": "Email verification request."
        },
        "responses": {
          "200": {
            "description": "Verification result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Verification result."
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/request-password-reset": {
      "post": {
        "summary": "Request a password reset",
        "tags": [
          "accounts"
        ],
        "description": "Send a password reset email if the address maps to a password account. Always responds identically to avoid account enumeration.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Account email address."
                  }
                },
                "additionalProperties": true,
                "description": "Password reset request."
              }
            }
          },
          "description": "Password reset request."
        },
        "responses": {
          "200": {
            "description": "Always-ok response (no account enumeration); resetUrl only in email dev mode.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Always-ok response (no account enumeration); resetUrl only in email dev mode."
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/reset-password": {
      "post": {
        "summary": "Reset a password",
        "tags": [
          "accounts"
        ],
        "description": "Set a new password for an account given a valid reset token.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Password reset token."
                  },
                  "password": {
                    "type": "string",
                    "description": "New password (min 8 chars)."
                  }
                },
                "additionalProperties": true,
                "description": "Password reset completion."
              }
            }
          },
          "description": "Password reset completion."
        },
        "responses": {
          "200": {
            "description": "Password reset result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Password reset result."
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/google/start": {
      "get": {
        "summary": "Start the Google OAuth flow",
        "tags": [
          "auth"
        ],
        "description": "Redirect to Google for consent (not configured yet).",
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/auth/google/callback": {
      "get": {
        "summary": "Google OAuth callback",
        "tags": [
          "auth"
        ],
        "description": "Exchange the authorization code, find-or-create the account, set the session cookie, and redirect (not configured yet).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "code",
            "required": false,
            "description": "OAuth 2.0 authorization code."
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "state",
            "required": false,
            "description": "Opaque CSRF state echoed back by Google."
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "error",
            "required": false,
            "description": "OAuth error code, if the flow failed."
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/public/events/{id}": {
      "get": {
        "summary": "Get a public event view",
        "tags": [
          "public"
        ],
        "description": "Fetch the public lobby/stage view for an event: phases, on-stage cast (names only), and the active broadcast. Private events require a session of the owning workspace.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Public event view (lobby/stage state).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Public event view (lobby/stage state)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/events/{id}/table-summary": {
      "get": {
        "summary": "Read your own table’s notes",
        "tags": [
          "public"
        ],
        "description": "Exchange the token from a \"notes from your table\" email for that one table’s notes. Never returns another table’s content.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "in": "query",
            "name": "t",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "event",
                    "table",
                    "recipientUserId",
                    "recipientName",
                    "summary",
                    "stats",
                    "people",
                    "generatedAt"
                  ],
                  "properties": {
                    "event": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "scheduledAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "scheduledAt": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "additionalProperties": true
                    },
                    "table": {
                      "type": "object",
                      "required": [
                        "roomId",
                        "number",
                        "label"
                      ],
                      "properties": {
                        "roomId": {
                          "type": "string"
                        },
                        "number": {
                          "type": "integer"
                        },
                        "label": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    },
                    "recipientUserId": {
                      "type": "string"
                    },
                    "recipientName": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "summary": {
                      "type": "object",
                      "required": [
                        "tldr",
                        "themes",
                        "ideas",
                        "questions",
                        "perQuestion"
                      ],
                      "properties": {
                        "tldr": {
                          "type": "string"
                        },
                        "themes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "title",
                              "summary"
                            ],
                            "properties": {
                              "title": {
                                "type": "string"
                              },
                              "summary": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "ideas": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "questions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "perQuestion": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "ordinal",
                              "question",
                              "discussed",
                              "summary"
                            ],
                            "properties": {
                              "ordinal": {
                                "type": "integer"
                              },
                              "question": {
                                "type": "string"
                              },
                              "discussed": {
                                "type": "boolean"
                              },
                              "summary": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "additionalProperties": true
                    },
                    "stats": {
                      "anyOf": [
                        {
                          "type": "object",
                          "required": [
                            "totalWords",
                            "promptsCovered",
                            "promptsTotal",
                            "lifetimeSeconds",
                            "headcount"
                          ],
                          "properties": {
                            "totalWords": {
                              "type": "integer"
                            },
                            "promptsCovered": {
                              "type": "integer"
                            },
                            "promptsTotal": {
                              "type": "integer"
                            },
                            "lifetimeSeconds": {
                              "type": "integer"
                            },
                            "headcount": {
                              "type": "integer"
                            }
                          },
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "people": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "userId",
                          "name",
                          "words",
                          "turns",
                          "badges"
                        ],
                        "properties": {
                          "userId": {
                            "type": "string"
                          },
                          "name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "words": {
                            "type": "integer"
                          },
                          "turns": {
                            "type": "integer"
                          },
                          "badges": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "id",
                                "name",
                                "description",
                                "tier",
                                "icon"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": "string"
                                },
                                "tier": {
                                  "type": "integer"
                                },
                                "icon": {
                                  "type": "string"
                                },
                                "glyph": {
                                  "type": "string"
                                }
                              },
                              "additionalProperties": true
                            }
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "generatedAt": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/events/{id}/recap": {
      "get": {
        "summary": "Get a public event recap",
        "tags": [
          "public"
        ],
        "description": "Fetch an event’s recap: latest recording, clips, and AI summary (text + speaker stats). Private events require a session of the owning workspace.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Public event recap (recording, clips, summary).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Public event recap (recording, clips, summary)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/events/{id}/content": {
      "get": {
        "summary": "Get public post-event content",
        "tags": [
          "public"
        ],
        "description": "Fetch an event’s full post-event content (recording, derivations, generated media, cast) for the shareable replay page. Private events require a session of the owning workspace.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Public post-event content (recording, derivations, generated media) for the shareable replay page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Public post-event content (recording, derivations, generated media) for the shareable replay page."
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/assets/{id}": {
      "get": {
        "summary": "Get a public asset",
        "tags": [
          "public"
        ],
        "description": "Fetch a single asset (clip/recording) with its event context, for share-link targets. Gated on the parent event’s visibility.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Public asset view with event context.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Public asset view with event context."
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/events/{id}/register": {
      "post": {
        "summary": "Register for an event",
        "tags": [
          "public"
        ],
        "description": "Public self-registration: sign up for an event with a name and email. Rejected with `event_full` once the participant capacity is reached. Private events cannot be self-registered for.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "email"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320,
                    "format": "email"
                  }
                },
                "additionalProperties": false,
                "description": "Public self-registration for an event."
              }
            }
          },
          "description": "Public self-registration for an event."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Result of a public self-registration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "registered",
                    "alreadyRegistered"
                  ],
                  "properties": {
                    "registered": {
                      "type": "boolean"
                    },
                    "alreadyRegistered": {
                      "type": "boolean"
                    }
                  },
                  "description": "Result of a public self-registration."
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/events/{id}/enter": {
      "post": {
        "summary": "Enter an event from a registration link",
        "tags": [
          "public"
        ],
        "description": "Exchange the registration-entry token from the self-registration confirmation email for a session token, so the registrant can join the event room.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "additionalProperties": false,
                "description": "Registration-entry token exchange."
              }
            }
          },
          "description": "Registration-entry token exchange."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "A session for the registrant, minted from their entry token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "sessionToken",
                    "eventId",
                    "name"
                  ],
                  "properties": {
                    "sessionToken": {
                      "type": "string"
                    },
                    "eventId": {
                      "type": "string"
                    },
                    "name": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "description": "A session for the registrant, minted from their entry token."
                }
              }
            }
          }
        }
      }
    },
    "/v1/help/chat": {
      "post": {
        "summary": "Ask the in-product help assistant",
        "tags": [
          "help"
        ],
        "description": "Answer a question about using GatherCloud, grounded in the product FAQ. Unauthenticated and rate-limited; replies are not stored or broadcast.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "messages"
                ],
                "properties": {
                  "audience": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "host"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "viewer"
                        ]
                      }
                    ],
                    "description": "Which audience the assistant should answer as."
                  },
                  "surface": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "room"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "dashboard"
                        ]
                      }
                    ],
                    "description": "Where the user is asking from."
                  },
                  "eventType": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  },
                  "stage": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "prelive"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "open"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "live"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "ended"
                        ]
                      }
                    ]
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "object",
                          "required": [
                            "role",
                            "text"
                          ],
                          "properties": {
                            "role": {
                              "type": "string",
                              "enum": [
                                "user"
                              ]
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            }
                          },
                          "additionalProperties": false
                        },
                        {
                          "type": "object",
                          "required": [
                            "role",
                            "text"
                          ],
                          "properties": {
                            "role": {
                              "type": "string",
                              "enum": [
                                "model"
                              ]
                            },
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 2200
                            }
                          },
                          "additionalProperties": false
                        }
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 8
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "security": [],
        "responses": {
          "200": {
            "description": "The assistant reply for the latest user turn.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "reply"
                  ],
                  "properties": {
                    "reply": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true,
                  "description": "The assistant reply for the latest user turn."
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/gateway-token": {
      "post": {
        "summary": "Mint a gateway token",
        "tags": [
          "auth"
        ],
        "description": "Mint a short-lived Live Gateway WebSocket token for an event. A Bearer session token grants the caller their event role, narrowed to one the event actually has (workspace owners/admins default to host); without one, an anonymous viewer token is issued for public events that contain a broadcast phase. A signed-out caller on a call (meeting/breakout/rotation) is refused with `sign_in_required` — there is no anonymous seat to give them.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "eventId"
                ],
                "properties": {
                  "eventId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/guest-session": {
      "post": {
        "summary": "Exchange a partner JWT for a guest session",
        "tags": [
          "auth"
        ],
        "description": "Verify a partner-issued JWT against the event workspace’s registered guest integration and mint an ephemeral guest session scoped to this event. Guests get a real in-room identity from the JWT claims but no account, workspace, or persistent record. If the JWT email belongs to an existing GatherCloud account, the exchange is refused (409) and the caller must log in instead.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The raw partner-issued JWT."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/guest-integrations": {
      "post": {
        "summary": "Register a partner guest-JWT integration",
        "tags": [
          "guest-integrations"
        ],
        "description": "Register a partner platform (issuer + public key material) whose RS256-signed JWTs may join this workspace’s events as named guests. Provide exactly one of jwksUrl / publicKeyPem.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "issuer"
                ],
                "properties": {
                  "issuer": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The partner JWT's `iss` claim, verbatim."
                  },
                  "jwksUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "JWKS endpoint publishing the signing keys."
                  },
                  "publicKeyPem": {
                    "type": "string",
                    "minLength": 1,
                    "description": "SPKI PEM public key (RS256)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List partner guest-JWT integrations",
        "tags": [
          "guest-integrations"
        ],
        "description": "List the workspace’s active (non-revoked) guest integrations.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/guest-integrations/{integrationId}": {
      "delete": {
        "summary": "Revoke a partner guest-JWT integration",
        "tags": [
          "guest-integrations"
        ],
        "description": "Revoke an integration: new guest-session exchanges for its issuer are refused immediately. Already-minted guest sessions run out their TTL.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "integrationId",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/workspaces": {
      "post": {
        "summary": "Create a workspace",
        "tags": [
          "workspaces"
        ],
        "description": "Self-serve workspace creation by any logged-in account (ADR 0007). A first \"default\" API key is generated and returned once in the response.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "slug": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created workspace plus the first API key (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created workspace plus the first API key (shown once)."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List workspaces",
        "tags": [
          "workspaces"
        ],
        "description": "List the calling account’s workspaces. With a valid x-platform-key header, lists all workspaces (platform ops).",
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "workspaces"
                  ],
                  "properties": {
                    "workspaces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true,
                        "description": "Workspace resource."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}": {
      "patch": {
        "summary": "Update a workspace",
        "tags": [
          "workspaces"
        ],
        "description": "Rename a workspace and/or change its slug (owner/admin only). The slug is the workspace’s public handle, so it is kept unique and well-formed.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Updated workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Updated workspace."
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/members": {
      "get": {
        "summary": "List workspace members",
        "tags": [
          "workspaces"
        ],
        "description": "List the workspace’s members with their role and primary email. Any member of the workspace may view this.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "members"
                  ],
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/members/{memberId}": {
      "patch": {
        "summary": "Update a member role",
        "tags": [
          "workspaces"
        ],
        "description": "Change a member role between \"member\" and \"admin\" (owner/admin only). Owner roles are protected and cannot be changed via this endpoint.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "role"
                ],
                "properties": {
                  "role": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "member"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "admin"
                        ]
                      }
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "memberId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Updated member.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Updated member."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a member",
        "tags": [
          "workspaces"
        ],
        "description": "Remove a member from the workspace (owner/admin only). Owners cannot be removed. To remove yourself use DELETE /v1/workspaces/:id/members/me.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "memberId",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/workspaces/{id}/members/me": {
      "delete": {
        "summary": "Leave a workspace",
        "tags": [
          "workspaces"
        ],
        "description": "Remove yourself from the workspace. Blocked if you are the only owner — transfer ownership or promote another member to owner first.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/workspaces/{id}/session": {
      "post": {
        "summary": "Mint a workspace session token",
        "tags": [
          "workspaces"
        ],
        "description": "THE BRIDGE (ADR 0007): exchange an account session for a workspace session token. Upserts the account’s per-workspace participant identity (users row) and mints the workspace session token.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace session token plus the bridged participant identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Workspace session token plus the bridged participant identity."
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/api-keys": {
      "get": {
        "summary": "List workspace API keys",
        "tags": [
          "api-keys"
        ],
        "description": "List the workspace’s API keys (owner/admin only). Key secrets are never returned — only metadata and revocation state.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apiKeys"
                  ],
                  "properties": {
                    "apiKeys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a workspace API key",
        "tags": [
          "api-keys"
        ],
        "description": "Create a new API key for the workspace (owner/admin only). The secret key value is returned once in this response and never again.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Created API key, including the secret key value (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created API key, including the secret key value (shown once)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/api-keys/{keyId}": {
      "delete": {
        "summary": "Revoke or delete a workspace API key",
        "tags": [
          "api-keys"
        ],
        "description": "Owner/admin only. The first DELETE soft-revokes the key (the row stays auditable); a second DELETE on an already-revoked key removes it permanently.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "keyId",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/api-keys": {
      "post": {
        "summary": "Create an API key (API-key authed)",
        "tags": [
          "api-keys"
        ],
        "description": "API-first self-service: create a new API key for the workspace scoped by the calling key (x-api-key). The new secret key value is returned once.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created API key, including the secret key value (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created API key, including the secret key value (shown once)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{id}/invites": {
      "post": {
        "summary": "Create an invite",
        "tags": [
          "invites"
        ],
        "description": "Create a workspace or event invite (admin/owner account session, or the workspace API key). The token is the authority; the link is returned once for link/dev invites.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string"
                  },
                  "kind": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "workspace"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "event"
                        ]
                      }
                    ],
                    "description": "Whether an invite grants workspace or event access.",
                    "title": "InviteKind"
                  },
                  "eventId": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Created invite metadata plus, for link/dev invites, the invite URL (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created invite metadata plus, for link/dev invites, the invite URL (shown once)."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List workspace invites",
        "tags": [
          "invites"
        ],
        "description": "List the workspace’s invites for the members screen. Any member of the workspace may view this.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "invites"
                  ],
                  "properties": {
                    "invites": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/invites/{token}": {
      "get": {
        "summary": "Preview an invite",
        "tags": [
          "invites"
        ],
        "description": "Public preview of an invite — what the /invite/:token page renders.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "token",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Public invite preview for the /invite/:token page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Public invite preview for the /invite/:token page."
                }
              }
            }
          }
        }
      }
    },
    "/v1/invites/{token}/accept": {
      "post": {
        "summary": "Accept an invite",
        "tags": [
          "invites"
        ],
        "description": "Accept an invite as the logged-in account. The token is the authority; an email mismatch is a UX confirmation, never an error.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "token",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Acceptance result (workspace or event binding).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Acceptance result (workspace or event binding)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/invites/{token}/attend": {
      "post": {
        "summary": "Attend an event invite without an account",
        "tags": [
          "invites"
        ],
        "description": "Join an event from an invite link WITHOUT an account: name-only join. Mints a workspace session for a gc-invite participant; the link is multi-use.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "titleOrg": {
                    "type": "string",
                    "maxLength": 80
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "token",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace session token for an accountless attendee plus their participant identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Workspace session token for an accountless attendee plus their participant identity."
                }
              }
            }
          }
        }
      }
    },
    "/v1/invites/{id}": {
      "delete": {
        "summary": "Revoke an invite",
        "tags": [
          "invites"
        ],
        "description": "Revoke an invite (admin/owner account session, or the workspace API key). Auth is dispatched inside the handler once the invite’s workspace is known.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/invites/{id}/resend": {
      "post": {
        "summary": "Resend an invite email",
        "tags": [
          "invites"
        ],
        "description": "Re-deliver an addressed invite. Mints a fresh token (the old link stops working) and renews expiry, then emails the recipient. Admin/owner account session, or the workspace API key.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Created invite metadata plus, for link/dev invites, the invite URL (shown once).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Created invite metadata plus, for link/dev invites, the invite URL (shown once)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "post": {
        "summary": "Create an event",
        "tags": [
          "events"
        ],
        "description": "Create an event, optionally with an initial ordered list of phases. A session-authed creator is enrolled as host.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "title"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1
                  },
                  "scheduledAt": {
                    "type": "string"
                  },
                  "scheduledEndAt": {
                    "type": "string"
                  },
                  "visibility": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "public"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "unlisted"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "private"
                        ]
                      }
                    ],
                    "description": "Event discoverability.",
                    "title": "Visibility"
                  },
                  "allowAnonymousVoting": {
                    "type": "boolean"
                  },
                  "allowAnonymousQuestions": {
                    "type": "boolean"
                  },
                  "capacity": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "properties": {
                      "design": {
                        "type": "object",
                        "properties": {
                          "background": {
                            "anyOf": [
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "url"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "image"
                                    ]
                                  },
                                  "url": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "color"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "color"
                                    ]
                                  },
                                  "color": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "css"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "gradient"
                                    ]
                                  },
                                  "css": {
                                    "type": "string"
                                  },
                                  "from": {
                                    "type": "string"
                                  },
                                  "to": {
                                    "type": "string"
                                  },
                                  "style": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "preset"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "animated"
                                    ]
                                  },
                                  "preset": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "enum": [
                                          "aurora"
                                        ]
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "mesh"
                                        ]
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "drift"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              }
                            ]
                          },
                          "accentColor": {
                            "type": "string"
                          },
                          "tileBorderColor": {
                            "type": "string"
                          },
                          "logoUrl": {
                            "type": "string"
                          },
                          "layout": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false,
                        "description": "Host-configured stage look (RoomDesign)."
                      }
                    },
                    "additionalProperties": true,
                    "description": "Caller-supplied metadata."
                  },
                  "phases": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "modality": {
                          "anyOf": [
                            {
                              "type": "string",
                              "enum": [
                                "broadcast"
                              ]
                            },
                            {
                              "type": "string",
                              "enum": [
                                "breakout"
                              ]
                            },
                            {
                              "type": "string",
                              "enum": [
                                "meeting"
                              ]
                            },
                            {
                              "type": "string",
                              "enum": [
                                "rotation"
                              ]
                            }
                          ],
                          "description": "The behaviour of a phase.",
                          "title": "Modality"
                        },
                        "config": {
                          "type": "object",
                          "properties": {
                            "roomSize": {
                              "type": "number"
                            },
                            "durationSeconds": {
                              "type": "number"
                            },
                            "openConversationSeconds": {
                              "type": "number"
                            },
                            "extendable": {
                              "type": "boolean"
                            },
                            "rebalanceThreshold": {
                              "type": "number"
                            },
                            "lobby": {
                              "type": "boolean"
                            },
                            "lobbyWaitSeconds": {
                              "type": "number"
                            },
                            "rounds": {
                              "type": "number"
                            },
                            "roundSeconds": {
                              "type": "number"
                            }
                          },
                          "additionalProperties": true,
                          "description": "Modality-specific phase settings.",
                          "title": "PhaseConfig"
                        },
                        "featureSet": {
                          "type": "array",
                          "items": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "qa"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "chat"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "polls"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "reactions"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "transcript"
                                ]
                              },
                              {
                                "type": "string",
                                "enum": [
                                  "capture"
                                ]
                              }
                            ],
                            "description": "Interactive feature toggle.",
                            "title": "Feature"
                          }
                        }
                      },
                      "description": "Phase definition."
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Event resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Event resource."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List events",
        "tags": [
          "events"
        ],
        "description": "List the workspace’s most recent events (max 100).",
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "events"
                  ],
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true,
                        "description": "Event resource."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}": {
      "get": {
        "summary": "Get an event",
        "tags": [
          "events"
        ],
        "description": "Fetch a single event with its ordered phases.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Event with its ordered phases.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "phases"
                  ],
                  "properties": {
                    "phases": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true,
                        "description": "Phase resource."
                      }
                    }
                  },
                  "additionalProperties": true,
                  "description": "Event with its ordered phases."
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update an event",
        "tags": [
          "events"
        ],
        "description": "Patch event fields. Schedule (start/end) changes bump the calendar sequence and resend the .ics invite (ADR 0008).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "scheduledAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "scheduledEndAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "visibility": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "public"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "unlisted"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "private"
                        ]
                      }
                    ],
                    "description": "Event discoverability."
                  },
                  "allowAnonymousVoting": {
                    "type": "boolean"
                  },
                  "allowAnonymousQuestions": {
                    "type": "boolean"
                  },
                  "capacity": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "properties": {
                      "design": {
                        "type": "object",
                        "properties": {
                          "background": {
                            "anyOf": [
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "url"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "image"
                                    ]
                                  },
                                  "url": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "color"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "color"
                                    ]
                                  },
                                  "color": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "css"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "gradient"
                                    ]
                                  },
                                  "css": {
                                    "type": "string"
                                  },
                                  "from": {
                                    "type": "string"
                                  },
                                  "to": {
                                    "type": "string"
                                  },
                                  "style": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "kind",
                                  "preset"
                                ],
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "animated"
                                    ]
                                  },
                                  "preset": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "enum": [
                                          "aurora"
                                        ]
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "mesh"
                                        ]
                                      },
                                      {
                                        "type": "string",
                                        "enum": [
                                          "drift"
                                        ]
                                      }
                                    ]
                                  }
                                }
                              }
                            ]
                          },
                          "accentColor": {
                            "type": "string"
                          },
                          "tileBorderColor": {
                            "type": "string"
                          },
                          "logoUrl": {
                            "type": "string"
                          },
                          "layout": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false,
                        "description": "Host-configured stage look (RoomDesign)."
                      }
                    },
                    "additionalProperties": true,
                    "description": "Caller-supplied metadata."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Event resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Event resource."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete (cancel) an event",
        "tags": [
          "events"
        ],
        "description": "Delete an event. This is the cancel path: calendar invites are cancelled before the row is removed (ADR 0008).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/calendar.ics": {
      "get": {
        "summary": "Download the event as an iCalendar (.ics) file",
        "tags": [
          "events"
        ],
        "description": "Export the event as an .ics file to import into Google Calendar, Outlook or Apple Calendar. Uses the same UID and calendar sequence as the emailed invites, so re-importing after a reschedule updates the existing calendar entry in place (ADR 0008).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/publish": {
      "post": {
        "summary": "Publish an event",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/start": {
      "post": {
        "summary": "Start an event",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/advance": {
      "post": {
        "summary": "Advance to the next phase",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/end": {
      "post": {
        "summary": "End an event",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/phases": {
      "post": {
        "summary": "Append a phase to an event",
        "tags": [
          "events"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "modality": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "broadcast"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "breakout"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "meeting"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "rotation"
                        ]
                      }
                    ],
                    "description": "The behaviour of a phase."
                  },
                  "config": {
                    "type": "object",
                    "properties": {
                      "roomSize": {
                        "type": "number"
                      },
                      "durationSeconds": {
                        "type": "number"
                      },
                      "openConversationSeconds": {
                        "type": "number"
                      },
                      "extendable": {
                        "type": "boolean"
                      },
                      "rebalanceThreshold": {
                        "type": "number"
                      },
                      "lobby": {
                        "type": "boolean"
                      },
                      "lobbyWaitSeconds": {
                        "type": "number"
                      },
                      "rounds": {
                        "type": "number"
                      },
                      "roundSeconds": {
                        "type": "number"
                      }
                    },
                    "additionalProperties": true,
                    "description": "Modality-specific phase settings."
                  },
                  "featureSet": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "qa"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "chat"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "polls"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "reactions"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "transcript"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "capture"
                          ]
                        }
                      ],
                      "description": "Interactive feature toggle."
                    }
                  }
                },
                "description": "Phase definition."
              }
            }
          },
          "description": "Phase definition."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Phase resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Phase resource."
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}/extend": {
      "post": {
        "summary": "Extend the active phase timer",
        "tags": [
          "events"
        ],
        "description": "Add seconds (10–3600) to the active phase’s timer.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "seconds"
                ],
                "properties": {
                  "seconds": {
                    "type": "integer",
                    "minimum": 10,
                    "maximum": 3600
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "extendedBySeconds"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "extendedBySeconds": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}": {
      "patch": {
        "summary": "Update a phase",
        "tags": [
          "events"
        ],
        "description": "Patch a phase’s config and/or feature set.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "modality": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "broadcast"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "breakout"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "meeting"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "rotation"
                        ]
                      }
                    ],
                    "description": "The behaviour of a phase."
                  },
                  "config": {
                    "type": "object",
                    "properties": {
                      "roomSize": {
                        "type": "number"
                      },
                      "durationSeconds": {
                        "type": "number"
                      },
                      "openConversationSeconds": {
                        "type": "number"
                      },
                      "extendable": {
                        "type": "boolean"
                      },
                      "rebalanceThreshold": {
                        "type": "number"
                      },
                      "lobby": {
                        "type": "boolean"
                      },
                      "lobbyWaitSeconds": {
                        "type": "number"
                      },
                      "rounds": {
                        "type": "number"
                      },
                      "roundSeconds": {
                        "type": "number"
                      }
                    },
                    "additionalProperties": true,
                    "description": "Modality-specific phase settings."
                  },
                  "featureSet": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "qa"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "chat"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "polls"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "reactions"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "transcript"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "capture"
                          ]
                        }
                      ],
                      "description": "Interactive feature toggle."
                    }
                  }
                },
                "description": "Phase definition."
              }
            }
          },
          "description": "Phase definition."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Phase resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Phase resource."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/memberships": {
      "post": {
        "summary": "Assign an event membership role",
        "tags": [
          "events"
        ],
        "description": "Assign (or update) a user’s role on an event. Role designation is GatherCloud-side, never a JWT claim.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "userId",
                  "role"
                ],
                "properties": {
                  "userId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "role": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "workspace_admin"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "host"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "speaker"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "participant"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "viewer"
                        ]
                      }
                    ],
                    "description": "Per-event membership role.",
                    "title": "Role"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "Membership resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Membership resource."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/attendees": {
      "get": {
        "summary": "List live attendees",
        "tags": [
          "events"
        ],
        "description": "Host view: the event’s present attendees (those who have not left).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Live attendee roster (host view).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "attendees"
                  ],
                  "properties": {
                    "attendees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "description": "Live attendee roster (host view)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/registrations": {
      "get": {
        "summary": "List registered participants",
        "tags": [
          "events"
        ],
        "description": "Host view: everyone registered for the event (an attendee-role membership that has not left), with their name, email and registration time, plus the confirmed count against capacity. Emails are host-only, so this is gated to hosts/admins.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Registered participants with a confirmed count vs capacity (host view).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "registrations",
                    "confirmedCount",
                    "capacity"
                  ],
                  "properties": {
                    "registrations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "confirmedCount": {
                      "type": "integer"
                    },
                    "capacity": {
                      "anyOf": [
                        {
                          "type": "integer"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "description": "Registered participants with a confirmed count vs capacity (host view)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/my-kick-status": {
      "get": {
        "summary": "Get my kick status",
        "tags": [
          "events"
        ],
        "description": "Whether the calling session has been removed from the event. Polled by attendees as a fallback when the realtime gateway is unavailable.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Whether the caller has been removed from the event.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Whether the caller has been removed from the event."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/memberships/{userId}": {
      "delete": {
        "summary": "Remove (kick) an attendee",
        "tags": [
          "events"
        ],
        "description": "Host-only: remove an attendee from the event and evict them from their media room. Session callers need host/workspace_admin; API-key callers have full access.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "userId",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/breakout/overview": {
      "get": {
        "summary": "List breakout rooms with participants",
        "tags": [
          "events"
        ],
        "description": "Host view: every open room in the active phase, each with the participants currently assigned to it (name, role, membership id). Session callers need host/workspace_admin.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Open rooms of the active phase, each with its participants (host view).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "rooms",
                    "self"
                  ],
                  "properties": {
                    "rooms": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    },
                    "self": {
                      "type": "object",
                      "required": [
                        "roomId",
                        "mode",
                        "canChoose"
                      ],
                      "properties": {
                        "roomId": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mode": {
                          "anyOf": [
                            {
                              "type": "string",
                              "enum": [
                                "participant"
                              ]
                            },
                            {
                              "type": "string",
                              "enum": [
                                "observer"
                              ]
                            }
                          ],
                          "description": "How a host enters a breakout table.",
                          "title": "BreakoutJoinMode"
                        },
                        "canChoose": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true,
                  "description": "Open rooms of the active phase, each with its participants (host view)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/breakout/move": {
      "post": {
        "summary": "Move a participant between rooms",
        "tags": [
          "events"
        ],
        "description": "Host-only: reassign a participant (by membership) to another open room in the same active phase, evict them from their current room, and push a room event so their client reconnects to the new room.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "membershipId",
                  "toRoomId"
                ],
                "properties": {
                  "membershipId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "toRoomId": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "additionalProperties": false,
                "description": "Move a participant into another open room."
              }
            }
          },
          "description": "Move a participant into another open room."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Move result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Move result."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/breakout/join": {
      "post": {
        "summary": "Enter a breakout table as a participant or observer",
        "tags": [
          "events"
        ],
        "description": "Host-only: put the caller into one of the active breakout’s open tables, either as an ordinary participant or as an observer who watches without taking part in the table. Evicts them from their previous table and pushes a room event so their own client reconnects to the new one.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "roomId",
                  "mode"
                ],
                "properties": {
                  "roomId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "mode": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "participant"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "observer"
                        ]
                      }
                    ],
                    "description": "How a host enters a breakout table."
                  }
                },
                "additionalProperties": false,
                "description": "Enter one of the active breakout’s tables as a participant or an observer."
              }
            }
          },
          "description": "Enter one of the active breakout’s tables as a participant or an observer."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The table the caller is now in, and how.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "The table the caller is now in, and how."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/breakout/leave": {
      "post": {
        "summary": "Step out of a breakout table",
        "tags": [
          "events"
        ],
        "description": "Host-only: leave the caller’s current breakout table and return to the room overview. Evicts them from the media room and clears their table assignment; other participants are unaffected.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Result of stepping out of a breakout table.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Result of stepping out of a breakout table."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/questions": {
      "get": {
        "summary": "List event questions",
        "tags": [
          "events"
        ],
        "description": "List an event’s questions with their vote tallies, top first.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "questions"
                  ],
                  "properties": {
                    "questions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/assets": {
      "get": {
        "summary": "List event assets",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "assets"
                  ],
                  "properties": {
                    "assets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{id}": {
      "delete": {
        "summary": "Soft-delete a segment",
        "tags": [
          "events"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/segments/{id}/playback": {
      "get": {
        "summary": "Get a recording part’s playback URL",
        "tags": [
          "events"
        ],
        "description": "Resolve one recording segment’s playback URL on demand (derived from the Mux asset’s playback id). Returns a null URL with a status while the asset is still processing or unavailable.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "On-demand playback URL + status for one recording part.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "On-demand playback URL + status for one recording part."
                }
              }
            }
          }
        }
      }
    },
    "/v1/users": {
      "get": {
        "summary": "List workspace users",
        "tags": [
          "events"
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "users"
                  ],
                  "properties": {
                    "users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Pre-provision a workspace user",
        "tags": [
          "events"
        ],
        "description": "Upsert a user by external subject (workspace directory bridge).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "externalSub"
                ],
                "properties": {
                  "externalSub": {
                    "type": "string",
                    "minLength": 1
                  },
                  "email": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "picture": {
                    "type": "string"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "User resource."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/prompts": {
      "get": {
        "summary": "List an event’s discussion prompts",
        "tags": [
          "prompts"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The event’s discussion prompts, in order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "prompts"
                  ],
                  "properties": {
                    "prompts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true,
                  "description": "The event’s discussion prompts, in order."
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Append a discussion prompt",
        "tags": [
          "prompts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "turnSeconds": {
                    "type": "integer",
                    "minimum": 15,
                    "maximum": 1800
                  }
                },
                "additionalProperties": false,
                "description": "A discussion question to append."
              }
            }
          },
          "description": "A discussion question to append."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "201": {
            "description": "A discussion prompt.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "A discussion prompt."
                }
              }
            }
          }
        }
      }
    },
    "/v1/prompts/{id}": {
      "patch": {
        "summary": "Update a discussion prompt",
        "tags": [
          "prompts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "turnSeconds": {
                    "type": "integer",
                    "minimum": 15,
                    "maximum": 1800
                  }
                },
                "additionalProperties": false,
                "description": "Patch a discussion question."
              }
            }
          },
          "description": "Patch a discussion question."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A discussion prompt.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "A discussion prompt."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a discussion prompt",
        "tags": [
          "prompts"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/prompts/reorder": {
      "post": {
        "summary": "Reorder an event’s discussion prompts",
        "tags": [
          "prompts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "uniqueItems": true
                  }
                },
                "additionalProperties": false,
                "description": "Reorder the event’s prompts."
              }
            }
          },
          "description": "Reorder the event’s prompts."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The event’s discussion prompts, in order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "prompts"
                  ],
                  "properties": {
                    "prompts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true,
                  "description": "The event’s discussion prompts, in order."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/prompts/generate": {
      "post": {
        "summary": "AI-draft discussion prompts from the event",
        "tags": [
          "prompts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                  }
                },
                "additionalProperties": false,
                "description": "AI-draft discussion questions from the event."
              }
            }
          },
          "description": "AI-draft discussion questions from the event."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The event’s discussion prompts, in order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "prompts"
                  ],
                  "properties": {
                    "prompts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true,
                  "description": "The event’s discussion prompts, in order."
                }
              }
            }
          }
        }
      }
    },
    "/v1/rooms/{roomId}/prompts/advance": {
      "post": {
        "summary": "Advance this breakout table to the next discussion prompt",
        "tags": [
          "prompts"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "roomId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A discussion prompt.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "A discussion prompt."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/media-token": {
      "post": {
        "summary": "Mint a media join token",
        "tags": [
          "media"
        ],
        "description": "Mint a media-server token for the session user to join the active phase’s room. Lazily enrolls an eligible session user as a participant (or host, for workspace admins) when they have no membership yet.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Media join token + room coordinates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Media join token + room coordinates."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/lobby/join-now": {
      "post": {
        "summary": "Leave the lobby and join a table now",
        "tags": [
          "media"
        ],
        "description": "Skip the breakout lobby wait and place the caller into a table right away (emptiest open table, or a new one if none are open).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Media join token + room coordinates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Media join token + room coordinates."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/extend": {
      "post": {
        "summary": "Extend the caller’s breakout table (participant)",
        "tags": [
          "media"
        ],
        "description": "Add seconds to the caller’s own breakout table’s open-conversation buffer. Allowed only when the breakout has a duration and the host enabled extensions, and the caller is seated at a table. Other tables and the phase hard limit are unaffected; cumulative extension is capped.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "seconds"
                ],
                "properties": {
                  "seconds": {
                    "type": "integer",
                    "minimum": 10,
                    "maximum": 3600
                  }
                },
                "additionalProperties": false,
                "description": "Seconds to add to the active breakout timer."
              }
            }
          },
          "description": "Seconds to add to the active breakout timer."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Extend result (seconds added).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Extend result (seconds added)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/rooms/{id}/transcript-cues": {
      "post": {
        "summary": "Push transcript cues",
        "tags": [
          "media"
        ],
        "description": "Client-push path for on-device transcription: room participants stream cues up, which are stored and fanned out as live domain events. Only open while the room’s transcription is active (never in the green room or during a pause).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cues": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "tsStart": {
                          "type": "number"
                        },
                        "tsEnd": {
                          "type": "number"
                        },
                        "text": {
                          "type": "string"
                        },
                        "speaker": {
                          "type": "string"
                        }
                      },
                      "description": "A single transcript cue."
                    }
                  }
                },
                "additionalProperties": false,
                "description": "Batch of transcript cues to ingest."
              }
            }
          },
          "description": "Batch of transcript cues to ingest."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Ingestion result (accepted count).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Ingestion result (accepted count)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}/broadcast/start": {
      "post": {
        "summary": "Start (or resume) a broadcast",
        "tags": [
          "broadcasts"
        ],
        "description": "Take the phase’s broadcast offline|paused → live, opening a new recording segment and returning its playback URL.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast went live; the new segment ordinal and playback URL.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Broadcast went live; the new segment ordinal and playback URL."
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}/broadcast/pause": {
      "post": {
        "summary": "Pause a broadcast",
        "tags": [
          "broadcasts"
        ],
        "description": "Pause a live broadcast (live → paused), closing the open segment.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast paused or stopped; the closed segment’s asset id (if any).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Broadcast paused or stopped; the closed segment’s asset id (if any)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}/broadcast/stop": {
      "post": {
        "summary": "Stop a broadcast",
        "tags": [
          "broadcasts"
        ],
        "description": "Stop a live broadcast (live → offline), closing the open segment.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast paused or stopped; the closed segment’s asset id (if any).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Broadcast paused or stopped; the closed segment’s asset id (if any)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/phases/{id}/broadcast/resume": {
      "post": {
        "summary": "Resume a broadcast",
        "tags": [
          "broadcasts"
        ],
        "description": "Alias for start-from-paused: redirects (307) to the broadcast start route.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/segments": {
      "get": {
        "summary": "List broadcast segments",
        "tags": [
          "broadcasts"
        ],
        "description": "List an event’s broadcast segments, ordered.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "An event’s broadcast segments, ordered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "segments"
                  ],
                  "properties": {
                    "segments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "description": "An event’s broadcast segments, ordered."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/recordings/merge": {
      "post": {
        "summary": "Merge broadcast recordings",
        "tags": [
          "broadcasts"
        ],
        "description": "Merge the remaining (non-deleted) segments into the final recap recording. Lets a host re-merge after editing the segment list.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Recap merge result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Recap merge result."
                }
              }
            }
          }
        }
      }
    },
    "/v1/assets/{id}/clip": {
      "post": {
        "summary": "Clip a recording",
        "tags": [
          "assets"
        ],
        "description": "Clip a time range out of a Mux-backed recording asset, producing a new clip asset (resolved asynchronously via the asset-check task). Participant-facing: workspace API key or a session.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "startSeconds": {
                    "type": "number"
                  },
                  "endSeconds": {
                    "type": "number"
                  }
                },
                "additionalProperties": false,
                "description": "Time range (seconds) to clip out of a recording: 0 <= start < end."
              }
            }
          },
          "description": "Time range (seconds) to clip out of a recording: 0 <= start < end."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Clip job accepted (Mux asset id + preparing status).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Clip job accepted (Mux asset id + preparing status)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/content": {
      "get": {
        "summary": "Get post-event content",
        "tags": [
          "media"
        ],
        "description": "Fetch all post-event derivations and generated media for an event, aggregated for the host dashboard.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "All post-event derivations (recap, themes, Q&A, quotes, resources, action items, key moments) plus generated media for an event.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "All post-event derivations (recap, themes, Q&A, quotes, resources, action items, key moments) plus generated media for an event."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/derivations": {
      "post": {
        "summary": "Run post-event derivations",
        "tags": [
          "media"
        ],
        "description": "Run the Gemini derivation fan-out (recap/Q&A/themes/…) over the event's stored transcript, gated by its event-type profile. Fills gaps by default; pass ?force=true to regenerate existing derivations. Pass ?only=quotes,key_moments to regenerate specific types in isolation, ignoring the profile. Also runs automatically after transcription when the pipeline is enabled.",
        "parameters": [
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "force",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "only",
            "required": false,
            "description": "Comma-separated derivation types to regenerate in isolation (e.g. \"quotes,key_moments\"), regardless of the event-type profile. Omit to run the full profile. Unknown types are rejected with a 400."
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/resolve-speakers": {
      "post": {
        "summary": "Resolve transcript speakers",
        "tags": [
          "media"
        ],
        "description": "Map the anonymous diarization labels on the stored transcript (speaker_0, …) to the real on-stage participants, storing a speaker_map derivation that the content read model applies to quotes + transcript. Prefers matching the durable live-caption ledger by spoken text, falling back to Gemini for the rest. Fills gaps by default; ?force=true re-runs. Also runs automatically before the derivation fan-out.",
        "parameters": [
          {
            "schema": {
              "type": "boolean"
            },
            "in": "query",
            "name": "force",
            "required": false
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/clips": {
      "post": {
        "summary": "Cut auto-clips for an event",
        "tags": [
          "media"
        ],
        "description": "Enqueue per-answered-question clips cut from the recap (needs a qa_answers derivation + a gs:// recap recording). Returns how many clips were queued.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/quote-cards": {
      "post": {
        "summary": "Render quote cards for an event",
        "tags": [
          "media"
        ],
        "description": "Render pull-quote card images from the quotes derivation (idea H). Returns how many cards were queued.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/embeddings": {
      "post": {
        "summary": "Embed an event transcript",
        "tags": [
          "media"
        ],
        "description": "Generate + store transcript-chunk embeddings for semantic search, replacing any existing set for the event (safe to re-run). Returns rows written.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/reprocess": {
      "post": {
        "summary": "Re-run the post-event pipeline",
        "tags": [
          "media"
        ],
        "description": "Re-run derivations only ('insights', synchronous) or re-transcribe and re-run the full chain ('full', forced, enqueued). Regenerates content that already exists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scope"
                ],
                "properties": {
                  "scope": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "insights"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "full"
                        ]
                      }
                    ],
                    "description": "'insights' regenerates the Gemini derivations (recap, themes, quotes, key moments, Q&A) from the existing transcript, synchronously. 'full' re-transcribes the recording and re-runs the whole chain (derivations, clips, quote cards, embeddings), enqueued."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Reprocess accepted (sync summary or queued).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Reprocess accepted (sync summary or queued)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/replay-status": {
      "get": {
        "summary": "Post-event pipeline status",
        "tags": [
          "media"
        ],
        "description": "Per-stage status of the post-event content pipeline (merge, transcription, derivations, clips, quote cards, embeddings, summary) plus a top-line state for the dashboard replay banner.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Per-stage post-event pipeline status for the replay banner.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "overall",
                    "hasRecording",
                    "hasTranscript",
                    "stages"
                  ],
                  "properties": {
                    "overall": {
                      "type": "string",
                      "description": "ready | running | failed | idle"
                    },
                    "hasRecording": {
                      "type": "boolean"
                    },
                    "hasTranscript": {
                      "type": "boolean"
                    },
                    "stages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "key",
                          "label",
                          "group",
                          "status",
                          "error",
                          "dependsOn"
                        ],
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "group": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "error": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "dependsOn": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        }
                      }
                    }
                  },
                  "additionalProperties": false,
                  "description": "Per-stage post-event pipeline status for the replay banner."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/share-email": {
      "post": {
        "summary": "Email the replay link",
        "tags": [
          "media"
        ],
        "description": "Send the event's public replay link (with recap teaser) to up to 10 recipients. In log-adapter/dev mode the link is echoed instead of sent.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "to"
                ],
                "properties": {
                  "to": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "Recipient email addresses (max 10 per send)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Emails sent (count); replay link echoed in dev/log-adapter mode.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Emails sent (count); replay link echoed in dev/log-adapter mode."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/search": {
      "get": {
        "summary": "Semantic search a transcript",
        "tags": [
          "media"
        ],
        "description": "Rank transcript cues against ?q= by cosine similarity (needs embeddings).",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response"
          }
        }
      }
    },
    "/v1/events/{id}/table-summaries": {
      "get": {
        "summary": "Per-breakout-table AI notes",
        "tags": [
          "media"
        ],
        "description": "Every breakout table of the event with its notes, stats and badges, plus the cross-table synthesis. `hasTables` is false for an event that ran no breakout phase, which is how the dashboard panel knows to hide itself.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "hasTables",
                    "stage",
                    "anyShared",
                    "tables",
                    "rollup"
                  ],
                  "properties": {
                    "hasTables": {
                      "type": "boolean"
                    },
                    "stage": {
                      "type": "string",
                      "description": "pending | running | done | failed | skipped"
                    },
                    "anyShared": {
                      "type": "boolean"
                    },
                    "tables": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "roomId",
                          "number",
                          "label",
                          "phaseOrdinal",
                          "status",
                          "summary",
                          "stats",
                          "people",
                          "tableBadges",
                          "attributionWarning",
                          "source",
                          "generatedAt",
                          "sharedAt",
                          "reachable"
                        ],
                        "properties": {
                          "roomId": {
                            "type": "string"
                          },
                          "number": {
                            "type": "integer"
                          },
                          "label": {
                            "type": "string"
                          },
                          "phaseOrdinal": {
                            "type": "integer"
                          },
                          "status": {
                            "type": "string",
                            "description": "ready | thin | pending"
                          },
                          "summary": {
                            "anyOf": [
                              {
                                "type": "object",
                                "required": [
                                  "tldr",
                                  "themes",
                                  "ideas",
                                  "questions",
                                  "perQuestion"
                                ],
                                "properties": {
                                  "tldr": {
                                    "type": "string"
                                  },
                                  "themes": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "required": [
                                        "title",
                                        "summary"
                                      ],
                                      "properties": {
                                        "title": {
                                          "type": "string"
                                        },
                                        "summary": {
                                          "type": "string"
                                        }
                                      },
                                      "additionalProperties": true
                                    }
                                  },
                                  "ideas": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "questions": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "perQuestion": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "required": [
                                        "ordinal",
                                        "question",
                                        "discussed",
                                        "summary"
                                      ],
                                      "properties": {
                                        "ordinal": {
                                          "type": "integer"
                                        },
                                        "question": {
                                          "type": "string"
                                        },
                                        "discussed": {
                                          "type": "boolean"
                                        },
                                        "summary": {
                                          "type": "string"
                                        }
                                      },
                                      "additionalProperties": true
                                    }
                                  }
                                },
                                "additionalProperties": true
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "stats": {
                            "anyOf": [
                              {
                                "type": "object",
                                "required": [
                                  "totalWords",
                                  "totalTurns",
                                  "totalQuestions",
                                  "promptsCovered",
                                  "promptsTotal",
                                  "lifetimeSeconds",
                                  "headcount",
                                  "speakers",
                                  "rosterReconstructed"
                                ],
                                "properties": {
                                  "totalWords": {
                                    "type": "integer"
                                  },
                                  "totalTurns": {
                                    "type": "integer"
                                  },
                                  "totalQuestions": {
                                    "type": "integer"
                                  },
                                  "promptsCovered": {
                                    "type": "integer"
                                  },
                                  "promptsTotal": {
                                    "type": "integer"
                                  },
                                  "lifetimeSeconds": {
                                    "type": "integer"
                                  },
                                  "headcount": {
                                    "type": "integer"
                                  },
                                  "speakers": {
                                    "type": "integer"
                                  },
                                  "rosterReconstructed": {
                                    "type": "boolean"
                                  }
                                },
                                "additionalProperties": true
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "people": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "userId",
                                "name",
                                "words",
                                "turns",
                                "spanSeconds",
                                "questionsAsked",
                                "badges"
                              ],
                              "properties": {
                                "userId": {
                                  "type": "string"
                                },
                                "name": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "words": {
                                  "type": "integer"
                                },
                                "turns": {
                                  "type": "integer"
                                },
                                "spanSeconds": {
                                  "type": "integer"
                                },
                                "questionsAsked": {
                                  "type": "integer"
                                },
                                "badges": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "required": [
                                      "id",
                                      "name",
                                      "description",
                                      "tier",
                                      "icon"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string"
                                      },
                                      "name": {
                                        "type": "string"
                                      },
                                      "description": {
                                        "type": "string"
                                      },
                                      "tier": {
                                        "type": "integer"
                                      },
                                      "icon": {
                                        "type": "string"
                                      },
                                      "glyph": {
                                        "type": "string"
                                      }
                                    },
                                    "additionalProperties": true
                                  }
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "tableBadges": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "id",
                                "name",
                                "description",
                                "tier",
                                "icon"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": "string"
                                },
                                "tier": {
                                  "type": "integer"
                                },
                                "icon": {
                                  "type": "string"
                                },
                                "glyph": {
                                  "type": "string"
                                }
                              },
                              "additionalProperties": true
                            }
                          },
                          "attributionWarning": {
                            "type": "boolean"
                          },
                          "source": {
                            "type": "object",
                            "required": [
                              "cues",
                              "words",
                              "speakers"
                            ],
                            "properties": {
                              "cues": {
                                "type": "integer"
                              },
                              "words": {
                                "type": "integer"
                              },
                              "speakers": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": true
                          },
                          "generatedAt": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "sharedAt": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "reachable": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "rollup": {
                      "anyOf": [
                        {
                          "type": "object",
                          "required": [
                            "rollup",
                            "tablesCovered",
                            "tablesTotal",
                            "generatedAt",
                            "stale"
                          ],
                          "properties": {
                            "rollup": {
                              "type": "object",
                              "required": [
                                "tldr",
                                "consensus",
                                "divergence",
                                "standoutIdeas",
                                "openQuestions",
                                "perQuestion"
                              ],
                              "properties": {
                                "tldr": {
                                  "type": "string"
                                },
                                "consensus": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "divergence": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "required": [
                                      "point",
                                      "positions"
                                    ],
                                    "properties": {
                                      "point": {
                                        "type": "string"
                                      },
                                      "positions": {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        }
                                      }
                                    },
                                    "additionalProperties": true
                                  }
                                },
                                "standoutIdeas": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "required": [
                                      "idea",
                                      "tables"
                                    ],
                                    "properties": {
                                      "idea": {
                                        "type": "string"
                                      },
                                      "tables": {
                                        "type": "array",
                                        "items": {
                                          "type": "integer"
                                        }
                                      }
                                    },
                                    "additionalProperties": true
                                  }
                                },
                                "openQuestions": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "perQuestion": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "required": [
                                      "ordinal",
                                      "question",
                                      "synthesis"
                                    ],
                                    "properties": {
                                      "ordinal": {
                                        "type": "integer"
                                      },
                                      "question": {
                                        "type": "string"
                                      },
                                      "synthesis": {
                                        "type": "string"
                                      }
                                    },
                                    "additionalProperties": true
                                  }
                                }
                              },
                              "additionalProperties": true
                            },
                            "tablesCovered": {
                              "type": "integer"
                            },
                            "tablesTotal": {
                              "type": "integer"
                            },
                            "generatedAt": {
                              "type": "string"
                            },
                            "stale": {
                              "type": "boolean"
                            }
                          },
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Generate per-table notes",
        "tags": [
          "media"
        ],
        "description": "Host-only. Runs inline for a targeted re-run of a few tables; queues a Cloud Task for a whole event, so the request returns before the model calls do.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "roomIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 200
                  },
                  "force": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "queued"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "queued": {
                      "type": "boolean"
                    },
                    "tables": {
                      "type": "integer"
                    },
                    "ran": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "thin": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "failed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "deferred": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/table-summaries/rollup": {
      "post": {
        "summary": "Re-run the cross-table synthesis",
        "tags": [
          "media"
        ],
        "description": "Host-only. Refreshes the \"across all tables\" overview — the thing to call when a table has been re-summarised since it was written.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "force": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "queued"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "queued": {
                      "type": "boolean"
                    },
                    "tables": {
                      "type": "integer"
                    },
                    "ran": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "thin": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "failed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "deferred": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/table-summaries/share": {
      "post": {
        "summary": "Email each table its own notes",
        "tags": [
          "media"
        ],
        "description": "Host-only. Emails every reachable participant a personal, revocable link to the notes for the table(s) they were at — never another table’s. Recipients are derived server-side; the caller cannot name them.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "roomIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 200
                  },
                  "resend": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "sent",
                    "unreachable",
                    "tables"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "sent": {
                      "type": "integer"
                    },
                    "unreachable": {
                      "type": "integer"
                    },
                    "tables": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "roomId",
                          "number",
                          "sent"
                        ],
                        "properties": {
                          "roomId": {
                            "type": "string"
                          },
                          "number": {
                            "type": "integer"
                          },
                          "sent": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "sampleUrl": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/table-summaries/revoke": {
      "post": {
        "summary": "Stop sharing table notes",
        "tags": [
          "media"
        ],
        "description": "Host-only. Clears `shared_at`, so every emailed link stops working immediately. Not retroactive: the emails themselves stay in inboxes, including the excerpt they quote.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "roomIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 200
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "revoked"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "revoked": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/transcribe": {
      "post": {
        "summary": "Transcribe an event recording",
        "tags": [
          "transcripts"
        ],
        "description": "Post-event batch transcription of a GCS audio object via the TranscriptionPort. Stores editable cues and materialises the transcript asset + JSON/VTT derivatives at the documented paths.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourceUri": {
                    "type": "string"
                  },
                  "roomId": {
                    "type": "string"
                  },
                  "force": {
                    "type": "boolean"
                  },
                  "sync": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false,
                "description": "Batch transcription request."
              }
            }
          },
          "description": "Batch transcription request."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Transcription result (cue count + asset coordinates).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Transcription result (cue count + asset coordinates)."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/transcript": {
      "get": {
        "summary": "Get an event transcript",
        "tags": [
          "transcripts"
        ],
        "description": "Fetch an event’s stored transcript cues, earliest first.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Stored transcript cues for an event.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "cues"
                  ],
                  "properties": {
                    "cues": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true,
                  "description": "Stored transcript cues for an event."
                }
              }
            }
          }
        }
      }
    },
    "/v1/transcript-cues/{id}": {
      "patch": {
        "summary": "Edit a transcript cue",
        "tags": [
          "transcripts"
        ],
        "description": "Admin correction of a stored cue’s text and/or speaker. Flips `edited` so re-transcription won’t clobber corrections.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "speaker": {
                    "type": "string"
                  }
                },
                "additionalProperties": false,
                "description": "Admin cue correction."
              }
            }
          },
          "description": "Admin cue correction."
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Transcript cue resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Transcript cue resource."
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/uploads": {
      "post": {
        "summary": "Request an image upload URL",
        "tags": [
          "assets"
        ],
        "description": "Mint a short-lived signed URL for uploading an image (stage design background/logo) straight to the assets bucket. PUT the file bytes to uploadUrl with requiredHeaders, then call confirm.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "contentType"
                ],
                "properties": {
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "contentType": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "image/png"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "image/jpeg"
                        ]
                      },
                      {
                        "type": "string",
                        "enum": [
                          "image/webp"
                        ]
                      }
                    ],
                    "description": "MIME type of the image being uploaded."
                  },
                  "purpose": {
                    "type": "string",
                    "maxLength": 60
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "assetId",
                    "uploadUrl",
                    "url",
                    "requiredHeaders"
                  ],
                  "properties": {
                    "assetId": {
                      "type": "string"
                    },
                    "uploadUrl": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "requiredHeaders": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{id}/uploads/{assetId}/confirm": {
      "post": {
        "summary": "Confirm an image upload",
        "tags": [
          "assets"
        ],
        "description": "Verify the uploaded object and record it as a photo asset on the event. Idempotent for the same asset id.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "purpose": {
                    "type": "string",
                    "maxLength": 60
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
            },
            "in": "path",
            "name": "assetId",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "assetId",
                    "url"
                  ],
                  "properties": {
                    "assetId": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "summary": "Register a webhook endpoint",
        "tags": [
          "webhooks"
        ],
        "description": "Register an endpoint to receive HMAC-signed event deliveries. The signing secret is returned once, at creation time.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Endpoint to deliver signed events to."
                  },
                  "eventTypes": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "event.published"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "event.started"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "event.ended"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "participant.joined"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "participant.left"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "broadcast.live"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "broadcast.paused"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "recording.ready"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "transcript.ready"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "question.created"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "clip.ready"
                          ]
                        }
                      ],
                      "description": "A webhook-deliverable domain event type."
                    },
                    "description": "Event types this endpoint subscribes to (defaults to none)."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook endpoint resource.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": true,
                  "description": "Webhook endpoint resource."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List webhook endpoints",
        "tags": [
          "webhooks"
        ],
        "description": "List the workspace’s registered webhook endpoints (secrets omitted).",
        "responses": {
          "200": {
            "description": "Default Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "webhooks"
                  ],
                  "properties": {
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {},
                        "additionalProperties": true
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "summary": "Delete a webhook endpoint",
        "tags": [
          "webhooks"
        ],
        "description": "Remove a registered webhook endpoint.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Default Response"
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.gathercloud.dev"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ]
}
