{
  "openapi": "3.1.0",
  "info": {
    "title": "Sessionboard Public API",
    "version": "1.0",
    "description": "REST API for managing sessions, speakers, contacts, sponsors, exhibitors, and event data on the Sessionboard platform.",
    "contact": {
      "name": "Sessionboard Support",
      "email": "support@sessionboard.com"
    },
    "termsOfService": "https://www.sessionboard.com/legal/terms-of-service"
  },
  "servers": [
    {
      "url": "https://public-api.sessionboard.com",
      "description": "US Region"
    },
    {
      "url": "https://public-api-eu.sessionboard.com",
      "description": "EU Region"
    }
  ],
  "security": [
    {
      "ApiKey": []
    },
    {
      "BearerToken": []
    }
  ],
  "tags": [
    {
      "name": "Events",
      "description": "Manage events on the platform."
    },
    {
      "name": "Sessions",
      "description": "Search and retrieve sessions within an event."
    },
    {
      "name": "Session Writes",
      "description": "Create, update, delete, and restore sessions. Requires the `write:sessions` scope."
    },
    {
      "name": "Contact Writes",
      "description": "Create, update, delete, and restore contacts. Requires the `write:contacts` scope."
    },
    {
      "name": "Exhibitor Writes",
      "description": "Create, update, delete, and restore exhibitors. Requires the `write:exhibitors` scope."
    },
    {
      "name": "Sponsor Writes",
      "description": "Create, update, delete, and restore sponsors. Requires the `write:sponsors` scope."
    },
    {
      "name": "Field Writes",
      "description": "Create, update, and delete custom fields. Requires the `write:fields` scope."
    },
    {
      "name": "Speakers",
      "description": "Search and retrieve speakers within an event."
    },
    {
      "name": "Participants",
      "description": "Search and retrieve every contact holding a session role on an event —\nspeakers, chairpersons, moderators and custom roles — with the roles\neach one holds, and list the event's participant roles.\n"
    },
    {
      "name": "Contacts",
      "description": "Search and retrieve contacts at the organization or event level."
    },
    {
      "name": "Sponsors",
      "description": "Search and retrieve sponsors within an event."
    },
    {
      "name": "Exhibitors",
      "description": "Search and retrieve exhibitors within an event."
    },
    {
      "name": "Event Settings",
      "description": "Retrieve event configuration such as fields, tags, tracks, rooms, formats, levels, languages, and session statuses."
    },
    {
      "name": "GDPR",
      "description": "Manage GDPR data access and erasure requests."
    },
    {
      "name": "Insights",
      "description": "Query event data using SbQL, generate queries with AI, and manage dashboards."
    },
    {
      "name": "Ask",
      "description": "Ask a natural-language question about one event and get a cited answer. Requires the `read:ask` scope, granted explicitly."
    },
    {
      "name": "Sharing",
      "description": "A webinar's sharing pieces, for your own tools and AI assistants — email signatures for your team, share cards, speakers' personal links and a draft kit of posts for your team. Reads need `read:events`, writes `write:marketing`. Webinars only. Sending email signatures from an AI assistant waits for a person's OK (`202 needs_approval`)."
    },
    {
      "name": "Event Emails",
      "description": "An in-person event's or webinar's lifecycle emails (confirmation, reminders, replay) for your own tools and AI assistants. Reads need `read:events`. Designs an assistant proposes wait for a person to accept them in Sessionboard."
    },
    {
      "name": "Metadata Writes",
      "description": "Create, update, and delete session metadata (rooms, tracks, tags, formats, levels, languages, statuses). Requires the `write:metadata` scope."
    },
    {
      "name": "Agenda Planning",
      "description": "Manage agenda drafts, draft sessions, scheduling rules, and evaluation personas. Requires the `write:events` scope."
    },
    {
      "name": "Dashboards & Widgets",
      "description": "Create, read, update, and delete dashboards and widgets at the event or organization level. Requires `write:events` scope for writes."
    },
    {
      "name": "Reports & Queries",
      "description": "Create, read, update, delete, and run saved SbQL queries/reports at the event or organization level. Requires `write:events` scope for writes."
    },
    {
      "name": "Transcriptions",
      "description": "Transcript text on sessions — fragments, summaries, insights, and translations. Requires `read:transcriptions` / `write:transcriptions` scopes."
    },
    {
      "name": "Session Recordings",
      "description": "Session audio files for recording archives (live capture or imported audio). Requires `read:transcriptions` / `write:transcriptions` scopes."
    },
    {
      "name": "Media",
      "description": "Upload video or audio files for automatic transcription. Requires `read:media` / `write:media` scopes."
    },
    {
      "name": "Session Files",
      "description": "Documents attached to sessions (PDFs, PowerPoint, Word, images, and similar).\nSimple upload: `POST .../files/upload` (multipart, max 50 MB).\nDirect-to-storage: create → PUT → complete (max 500 MB).\nRequires `read:sessions` / `write:sessions` scopes.\nSee the [Uploading session files](/guides/uploading-session-files) guide.\n"
    },
    {
      "name": "OAuth",
      "description": "OAuth 2.1 endpoints for AI client authorization (Claude, ChatGPT). Mounted at `/oauth/` (not `/v1/`)."
    },
    {
      "name": "Products",
      "description": "Which Sessionboard products your organization has: Platform, Sessions, CRM,\nAwards, Learning and Marketing, each with whether it is owned and how\n(a self-serve plan, or your Platform contract). Any `read:*` scope is enough.\n"
    },
    {
      "name": "Tasks",
      "description": "Your team's to-dos in Sessionboard Platform: a title, an assignee, a due\ndate with an optional time, a reminder, and the records each task is\nabout (contacts, sessions, sponsors, exhibitors, groups). Reads need\n`read:tasks`, writes `write:tasks`. An organization on a self-serve\nSessionboard product gets `403 TASKS_PLATFORM_ONLY`. See the\n[Tasks guide](/guides/tasks).\n"
    },
    {
      "name": "Log Export",
      "description": "Pull your organization's API request, security and audit logs into a SIEM\nsuch as Splunk, Microsoft Sentinel or Elastic. Requires a dedicated API token\nwith the `read:audit_logs` scope, which can call nothing else.\nSee the [Exporting logs to a SIEM](/guides/exporting-logs-to-a-siem) guide.\n"
    },
    {
      "name": "Awards",
      "description": "Read and manage Awards programs and their categories, rounds, promo codes, submissions and reviews. Organization-level: paths start at `/v1/organization/{orgId}/awards`. Requires `read:awards` / `write:awards` scopes."
    },
    {
      "name": "Learning",
      "description": "Turn Media-section videos (webinars, recordings, uploads, clips) into a course: draft it from\nvideos, review and edit the draft, then publish it and assign it. Organization-level: paths\nstart at `/v1/organization/{orgId}/learning`, and the same operations are served under\n`/v1/learning` with the organization taken from the token. Requires the preview scopes\n`read:learning` / `write:learning`, which a token or OAuth client gets only when they are\nnamed explicitly (not by default, and not listed in `scopes_supported`). The organization\nmust have Learning turned on, and the token's user needs the Lessons permissions.\n"
    }
  ],
  "paths": {
    "/v1/events": {
      "get": {
        "operationId": "list-events",
        "summary": "List events",
        "description": "Returns events accessible to the authenticated API key.\n\nResults are paginated: `page` (1–999, default 1) and `pageSize`\n(1–100, default 25) are honored, and the response wraps events in\nthe standard `{ results, pagination }` envelope. Events are ordered\noldest-first (`created_at` ascending, ties broken by `id`), so pages\nare stable across requests.\n\nBy default each event is `id`, `name`, `timezone`, `starts_at`,\n`ends_at`, and `features`. Pass `expand` to attach extra collections.\n\n`expand=custom_fields` includes org-defined event custom field values\n(`CustomFieldValue[]`). An event with no values returns `[]`.\nDatetime custom field values are ISO 8601 in the event's local time\nwith its UTC offset (for example `2026-08-15T09:00:00-03:00`); when\nthe event has no valid timezone the raw UTC instant is returned\n(`2026-08-15T12:00:00.000Z`). Date-only (`date`) fields serialize\nas `M-DD-YYYY`: month without a leading zero, day with one, four-digit\nyear (for example `9-22-2026` for 22 September 2026, `3-04-2026` for\n4 March 2026). This is not ISO 8601; parse it with that exact pattern.\n\n`expand=integration_mappings` includes conference connector mappings\n(`EventIntegrationMapping[]`) from `Integration_Event_Mapping_Union`\n(Cvent, Grip, Swoogo, Swapcard, ASP, Stova, Bizzabo, Gleanin,\nExpoPlatform, ON24). `source` is the union key (underscores, e.g.\n`expo_platform`). LiveBuzz / apps-engine campaign IDs are **not**\nincluded in this expand.\n\nRepeat the query param or comma-separate values:\n`?expand=custom_fields&expand=integration_mappings`\n",
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/ListEventsExpand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "results": [
                    {
                      "id": 3960,
                      "name": "Acme Conference",
                      "timezone": "America/Chicago",
                      "starts_at": "2026-10-05T13:00:00.000Z",
                      "ends_at": "2026-10-07T22:00:00.000Z",
                      "features": {
                        "primary_speakers": true,
                        "speaker_acceptance": false,
                        "translated_fields": false
                      }
                    }
                  ],
                  "pagination": {
                    "currentPage": 1,
                    "pageSize": 25,
                    "totalPages": 4,
                    "totalResults": 97
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions": {
      "post": {
        "operationId": "search-sessions",
        "summary": "Search sessions",
        "description": "Search and filter sessions within an event. Supports pagination,\nsorting, filtering by status, date ranges, and session categorization\n(`trackIds`, `tagIds`, `levelIds`, `formatIds`, `languageIds`), and\nexpanding related data.\n\nEach categorization filter needs at least one ID. An empty array is\nrejected with a 400 naming the field — to apply no filter at all, omit\nthe property rather than sending `[]`.\n\n`sort` uses nested keys — each sortable field is an object with a\n`sort` direction, for example `{\"sort\": {\"startsAt\": {\"sort\": \"asc\"}}}`.\nThere is no flat `{\"order\": \"...\", \"sort\": \"...\"}` form. Sessions with\na null `starts_at` always sort last when sorting by `startsAt`,\nregardless of direction.\n\nEvery session includes `is_abstract` and `composition_status`. Pass\n`filters.isAbstract` to return only abstract submissions or only\nprogram sessions. By default, sessions linked as composition sources\nare excluded; pass `expand=linked_sources` to include them. Pass\n`expand=composition` for full target/source details.\n\nEach session in the response includes a `subsessions` array. By\ndefault each subsession is returned in a minimal shape (`Subsession`).\nPass `expand=subsession_details` in the request body to receive full\nparent-shape parity (`SubsessionDetailed`) on every subsession —\nincluding `status`, `custom_status`, `custom_fields`, `chairpersons`,\n`moderators`, `sponsors`, `exhibitors`, `tags`, `language`, `track`,\n`level`, `room`, etc.\n\nEach subsession inherits the parent session's `is_abstract`,\n`composition_status`, and optional `composition` graph (when\n`expand=composition` is set).\n\nNested `language`, `track`, `level`, `format`, and `room` objects on\neach session include the field sets documented on the `Session` schema.\nUnassigned metadata is returned as `{}`.\n\nPaginated search responses return matching sessions under `results`\n(not `data`), alongside a `pagination` object.\n",
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionSearchBody"
              },
              "examples": {
                "sortByStartTime": {
                  "summary": "Sort by session start time (nested sort syntax)",
                  "description": "Sort keys are nested objects — `{\"startsAt\": {\"sort\": \"asc\"}}`.\nSessions with a null `starts_at` always sort last, regardless\nof direction.\n",
                  "value": {
                    "filters": {
                      "status": "accepted"
                    },
                    "sort": {
                      "startsAt": {
                        "sort": "asc"
                      }
                    }
                  }
                },
                "filterByCategorization": {
                  "summary": "Filter by tracks and tags",
                  "description": "IDs within one filter match with OR; separate filters combine\nwith AND.\n",
                  "value": {
                    "filters": {
                      "trackIds": [
                        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      ],
                      "tagIds": [
                        "9b2f0c1d-8e47-4a6b-9c3d-1a2b3c4d5e6f"
                      ]
                    },
                    "sort": {
                      "startsAt": {
                        "sort": "asc"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Session"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "get": {
        "operationId": "list-sessions",
        "summary": "List sessions (CRUD proxy)",
        "description": "Paginated list of top-level sessions via the CRUD proxy. Returns nested\n`language`, `track`, `level`, `format`, and `room` metadata using the same\nfield sets documented on the `Session` schema (`null` when unassigned).\nAlso includes `is_abstract` and `composition_status`.\n\nQuery params: `is_abstract` (`true`/`false`), `expand=linked_sources`,\n`expand=composition`, plus standard pagination and filters.\n\nSession categorization filters use snake_case query params on this\nendpoint: `track_id`/`track_ids`, `tag_id`/`tag_ids`,\n`level_id`/`level_ids`, `format_id`/`format_ids`,\n`language_id`/`language_ids`. Plural params take comma-separated UUIDs\n(OR within a filter; separate filters combine with AND).\n\nEvery value passed to these filters must be a UUID. A non-UUID value\nreturns `400` with error code `VALIDATION_ERROR` and a message naming\nthe offending parameter, for example\n`track_id must be a UUID (received \"nope\")`.\n",
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "is_abstract",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter to abstract submissions or program sessions."
          },
          {
            "$ref": "#/components/parameters/Expand"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "track_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter by a single track UUID."
          },
          {
            "name": "track_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated track UUIDs (OR). Repeat `track_id` for the same effect."
          },
          {
            "name": "level_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "level_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated level UUIDs (OR)."
          },
          {
            "name": "format_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated format UUIDs (OR)."
          },
          {
            "name": "language_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "language_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated language UUIDs (OR)."
          },
          {
            "name": "tag_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "tag_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated tag UUIDs (OR)."
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Session"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        },
                        "total_results": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A categorization filter param (`track_id`/`track_ids`,\n`level_id`/`level_ids`, `format_id`/`format_ids`,\n`language_id`/`language_ids`, `tag_id`/`tag_ids`) carried a\nnon-UUID value. The message names the offending parameter.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "examples": [
                        "VALIDATION_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "examples": [
                        "track_id must be a UUID (received \"nope\")"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/status": {
      "post": {
        "operationId": "search-sessions-by-status",
        "summary": "Search sessions by status",
        "description": "Returns a lightweight list of session statuses, including deleted\nsessions. Supports filtering by `deletedAt` in addition to standard\nfilters.\n\nAlso accepts the five session categorization filters (`trackIds`,\n`tagIds`, `levelIds`, `formatIds`, `languageIds`). IDs within one\nfilter match with OR; separate filters combine with AND. The filters\nare evaluated against the **top-level (root) session**: a subsession\nrow matches when its parent carries the filtered attribute, so a\nmatching parent and the flat rows of its `subsessions` array stay\nconsistent. Unlike other session searches, a **deleted** root session\nstill satisfies a categorization filter — surfacing deleted sessions\nis this endpoint's purpose, and filtering must not hide them.\n\nEach categorization filter needs at least one ID. An empty array is\nrejected with a 400 naming the field — to apply no filter at all, omit\nthe property rather than sending `[]`.\n\nParent rows additionally include a `subsessions` array with the same\nminimal status-focused shape for each child subsession\n(`SubsessionStatus`). Subsession rows that appear in the flat\nresults continue to surface with their own row (for back-compat) and\ncarry an empty `subsessions` array.\n",
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "createdAt": {
                        "$ref": "#/components/schemas/DateRangeFilter"
                      },
                      "updatedAt": {
                        "$ref": "#/components/schemas/DateRangeFilter"
                      },
                      "deletedAt": {
                        "$ref": "#/components/schemas/DateRangeFilter"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "accepted",
                          "accept_queue",
                          "pending",
                          "decline_queue",
                          "declined"
                        ]
                      },
                      "trackIds": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "Match sessions in any of these tracks (OR). Combined with other filters using AND. Evaluated against the top-level session; a deleted root still matches. Send at least one ID — an empty array is rejected with a 400; to apply no track filter, omit the property."
                      },
                      "levelIds": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "formatIds": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "languageIds": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "tagIds": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "Match sessions tagged with any of these tag IDs (OR). Send at least one ID — an empty array is rejected with a 400."
                      }
                    }
                  },
                  "sort": {
                    "type": "object",
                    "description": "Nested sort keys — the same shape as other search endpoints\n(`{\"createdAt\": {\"sort\": \"desc\"}}`), not a flat\n`{\"order\": \"createdAt\", \"sort\": \"desc\"}` pair.\n\nWhen sorting by `deletedAt`, deleted sessions sort before\nnever-deleted ones (whose `deleted_at` is null) in both\ndirections.\n",
                    "properties": {
                      "createdAt": {
                        "$ref": "#/components/schemas/NestedSortField"
                      },
                      "updatedAt": {
                        "$ref": "#/components/schemas/NestedSortField"
                      },
                      "deletedAt": {
                        "$ref": "#/components/schemas/NestedSortField"
                      }
                    }
                  },
                  "expand": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "examples": {
                "recentlyDeletedFirst": {
                  "summary": "Sort by deletion time (nested sort syntax)",
                  "value": {
                    "filters": {
                      "status": "declined"
                    },
                    "sort": {
                      "deletedAt": {
                        "sort": "desc"
                      }
                    }
                  }
                },
                "declinedInTrack": {
                  "summary": "Declined sessions in a track (categorization filter)",
                  "description": "IDs within one filter match with OR; separate filters combine\nwith AND. Filters match the top-level session, so subsession\nrows match via their parent — and a deleted root session\nstill matches.\n",
                  "value": {
                    "filters": {
                      "status": "declined",
                      "trackIds": [
                        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      ]
                    },
                    "sort": {
                      "deletedAt": {
                        "sort": "desc"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionStatus"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}": {
      "get": {
        "operationId": "get-session",
        "summary": "Get a session",
        "description": "Retrieve a single session by ID, optionally expanding related data.\n\nEvery session includes `is_abstract` and `composition_status`. Pass\n`expand=composition` for full linked target and source details.\n\nAccepts both parent session UUIDs and subsession UUIDs. When called\nwith a subsession UUID, the response is a full session-shaped DTO\nfor that subsession (with `parent_session_friendly_id` /\n`parent_session_friendly_id_raw` keys and no nested `subsessions`\narray). Subsessions inherit the parent session's `is_abstract`,\n`composition_status`, and optional `composition` graph (when\n`expand=composition` is set) — subsessions cannot participate in\ncomposition directly.\n\nThis means callers can iterate `parent.subsessions[]` and then call\nthis endpoint with each subsession id to retrieve the same shape\nas a parent session.\n\nPass `expand=subsession_details` to receive the full\n`SubsessionDetailed` shape on every entry of `parent.subsessions[]`;\nthe flag has no effect at the top level — the top-level response\nalways returns the full shape regardless of whether the requested\nid is a parent or a subsession.\n",
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The session ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Session not found"
          }
        }
      },
      "put": {
        "operationId": "update-session",
        "summary": "Update a session",
        "description": "Update an existing session. Requires the `write:sessions` scope. Send `updated_at` from the last-fetched session for optimistic concurrency control.",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The session ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updated_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Required for optimistic concurrency control. Send the `updated_at` value from the last-fetched session."
                  },
                  "title": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "starts_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "ends_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "capacity": {
                    "type": "integer"
                  },
                  "room_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "track_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "status": {
                    "type": "string"
                  },
                  "tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "is_public": {
                    "type": "boolean"
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "Session not found"
          },
          "409": {
            "description": "Stale update — session modified since last fetch"
          }
        }
      },
      "delete": {
        "operationId": "delete-session",
        "summary": "Soft-delete a session",
        "description": "Soft-delete a session. Can be restored with the restore endpoint. Requires the `write:sessions` scope.",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The session ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Session deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "Session not found"
          },
          "409": {
            "description": "Cannot delete — has active subsessions"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/fields": {
      "put": {
        "operationId": "update-session-fields",
        "summary": "Update session custom fields",
        "description": "Update custom field values on a session without touching other session properties. Requires the `write:sessions` scope.",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The session ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "values"
                ],
                "properties": {
                  "values": {
                    "type": "array",
                    "minItems": 1,
                    "description": "Field values to write. Unlike the session `PUT`, this\nendpoint takes an array of entries rather than a\n`custom_fields` object, and each entry may carry its own\n`language` — so this is the endpoint to use for writing a\nlanguage variant of a single field. An empty or missing\narray returns `400` `VALIDATION_ERROR`.\n\nValue formatting per type matches `custom_fields`\nelsewhere: an empty string (`\"\"`) clears a `number`,\n`currency`, or `percent` field; `checkbox` takes boolean\n`true` / `false`; `datetime` takes an ISO 8601 string.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`.\n",
                    "items": {
                      "type": "object",
                      "required": [
                        "internal_name"
                      ],
                      "properties": {
                        "internal_name": {
                          "type": "string",
                          "description": "The field's internal name, as listed by `GET /v1/event/{eventId}/fields`."
                        },
                        "value": {
                          "description": "The value to store. `null` clears it.",
                          "nullable": true
                        },
                        "language": {
                          "type": "string",
                          "description": "Optional locale for a language variant (for example `es_ES`). Must be one of the event's enabled locales. Omit it to write the event default.\n"
                        }
                      }
                    }
                  }
                }
              },
              "examples": {
                "single": {
                  "summary": "Write one field value",
                  "value": {
                    "values": [
                      {
                        "internal_name": "track_code",
                        "value": "T-42"
                      }
                    ]
                  }
                },
                "variant": {
                  "summary": "Write a Spanish variant of one field",
                  "value": {
                    "values": [
                      {
                        "internal_name": "session_subtitle",
                        "value": "Sesión de apertura",
                        "language": "es_ES"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Custom fields updated. The response echoes the fields that were\nwritten rather than the whole session — refetch with\n`GET /v1/event/{eventId}/sessions/{sessionId}` if you need the\nfull record.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "session_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "updated_fields": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "language": {
                                "type": "string",
                                "description": "Present only when the request specified a language."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — `values` missing or empty, an unknown field (`UNKNOWN_FIELD`), a type mismatch (`TYPE_MISMATCH`), or an integration-owned field (`FIELD_READ_ONLY`).\n"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "Session not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/speakers": {
      "post": {
        "operationId": "search-speakers",
        "summary": "Search speakers",
        "description": "Search and filter speakers within an event. Supports the session\ncategorization filters (`trackIds`, `tagIds`, `levelIds`, `formatIds`,\n`languageIds`) to match speakers by the sessions they are assigned to.\n`sort` uses the same nested shape as other search endpoints\n(`{\"createdAt\": {\"sort\": \"desc\"}}`).\n\nCategorization filters are evaluated against the **top-level\nsession**, matching session search semantics: a speaker assigned to a\nsubsession matches when the subsession's parent (root) session\nsatisfies the filter — a subsession's own categorization values are\nnot consulted.\n\nEach categorization filter needs at least one ID. An empty array is\nrejected with a 400 naming the field — to apply no filter at all, omit\nthe property rather than sending `[]`.\n\nOnly a session's **speakers** are matched. A contact attached to a\nmatching session as a chairperson, moderator or other participant is\nnot returned by this endpoint — with or without a filter. The session\nobject from `POST /v1/event/{eventId}/sessions` exposes four separate\nparticipant arrays (`speakers`, `chairpersons`, `moderators`,\n`participants`) and they are not interchangeable here: reconciling\n\"speakers on track X\" against a session search must compare against\nthe `speakers` array alone, or the counts will not agree. The same\ncontact can appear under different roles on different sessions, so a\ncontact present in the unfiltered speaker list may still be absent\nfrom a filtered one when its attachment to the matching session is a\nnon-speaker role.\n\nTo retrieve every participant regardless of role — chairpersons,\nmoderators and custom roles included, each with the roles it holds —\nuse `POST /v1/event/{eventId}/participants`. It accepts the same\nfilters and returns the same contact fields plus a `roles` array.\n",
        "tags": [
          "Speakers"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpeakerSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/speakers/{contactId}": {
      "get": {
        "operationId": "get-speaker",
        "summary": "Get a speaker",
        "description": "Retrieve a single speaker by contact ID.",
        "tags": [
          "Speakers"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Speaker not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/participants": {
      "post": {
        "operationId": "search-participants",
        "summary": "Search participants",
        "description": "Search every contact assigned to at least one session on the event in\n**any** participant role — the standard roles (speaker, chairperson,\nmoderator) and any custom role configured for the event (Panelist,\nCoach, Author, …). This is the superset of\n`POST /v1/event/{eventId}/speakers`, which matches speakers only.\n\nEach contact is returned **once**, however many sessions or roles it\nholds, with a `roles` array listing every role it has on the event and\nthe session ids where it holds each one. Every other field is the same\n`Contact` shape `POST /speakers` returns, in the same order, with\n`roles` appended last. `roles` always describes the contact's full\nset of roles on the event — it is not narrowed by the request filters,\nso a search filtered to the Moderator role still shows that a result is\nalso a Speaker elsewhere on the program.\n\n**Filters.** Every Search Speakers filter is accepted and behaves the\nsame: `createdAt`, `updatedAt`, `status` (the *session's* status),\n`trackIds`, `levelIds`, `formatIds`, `languageIds`, `tagIds`, plus\n`sort` and `expand`. Categorization filters are evaluated against the\n**top-level session**, so a participant on a subsession matches when\nthe subsession's parent satisfies the filter. Each array filter needs\nat least one id — `[]` is a `400` naming the field; omit the property\nto apply no filter.\n\nThree filters are specific to this endpoint:\n\n- `roleIds` — return only participants holding **at least one** of the\n  given roles, standard or custom. Get the ids from\n  `GET /v1/event/{eventId}/participant-roles`.\n- `roleSlugs` — the same, by role slug (`speaker`, `chairperson`,\n  `moderator`, or a custom role's slug). Use this to get every speaker\n  without resolving ids per event, or on older events where roles have\n  `roleId: null`.\n- `email` — exact, case-insensitive match on the contact's email. An\n  unknown address returns an empty `results` array with\n  `totalResults: 0`, not an error. For a single-record lookup that\n  answers `404` instead, use `GET /v1/event/{eventId}/participants?email=`.\n\n**Roles on older events.** Roles are stored per event. An event that\nhas never been opened in the Sessions editor may not have its standard\nroles created yet; its participants are still returned, but a\nstandard role on such an event has `roleId: null` (with `roleName`,\n`slug` and `coreRole` filled in) and cannot be matched by `roleIds`\nuntil the roles exist — filter by `roleSlugs` instead.\n`GET .../participant-roles` returns an empty list for such an event.\n",
        "tags": [
          "Participants"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ParticipantSearchBody"
              },
              "examples": {
                "byRole": {
                  "summary": "Everyone holding the Moderator or a custom role",
                  "value": {
                    "filters": {
                      "roleIds": [
                        "4efeb845-050f-4002-9496-cb586cdf10f2",
                        "52d60237-19db-4bda-a116-8b9fcb6750e9"
                      ],
                      "status": "accepted"
                    }
                  }
                },
                "bySlug": {
                  "summary": "Every speaker, by role slug",
                  "value": {
                    "filters": {
                      "roleSlugs": [
                        "speaker"
                      ]
                    }
                  }
                },
                "byEmail": {
                  "summary": "Match one contact by email",
                  "value": {
                    "filters": {
                      "email": "jane.smith@university.edu"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Participant"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — an empty filter array, a non-UUID in `roleIds`, or an out-of-range `page` / `pageSize`."
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "get": {
        "operationId": "get-participant-by-email",
        "summary": "Get a participant by email",
        "description": "Look up one participant by email address. The match is exact and\ncase-insensitive. Returns the participant, or `404` when no contact\nwith that address holds a session role on the event.\n\nSearch on this API is a `POST`, so a `GET` on the collection path is\nfree for the lookup — no `/by-email` sub-path is needed. `email` is\nrequired; a bare `GET /participants` is a `400`, not an unpaginated\nlist.\n\nContacts are not unique by email. If more than one contact on the\nevent shares the address, the earliest-created one is returned; use\n`POST /v1/event/{eventId}/participants` with the `email` filter to see\nthem all.\n",
        "tags": [
          "Participants"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "email",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "email"
            },
            "description": "The contact's email address. Matched exactly, ignoring case."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Participant"
                }
              }
            }
          },
          "400": {
            "description": "`email` is missing or empty."
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found, or no participant with that email on the event."
          }
        }
      }
    },
    "/v1/event/{eventId}/participants/{contactId}": {
      "get": {
        "operationId": "get-participant",
        "summary": "Get a participant",
        "description": "Retrieve a single participant by contact ID, with the `roles` it holds\non the event. `404` when the contact is not on the event, or is on the\nevent but holds no session role — a contact returned by\n`GET /v1/event/{eventId}/contacts/{contactId}` is not necessarily a\nparticipant.\n",
        "tags": [
          "Participants"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The contact ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Participant"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Participant not found on this event"
          }
        }
      }
    },
    "/v1/event/{eventId}/participant-roles": {
      "get": {
        "operationId": "list-participant-roles",
        "summary": "List participant roles",
        "description": "The event's participant roles — the three standard roles (Speaker,\nChairperson, Moderator) and every custom role configured for the\nevent — with the ids to use in the `roleIds` filter of\n`POST /v1/event/{eventId}/participants`. Ordered as the Sessions\nsettings page shows them. Deleted roles are not returned.\n\n`is_custom` is `true` for roles the organizer added. `core_role` is\nthe standard category a custom role maps to (`speaker`,\n`chairperson` or `moderator`); it decides which legacy array the\nrole's participants appear in on `POST /v1/event/{eventId}/sessions`,\nand is not a display label — use `name`.\n\nAn event that has never been opened in the Sessions editor may have no\nroles yet and answers with an empty `results` array. Its participants\nare still returned by `POST .../participants`, with `roleId: null` on\ntheir standard roles until the roles are created.\n",
        "tags": [
          "Participants"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EventParticipantRole"
                      }
                    }
                  }
                },
                "examples": {
                  "withCustomRoles": {
                    "value": {
                      "results": [
                        {
                          "id": "84bd12e5-d5ec-4c64-a604-4051e06c8dc2",
                          "name": "Speaker",
                          "name_plural": "Speakers",
                          "slug": "speaker",
                          "core_role": "speaker",
                          "is_custom": false,
                          "sort_order": 0,
                          "created_at": "2026-02-03T18:04:11.120Z",
                          "updated_at": "2026-02-03T18:04:11.120Z"
                        },
                        {
                          "id": "4efeb845-050f-4002-9496-cb586cdf10f2",
                          "name": "Moderator",
                          "name_plural": "Moderators",
                          "slug": "moderator",
                          "core_role": "moderator",
                          "is_custom": false,
                          "sort_order": 2,
                          "created_at": "2026-02-03T18:04:11.120Z",
                          "updated_at": "2026-02-03T18:04:11.120Z"
                        },
                        {
                          "id": "52d60237-19db-4bda-a116-8b9fcb6750e9",
                          "name": "Panelist",
                          "name_plural": "Panelists",
                          "slug": "panelist",
                          "core_role": "speaker",
                          "is_custom": true,
                          "sort_order": 3,
                          "created_at": "2026-02-10T09:41:52.004Z",
                          "updated_at": "2026-02-10T09:41:52.004Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/organization/{orgId}/contacts": {
      "post": {
        "operationId": "search-org-contacts",
        "summary": "Search organization contacts",
        "description": "Search and filter contacts across the organization.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The organization ID (UUID)."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Organization not found"
          }
        }
      }
    },
    "/v1/organization/{orgId}/contacts/{contactId}": {
      "get": {
        "operationId": "get-org-contact",
        "summary": "Get an organization contact",
        "description": "Retrieve a single contact by ID at the organization level.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The organization ID (UUID)."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts": {
      "post": {
        "operationId": "search-event-contacts",
        "summary": "Search event contacts",
        "description": "Search and filter contacts within an event.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts/{contactId}": {
      "get": {
        "operationId": "get-event-contact",
        "summary": "Get an event contact",
        "description": "Retrieve a single contact by ID at the event level.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      },
      "put": {
        "operationId": "update-contact",
        "summary": "Update a contact",
        "description": "Update an existing contact. Requires the `write:contacts` scope. Optionally send `updated_at` for optimistic concurrency control. Sending `null` for a standard field clears it; omitting a key leaves it unchanged.",
        "tags": [
          "Contact Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updated_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Optional optimistic concurrency control. Send the `updated_at` value from the last-fetched contact (or from your last write's response); a contact changed since then returns `409 STALE_UPDATE`."
                  },
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "company": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "about": {
                    "type": "string",
                    "description": "Biography. HTML is allowed and stored as rich text."
                  },
                  "salutation": {
                    "type": "string"
                  },
                  "honorific": {
                    "type": "string"
                  },
                  "address_line_1": {
                    "type": "string"
                  },
                  "address_line_2": {
                    "type": "string"
                  },
                  "address_city": {
                    "type": "string"
                  },
                  "address_state": {
                    "type": "string"
                  },
                  "address_postal_code": {
                    "type": "string"
                  },
                  "address_country": {
                    "type": "string",
                    "description": "ISO 3166-1 numeric code (as GET returns), alpha-2 or alpha-3 code, or English country name. Stored and returned as the numeric code. An unknown value returns `400` naming the field and nothing is written."
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:contacts scope"
          },
          "404": {
            "description": "Contact not found"
          },
          "409": {
            "description": "Stale update — contact modified since last fetch"
          }
        }
      },
      "delete": {
        "operationId": "delete-contact",
        "summary": "Soft-delete a contact",
        "description": "Soft-delete a contact. Can be restored with the restore endpoint. Requires the `write:contacts` scope.",
        "tags": [
          "Contact Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Contact deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:contacts scope"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sponsors": {
      "post": {
        "operationId": "search-sponsors",
        "summary": "Search sponsors",
        "description": "Search and filter sponsors within an event. Returns the account records carrying the Sponsor role on this event — an account holding both roles is returned by both searches, and contacts are never returned.\n",
        "tags": [
          "Sponsors"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Sponsor"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sponsors/{sponsorId}": {
      "get": {
        "operationId": "get-sponsor",
        "summary": "Get a sponsor",
        "description": "Retrieve a single sponsor by ID.",
        "tags": [
          "Sponsors"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sponsorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The sponsor ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sponsor"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "No sponsor with this id on this event. A record that exists but does not hold the sponsor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          }
        }
      },
      "put": {
        "operationId": "update-sponsor",
        "summary": "Update a sponsor",
        "description": "Update an existing sponsor. Requires the `write:sponsors` scope. Optionally send `updated_at` for optimistic concurrency control.",
        "tags": [
          "Sponsor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sponsorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The sponsor ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updated_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Optional optimistic concurrency control. Send the `updated_at` value from the last-fetched sponsor."
                  },
                  "name": {
                    "type": "string",
                    "description": "New sponsor name. Must be a non-empty string when present — an explicit empty string returns `400`. Omit the key to leave the name unchanged.\n"
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sponsor updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sponsor"
                },
                "example": {
                  "id": "7f5e2c1a-9b3d-4e6f-8a2b-1c4d5e6f7a8b",
                  "friendly_id": "SPO-12",
                  "name": "Globex Corporation",
                  "custom_fields": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error — `name`, when present, must be a non-empty string"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sponsors scope"
          },
          "404": {
            "description": "No sponsor with this id on this event. A record that exists but does not hold the sponsor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          },
          "409": {
            "description": "Stale update — sponsor modified since last fetch"
          }
        }
      },
      "delete": {
        "operationId": "delete-sponsor",
        "summary": "Soft-delete a sponsor",
        "description": "Soft-delete a sponsor. Can be restored with the restore endpoint. Requires the `write:sponsors` scope.\n\n**This deletes the group, not just its sponsor role.** The path names the role you are calling under, but the record that gets soft-deleted is the underlying group, so:\n\n* A group holding **both** roles loses its exhibitor role too. After\n  this call it is absent from both searches and both `GET`s answer\n  `404`.\n\n* A group linked to **other events** is removed from those events as\n  well — it is no longer returned by any event's sponsor or exhibitor\n  search across the organization.\n\n\nThis matches the admin UI, where the unit of deletion is the group, not one of its roles. There is no role-scoped or event-scoped delete on this API. If you only want to stop listing a partner for one season, do not call this endpoint.\n\n`POST /v1/event/{eventId}/sponsors/{sponsorId}/restore` reverses it with the same reach — both roles and every event come back — so nothing is lost permanently.\n",
        "tags": [
          "Sponsor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sponsorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The sponsor ID."
          }
        ],
        "responses": {
          "204": {
            "description": "Sponsor deleted. The response has no body — do not expect a `200` or a JSON payload.\n"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sponsors scope"
          },
          "404": {
            "description": "No sponsor with this id on this event. A record that exists but does not hold the sponsor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds. An **already-deleted** sponsor is also a `404`, so a repeated delete is safe but is not reported as a success.\n"
          }
        }
      }
    },
    "/v1/event/{eventId}/exhibitors": {
      "post": {
        "operationId": "search-exhibitors",
        "summary": "Search exhibitors",
        "description": "Search and filter exhibitors within an event. Returns the account records carrying the Exhibitor role on this event — an account holding both roles is returned by both searches, and contacts are never returned.\n",
        "tags": [
          "Exhibitors"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Exhibitor"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/exhibitors/{exhibitorId}": {
      "get": {
        "operationId": "get-exhibitor",
        "summary": "Get an exhibitor",
        "description": "Retrieve a single exhibitor by ID.",
        "tags": [
          "Exhibitors"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "exhibitorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The exhibitor ID."
          },
          {
            "$ref": "#/components/parameters/Expand"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exhibitor"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "No exhibitor with this id on this event. A record that exists but does not hold the exhibitor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          }
        }
      },
      "put": {
        "operationId": "update-exhibitor",
        "summary": "Update an exhibitor",
        "description": "Update an existing exhibitor. Requires the `write:exhibitors` scope. Optionally send `updated_at` for optimistic concurrency control.",
        "tags": [
          "Exhibitor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "exhibitorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The exhibitor ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updated_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Optional optimistic concurrency control. Send the `updated_at` value from the last-fetched exhibitor."
                  },
                  "name": {
                    "type": "string",
                    "description": "New exhibitor name. When present it must be a non-empty string — an explicit empty string returns `400`. Omit the key to leave the name unchanged."
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Exhibitor updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exhibitor"
                },
                "example": {
                  "id": "4b1de9c7-88a2-4e0f-b1f3-6a9d0c2e4f22",
                  "friendly_id": "EXH-8",
                  "name": "Initech Booth Services",
                  "custom_fields": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error — `name`, when present, must be a non-empty string"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:exhibitors scope"
          },
          "404": {
            "description": "No exhibitor with this id on this event. A record that exists but does not hold the exhibitor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          },
          "409": {
            "description": "Stale update — exhibitor modified since last fetch"
          }
        }
      },
      "delete": {
        "operationId": "delete-exhibitor",
        "summary": "Soft-delete an exhibitor",
        "description": "Soft-delete an exhibitor. Can be restored with the restore endpoint. Requires the `write:exhibitors` scope.\n\n**This deletes the group, not just its exhibitor role.** The path names the role you are calling under, but the record that gets soft-deleted is the underlying group, so:\n\n* A group holding **both** roles loses its sponsor role too. After\n  this call it is absent from both searches and both `GET`s answer\n  `404`.\n\n* A group linked to **other events** is removed from those events as\n  well — it is no longer returned by any event's sponsor or exhibitor\n  search across the organization.\n\n\nThis matches the admin UI, where the unit of deletion is the group, not one of its roles. There is no role-scoped or event-scoped delete on this API. If you only want to stop listing a partner for one season, do not call this endpoint.\n\n`POST /v1/event/{eventId}/exhibitors/{exhibitorId}/restore` reverses it with the same reach — both roles and every event come back — so nothing is lost permanently.\n",
        "tags": [
          "Exhibitor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "exhibitorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The exhibitor ID."
          }
        ],
        "responses": {
          "204": {
            "description": "Exhibitor deleted. The response has no body — do not expect a `200` or a JSON payload.\n"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:exhibitors scope"
          },
          "404": {
            "description": "No exhibitor with this id on this event. A record that exists but does not hold the exhibitor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds. An **already-deleted** exhibitor is also a `404`, so a repeated delete is safe but is not reported as a success.\n"
          }
        }
      }
    },
    "/v1/event/{eventId}/fields": {
      "get": {
        "operationId": "list-fields",
        "summary": "List fields",
        "description": "Returns all field definitions for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Field"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-fields",
        "summary": "Search fields",
        "description": "Search and filter field definitions for an event, including standard and custom fields.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "module": {
                        "type": "string",
                        "enum": [
                          "session",
                          "account",
                          "contact"
                        ],
                        "description": "Filter by module type."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "standard",
                          "custom"
                        ],
                        "description": "Filter by field source."
                      },
                      "scope": {
                        "type": "string",
                        "enum": [
                          "global",
                          "event"
                        ],
                        "description": "Filter by field scope."
                      },
                      "createdAt": {
                        "$ref": "#/components/schemas/DateRangeFilter"
                      },
                      "updatedAt": {
                        "$ref": "#/components/schemas/DateRangeFilter"
                      }
                    }
                  },
                  "sort": {
                    "$ref": "#/components/schemas/SortOptions"
                  },
                  "expand": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Field"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/tags": {
      "get": {
        "operationId": "list-tags",
        "summary": "List tags",
        "description": "Returns the event's taxonomy tags (the tags organizers create and apply\nto sessions in the app), paginated, newest first.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Tag"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-tags",
        "summary": "Search tags",
        "description": "Returns a paginated list of tags for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Tag"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/languages": {
      "get": {
        "operationId": "list-languages",
        "summary": "List languages",
        "description": "Returns the event's languages, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 languages appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Language"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-languages",
        "summary": "Search languages",
        "description": "Returns a paginated list of languages configured for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Language"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/formats": {
      "get": {
        "operationId": "list-formats",
        "summary": "List formats",
        "description": "Returns the event's session formats, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 session formats appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Format"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-formats",
        "summary": "Search formats",
        "description": "Returns a paginated list of session formats for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Format"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/tracks": {
      "get": {
        "operationId": "list-tracks",
        "summary": "List tracks",
        "description": "Returns the event's tracks, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 tracks appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Track"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-tracks",
        "summary": "Search tracks",
        "description": "Returns a paginated list of tracks for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Track"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/levels": {
      "get": {
        "operationId": "list-levels",
        "summary": "List levels",
        "description": "Returns the event's session levels, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 session levels appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Level"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-levels",
        "summary": "Search levels",
        "description": "Returns a paginated list of session levels for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Level"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/rooms": {
      "get": {
        "operationId": "list-rooms",
        "summary": "List rooms",
        "description": "Returns the event's rooms, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 rooms appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Room"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      },
      "post": {
        "operationId": "search-rooms",
        "summary": "Search rooms",
        "description": "Returns a paginated list of rooms for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Room"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/statuses": {
      "get": {
        "operationId": "list-statuses",
        "summary": "List session statuses",
        "description": "Returns the event's session status definitions, newest first.\n\nPaginated: up to `pageSize` per page (default 25, maximum 100),\nwith a `pagination` object alongside the results. This page\npreviously described an unpaginated array, which is why a caller\nwith more than 25 session status definitions appeared to be missing some.\n",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionCustomStatus"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/session-statuses": {
      "post": {
        "operationId": "search-session-statuses",
        "summary": "Search session statuses",
        "description": "Returns a paginated list of custom session status definitions for an event.",
        "tags": [
          "Event Settings"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSearchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionCustomStatus"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/rooms/create": {
      "post": {
        "operationId": "create-room",
        "summary": "Create a room",
        "description": "Create a new room. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "capacity": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Room created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Room"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/rooms/{id}": {
      "put": {
        "operationId": "update-room",
        "summary": "Update a room",
        "description": "Update a room. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "capacity": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Room updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Room"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-room",
        "summary": "Delete a room",
        "description": "Delete a room. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Room deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/tracks/create": {
      "post": {
        "operationId": "create-track",
        "summary": "Create a track",
        "description": "Create a new track. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Track created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Track"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/tracks/{id}": {
      "put": {
        "operationId": "update-track",
        "summary": "Update a track",
        "description": "Update a track. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Track updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Track"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-track",
        "summary": "Delete a track",
        "description": "Delete a track. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Track deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/tags/create": {
      "post": {
        "operationId": "create-tag",
        "summary": "Create a tag",
        "description": "Create a new event taxonomy tag. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "order": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Tag created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Tag"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required field (name)"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/tags/{id}": {
      "put": {
        "operationId": "update-tag",
        "summary": "Update a tag",
        "description": "Update a tag. Requires the `write:metadata` scope.\n\nSupports optimistic concurrency: pass the `updated_at` you last read\nand the request fails with `409` (`STALE_UPDATE`) if the tag changed\nsince then.\n",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "order": {
                    "type": "integer"
                  },
                  "updated_at": {
                    "type": "string",
                    "description": "Last-read `updated_at` for optimistic concurrency."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tag updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Tag"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          },
          "404": {
            "description": "Tag not found"
          },
          "409": {
            "description": "Stale update — tag modified since last fetch (STALE_UPDATE)"
          }
        }
      },
      "delete": {
        "operationId": "delete-tag",
        "summary": "Delete a tag",
        "description": "Delete a tag. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Tag deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          },
          "404": {
            "description": "Tag not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/formats/create": {
      "post": {
        "operationId": "create-format",
        "summary": "Create a format",
        "description": "Create a new session format. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Format created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Format"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/formats/{id}": {
      "put": {
        "operationId": "update-format",
        "summary": "Update a format",
        "description": "Update a session format. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Format updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Format"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-format",
        "summary": "Delete a format",
        "description": "Delete a session format. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Format deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/levels/create": {
      "post": {
        "operationId": "create-level",
        "summary": "Create a level",
        "description": "Create a new session level. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Level created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Level"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/levels/{id}": {
      "put": {
        "operationId": "update-level",
        "summary": "Update a level",
        "description": "Update a session level. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Level updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Level"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-level",
        "summary": "Delete a level",
        "description": "Delete a session level. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Level deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/languages/create": {
      "post": {
        "operationId": "create-language",
        "summary": "Create a language",
        "description": "Create a new language. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Language created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Language"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/languages/{id}": {
      "put": {
        "operationId": "update-language",
        "summary": "Update a language",
        "description": "Update a language. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Language updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Language"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-language",
        "summary": "Delete a language",
        "description": "Delete a language. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Language deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/statuses/create": {
      "post": {
        "operationId": "create-status",
        "summary": "Create a session status",
        "description": "Create a new custom session status. Requires the `write:metadata`\nscope.\n\nUnlike the other metadata endpoints, `name` alone is **not** enough.\n`color` and `status` are stored NOT NULL with no defaults, so all three\nare required; a payload missing either answers\n`400 VALIDATION_ERROR` naming the field.\n\n`status` is the underlying approval state this custom label maps onto —\nseveral labels may share one. It must be one of the five values below;\nanything else is a `400`, not a `500`.\n",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "color",
                  "status"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "description": "Approval state this custom status maps onto.",
                    "enum": [
                      "pending",
                      "accepted",
                      "declined",
                      "accept_queue",
                      "decline_queue"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Status created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionCustomStatus"
                }
              }
            }
          },
          "400": {
            "description": "Missing name, color or status, or a status outside the enum"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/statuses/{id}": {
      "put": {
        "operationId": "update-status",
        "summary": "Update a session status",
        "description": "Update a custom session status. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "description": "Approval state this custom status maps onto.",
                    "enum": [
                      "pending",
                      "accepted",
                      "declined",
                      "accept_queue",
                      "decline_queue"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionCustomStatus"
                }
              }
            }
          },
          "400": {
            "description": "A status outside the enum"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-status",
        "summary": "Delete a session status",
        "description": "Delete a custom session status. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Status deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/statuses/{id}/restore": {
      "post": {
        "operationId": "restore-status",
        "summary": "Restore a deleted session status",
        "description": "Restore a previously soft-deleted session status. Requires the `write:metadata` scope.",
        "tags": [
          "Metadata Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status restored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionCustomStatus"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:metadata scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts": {
      "get": {
        "operationId": "list-agenda-drafts",
        "summary": "List agenda drafts",
        "description": "Returns all agenda drafts for an event.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AgendaDraft"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/create": {
      "post": {
        "operationId": "create-agenda-draft",
        "summary": "Create an agenda draft",
        "description": "Create a new agenda draft workspace. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Draft name."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgendaDraft"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}": {
      "get": {
        "operationId": "get-agenda-draft",
        "summary": "Get an agenda draft",
        "description": "Retrieve a single agenda draft by ID.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The draft ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgendaDraft"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Draft not found"
          }
        }
      },
      "put": {
        "operationId": "update-agenda-draft",
        "summary": "Update an agenda draft",
        "description": "Update an agenda draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgendaDraft"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-agenda-draft",
        "summary": "Delete an agenda draft",
        "description": "Delete an agenda draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Draft deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/changes": {
      "get": {
        "operationId": "get-agenda-draft-changes",
        "summary": "Preview draft changes",
        "description": "Preview the pending changes in a draft before committing them to the live schedule.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "A summary of additions, modifications, and removals."
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/commit": {
      "post": {
        "operationId": "commit-agenda-draft",
        "summary": "Commit an agenda draft",
        "description": "Apply all changes in the draft to the live event schedule. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Draft committed"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/sessions": {
      "get": {
        "operationId": "list-draft-sessions",
        "summary": "List draft sessions",
        "description": "List session placements within an agenda draft.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DraftSession"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/sessions/create": {
      "post": {
        "operationId": "create-draft-session",
        "summary": "Create a draft session",
        "description": "Place a session in an agenda draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session_id"
                ],
                "properties": {
                  "session_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "starts_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "ends_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "room_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft session created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DraftSession"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/sessions/{draftSessionId}": {
      "put": {
        "operationId": "update-draft-session",
        "summary": "Update a draft session",
        "description": "Move or update a session placement in a draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "draftSessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "starts_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "ends_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "room_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft session updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DraftSession"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-draft-session",
        "summary": "Remove a draft session",
        "description": "Remove a session from an agenda draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "draftSessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Draft session removed"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/agenda-drafts/{draftId}/sessions/bulk": {
      "post": {
        "operationId": "bulk-draft-sessions",
        "summary": "Bulk draft session operations",
        "description": "Batch create, update, or delete session placements in a draft. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkOperations"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/rules": {
      "get": {
        "operationId": "list-event-rules",
        "summary": "List event rules",
        "description": "Returns all scheduling rules for an event.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EventRule"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/rules/create": {
      "post": {
        "operationId": "create-event-rule",
        "summary": "Create an event rule",
        "description": "Create a scheduling constraint. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "type"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "enabled": {
                    "type": "boolean",
                    "default": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rule created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRule"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/rules/{ruleId}": {
      "get": {
        "operationId": "get-event-rule",
        "summary": "Get an event rule",
        "description": "Retrieve a single event rule by ID.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRule"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Rule not found"
          }
        }
      },
      "put": {
        "operationId": "update-event-rule",
        "summary": "Update an event rule",
        "description": "Update a scheduling rule. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rule updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRule"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-event-rule",
        "summary": "Delete an event rule",
        "description": "Delete a scheduling rule. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rule deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/personas": {
      "get": {
        "operationId": "list-personas",
        "summary": "List personas",
        "description": "Returns all evaluation personas for an event.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Persona"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/personas/create": {
      "post": {
        "operationId": "create-persona",
        "summary": "Create a persona",
        "description": "Create an attendee persona for schedule evaluation. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Persona created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/personas/{personaId}": {
      "get": {
        "operationId": "get-persona",
        "summary": "Get a persona",
        "description": "Retrieve a single persona by ID.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "personaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Persona not found"
          }
        }
      },
      "put": {
        "operationId": "update-persona",
        "summary": "Update a persona",
        "description": "Update a persona. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "personaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Persona updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Persona"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-persona",
        "summary": "Delete a persona",
        "description": "Delete a persona. Requires the `write:events` scope.",
        "tags": [
          "Agenda Planning"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "personaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Persona deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/dashboards": {
      "get": {
        "operationId": "list-event-dashboards",
        "summary": "List dashboards",
        "description": "Returns all dashboards for an event. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "updated_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/dashboards/create": {
      "post": {
        "operationId": "create-event-dashboard",
        "summary": "Create a dashboard",
        "description": "Create a new dashboard with optional inline widgets. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "widgets": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Optional inline widget definitions to create with the dashboard."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dashboard created"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/dashboards/{id}": {
      "get": {
        "operationId": "get-event-dashboard",
        "summary": "Get a dashboard",
        "description": "Retrieve a dashboard with all widget data. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "widgets": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Dashboard not found"
          }
        }
      },
      "put": {
        "operationId": "update-event-dashboard",
        "summary": "Update a dashboard",
        "description": "Update dashboard properties. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dashboard updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-event-dashboard",
        "summary": "Delete a dashboard",
        "description": "Delete a dashboard. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dashboard deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/dashboards/{dashboardId}/widgets/create": {
      "post": {
        "operationId": "create-widget",
        "summary": "Create a widget",
        "description": "Add a widget to a dashboard. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "dashboardId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "description": "Widget type (e.g., chart, table, number)."
                  },
                  "title": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Widget-specific configuration."
                  },
                  "query": {
                    "type": "string",
                    "description": "SbQL query for the widget data."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Widget created"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/widgets/{widgetId}": {
      "put": {
        "operationId": "update-widget",
        "summary": "Update a widget",
        "description": "Update widget configuration. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "widgetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "query": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Widget updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-widget",
        "summary": "Delete a widget",
        "description": "Delete a widget from its dashboard. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "widgetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Widget deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/queries": {
      "get": {
        "operationId": "list-event-queries",
        "summary": "List saved queries for an event",
        "description": "Returns saved SbQL queries scoped to an event. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "query": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/event/{eventId}/queries/create": {
      "post": {
        "operationId": "create-event-query",
        "summary": "Create a saved query",
        "description": "Save a SbQL query as a reusable report. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "query"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "query": {
                    "type": "string",
                    "description": "The SbQL query string."
                  },
                  "category": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Query saved"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/queries/{queryId}": {
      "put": {
        "operationId": "update-event-query",
        "summary": "Update a saved query",
        "description": "Update a saved query. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "query": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Query updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-event-query",
        "summary": "Delete a saved query",
        "description": "Delete a saved query. Requires the `write:events` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Query deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/queries/{queryId}/run": {
      "post": {
        "operationId": "run-event-query",
        "summary": "Run a saved query for an event",
        "description": "Execute a saved SbQL query. Requires the `write:events` scope (reports execute through the write pipeline for quota tracking).",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "obfuscatePii": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to mask personal-data fields (such as emails and phone numbers) in the results. Results are not masked unless you send `true`."
                  },
                  "page": {
                    "type": "integer"
                  },
                  "limit": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Query not found"
          }
        }
      }
    },
    "/v1/dashboards": {
      "get": {
        "operationId": "list-org-dashboards-convenience",
        "summary": "List org dashboards (convenience)",
        "description": "Returns all dashboards across all events in the organization. Organization is resolved from the API token. No orgId required. Requires the `read:insights` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "event_id": {
                        "type": "integer",
                        "nullable": true
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "updated_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/dashboards/create": {
      "post": {
        "operationId": "create-org-dashboard-convenience",
        "summary": "Create an org dashboard (convenience)",
        "description": "Create a new cross-event dashboard. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "widgets": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Optional inline widget definitions."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dashboard created"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/dashboards/{id}": {
      "get": {
        "operationId": "get-org-dashboard-convenience",
        "summary": "Get an org dashboard (convenience)",
        "description": "Retrieve a cross-event dashboard with all widget data. Organization is resolved from the API token. No orgId required. Requires the `read:insights` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "widgets": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Dashboard not found"
          }
        }
      },
      "put": {
        "operationId": "update-org-dashboard-convenience",
        "summary": "Update an org dashboard (convenience)",
        "description": "Update dashboard properties. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dashboard updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-org-dashboard-convenience",
        "summary": "Delete an org dashboard (convenience)",
        "description": "Delete a cross-event dashboard. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dashboard deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/dashboards/{dashboardId}/widgets/create": {
      "post": {
        "operationId": "create-org-widget-convenience",
        "summary": "Create an org widget (convenience)",
        "description": "Add a widget to an org-level dashboard. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "dashboardId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "description": "Widget type (e.g., chart, table, number)."
                  },
                  "title": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "query": {
                    "type": "string",
                    "description": "SbQL query for the widget data."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Widget created"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/widgets/{widgetId}": {
      "put": {
        "operationId": "update-org-widget-convenience",
        "summary": "Update an org widget (convenience)",
        "description": "Update widget configuration. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "widgetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "config": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "query": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Widget updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-org-widget-convenience",
        "summary": "Delete an org widget (convenience)",
        "description": "Delete a widget. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Dashboards & Widgets"
        ],
        "parameters": [
          {
            "name": "widgetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Widget deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/queries": {
      "get": {
        "operationId": "list-org-queries-convenience",
        "summary": "List org saved queries (convenience)",
        "description": "Returns all saved SbQL queries across the organization. Organization is resolved from the API token. No orgId required. Requires the `read:insights` scope.",
        "tags": [
          "Reports & Queries"
        ],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by category."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "query": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          },
                          "event_id": {
                            "type": "integer",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/v1/queries/create": {
      "post": {
        "operationId": "create-org-query-convenience",
        "summary": "Create an org saved query (convenience)",
        "description": "Save a cross-event SbQL query. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Reports & Queries"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "query"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "query": {
                    "type": "string",
                    "description": "The SbQL query string."
                  },
                  "category": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Query saved"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/queries/{queryId}": {
      "put": {
        "operationId": "update-org-query-convenience",
        "summary": "Update an org saved query (convenience)",
        "description": "Update a saved query. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Reports & Queries"
        ],
        "parameters": [
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "query": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Query updated"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-org-query-convenience",
        "summary": "Delete an org saved query (convenience)",
        "description": "Delete a saved query. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope.",
        "tags": [
          "Reports & Queries"
        ],
        "parameters": [
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Query deleted"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:events scope"
          }
        }
      }
    },
    "/v1/queries/{queryId}/run": {
      "post": {
        "operationId": "run-org-query-convenience",
        "summary": "Run an org saved query (convenience)",
        "description": "Execute a saved cross-event SbQL query. Organization is resolved from the API token. No orgId required. Requires the `write:events` scope (reports execute through the write pipeline for quota tracking).",
        "tags": [
          "Reports & Queries"
        ],
        "parameters": [
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "obfuscatePii": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to mask personal-data fields (such as emails and phone numbers) in the results. Results are not masked unless you send `true`."
                  },
                  "page": {
                    "type": "integer"
                  },
                  "limit": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Query not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/execute": {
      "post": {
        "operationId": "execute-event-query",
        "summary": "Execute a SbQL query (event-scoped)",
        "description": "Execute a SbQL query scoped to the event in the path. Requires the `read:insights` scope. The query runs on that event only; an `eventId` or `eventIds` in the body or query string that names a different event returns `400` (or `403 EVENT_NOT_ALLOWED` for a token limited to specific events). Use `POST /v1/insights/execute` for queries across events.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID to scope the query to."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string"
                  },
                  "obfuscatePii": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to mask personal-data fields (such as emails and phone numbers) in the results. Results are not masked unless you send `true`."
                  },
                  "page": {
                    "type": "integer"
                  },
                  "limit": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/ai/generate": {
      "post": {
        "operationId": "generate-event-query",
        "summary": "Generate a SbQL query from natural language (event-scoped)",
        "description": "Use AI to translate natural language into a SbQL query scoped to the event in the path. Requires the `read:insights` scope. An `eventId` in the body that names a different event returns `400` (or `403 EVENT_NOT_ALLOWED` for a token limited to specific events).",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "explanation": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/schema": {
      "get": {
        "operationId": "get-event-insights-schema",
        "summary": "Get event-scoped insights schema",
        "description": "Returns the SbQL schema including event-specific custom fields. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/suggestions": {
      "get": {
        "operationId": "get-event-suggestions",
        "summary": "Get event-scoped query suggestions",
        "description": "Returns contextual query suggestions for a specific event. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "query": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/queries": {
      "get": {
        "operationId": "list-event-insights-queries",
        "summary": "List saved queries (event-scoped insights)",
        "description": "Returns saved queries via the insights proxy. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/queries/{queryId}/run": {
      "post": {
        "operationId": "run-event-insights-query",
        "summary": "Run a saved query (event-scoped insights)",
        "description": "Execute a saved query via the insights proxy. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/insights/dashboards/{id}": {
      "get": {
        "operationId": "get-event-insights-dashboard",
        "summary": "Get a dashboard (event-scoped insights)",
        "description": "Retrieve a dashboard via the insights proxy. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "widgets": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/ask": {
      "post": {
        "operationId": "ask-event",
        "summary": "Ask a question about an event",
        "description": "Ask a question about one event in plain language and get an answer written for the\norganizer. The answer is grounded in the event's program (sessions, speakers, exhibitors,\nsponsors), session transcripts, the event's knowledge and pinned answers, and the\nSessionboard Help Center. `[n]` markers in `answer` point at `citations[]` entry `index` n;\ncitations are built from records, never from model text.\n\nRead-only: nothing in the event changes and `actions` is always `[]`.\n\nRequires the `read:ask` scope, granted **explicitly** — a legacy token with an empty scope\nlist does not get it. The token's event allow-list and the organization's AI features\nswitch apply.\n\n**Slow.** An answer takes several seconds and can take up to 90; set your client timeout\nto at least 90 seconds. If Sessionboard does not answer in time the API returns `504`.\n\nTo ask a follow-up in the same thread, send back the `conversation_id` from the previous\nanswer. A conversation continues only for the same token and user; any other\n`conversation_id` starts a new conversation.\n\nThe API request log records the call with `question` redacted.\n",
        "tags": [
          "Ask"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event to ask about."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskRequest"
              },
              "example": {
                "question": "Which sessions on Tuesday cover AI?",
                "lang": "en"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The answer and its sources.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskResponse"
                },
                "example": {
                  "status": "ok",
                  "answer": "Two sessions on Tuesday cover AI [1] [2].",
                  "citations": [
                    {
                      "index": 1,
                      "type": "session",
                      "id": "3f2a9c1e-5b7d-4e8a-9c0f-1a2b3c4d5e6f",
                      "title": "Applied AI in Clinical Practice",
                      "starts_at": "2026-11-10T14:00:00.000Z"
                    },
                    {
                      "index": 2,
                      "type": "session",
                      "id": "8d1e4b2a-6c3f-4a9e-b7d0-2e3f4a5b6c7d",
                      "title": "Panel: Where AI Helps and Where It Hurts",
                      "starts_at": "2026-11-10T16:30:00.000Z"
                    }
                  ],
                  "actions": [],
                  "conversation_id": "7b0c0e0c-9a39-4b8f-9d5d-1e2f3a4b5c6d",
                  "message_id": "2c9e7a41-0b3d-4f6e-8a1c-5d4e3f2a1b0c"
                }
              }
            }
          },
          "400": {
            "description": "Malformed body: `question` missing, an unknown key, a `conversation_id` that is not a\nUUID, a `lang` that is not a language tag, or a `question` longer than 1000 characters.\n"
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "- `SCOPE_REQUIRED` — the token does not hold `read:ask` (legacy tokens with no scopes included).\n- `EVENT_NOT_ALLOWED` — the event is outside the token's event allow-list.\n- `AI_DISABLED` — AI features are switched off for the organization.\n- `FORBIDDEN` — Ask is switched off for this event (`details.reason: off`), AI features are off (`details.reason: ai_disabled`), or the organization is out of AI credits under enforcement (`details.reason: ai_credits`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskError"
                },
                "examples": {
                  "scope_required": {
                    "summary": "Token lacks read:ask",
                    "value": {
                      "error": "SCOPE_REQUIRED",
                      "message": "This operation requires the 'read:ask' scope."
                    }
                  },
                  "event_not_allowed": {
                    "summary": "Event outside the token's allow-list",
                    "value": {
                      "error": "EVENT_NOT_ALLOWED",
                      "message": "This API token is not allowed to access this event"
                    }
                  },
                  "ai_disabled": {
                    "summary": "Organization AI features off",
                    "value": {
                      "error": "AI_DISABLED",
                      "message": "AI features are not enabled for this organization"
                    }
                  },
                  "ask_off": {
                    "summary": "Ask switched off for the event",
                    "value": {
                      "error": "FORBIDDEN",
                      "message": "Ask is switched off for this event.",
                      "details": {
                        "reason": "off"
                      }
                    }
                  },
                  "out_of_credits": {
                    "summary": "Organization out of AI credits",
                    "value": {
                      "error": "FORBIDDEN",
                      "message": "Out of AI credits. Add credits to continue.",
                      "details": {
                        "reason": "ai_credits"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The event does not exist or belongs to another organization."
          },
          "422": {
            "description": "`VALIDATION_ERROR` — Ask would not take the question. Nothing is spent.\n`details.reason` is `empty` (under 2 characters), `too_long` (over 500 characters),\n`blocked` (flagged as unsafe) or `repeated` (the same question asked twice in a row).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "Ask could not take that question.",
                  "details": {
                    "reason": "too_long",
                    "conversation_id": null
                  }
                }
              }
            }
          },
          "429": {
            "description": "- `RATE_LIMITED` — the per-user question limit (by default 10 a minute and 200 a day). `details.reason` is `per_minute` or `daily`; wait `Retry-After` seconds (also `details.retry_after_seconds`).\n- `QUOTA_EXCEEDED` — the event's daily Ask budget is used up (`details.reason: busy`). Try again later.\n- The API's own limit of 100 requests per 15 minutes per token, and 20 requests a minute per organization and user, also return `429` with `Retry-After`. That body is the gateway's `TooManyRequestsError` shape (`name`, `message`, `status`, `success`), not an `AskError` — see [Rate Limiting](/rate-limiting).\n",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before asking again.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AskError"
                    },
                    {
                      "$ref": "#/components/schemas/TooManyRequestsError"
                    }
                  ]
                },
                "examples": {
                  "rate_limited": {
                    "summary": "Per-user question limit",
                    "value": {
                      "error": "RATE_LIMITED",
                      "message": "Too many questions. Try again later.",
                      "details": {
                        "reason": "per_minute",
                        "retry_after_seconds": 17,
                        "remaining_today": 183
                      }
                    }
                  },
                  "quota_exceeded": {
                    "summary": "Event's daily Ask budget used up",
                    "value": {
                      "error": "QUOTA_EXCEEDED",
                      "message": "Today's Ask budget for this event is used up. Try again later.",
                      "details": {
                        "reason": "busy"
                      }
                    }
                  },
                  "api_rate_limit": {
                    "summary": "API token or organization request limit",
                    "value": {
                      "status": 429,
                      "success": false,
                      "message": "Error while trying to reach the endpoint: Too many requests",
                      "name": "TooManyRequestsError"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "`INTERNAL_ERROR` — Ask could not answer right now. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskError"
                },
                "example": {
                  "error": "INTERNAL_ERROR",
                  "message": "Ask could not answer right now."
                }
              }
            }
          },
          "504": {
            "description": "No answer within 90 seconds. Retry, or ask a narrower question."
          }
        }
      }
    },
    "/v1/event/{eventId}/emails/{key}/authoring/preview": {
      "post": {
        "operationId": "preview-event-email",
        "summary": "Preview a lifecycle email",
        "description": "Renders one of an in-person event's or webinar's lifecycle emails exactly as Sessionboard's own\npreview draws it: the event's real name, date, venue and join link, the Brand kit, and the footer the\nsend adds. `version: live` (the default) is what sends today; `version: proposed` is the design an AI\nassistant proposed, which a person has not accepted yet (`404` when there is none).\n\nReturns `subject`, `preheader`, `html`, `text`, `design_mode` and `accessibility_warnings`. A read:\nit stores nothing and emails no one. Requires `read:events`; the organization's AI switch applies, and\na key restricted to particular events can preview only those events' emails.\n",
        "tags": [
          "Event Emails"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event or webinar"
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The email's key, e.g. `gathering-reminder`"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "version": {
                    "type": "string",
                    "enum": [
                      "live",
                      "proposed"
                    ],
                    "default": "live"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The rendered email.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "version": {
                          "type": "string",
                          "enum": [
                            "live",
                            "proposed"
                          ]
                        },
                        "proposed_by": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Who proposed the design (`proposed` only)"
                        },
                        "proposed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "subject": {
                          "type": "string"
                        },
                        "preheader": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "html": {
                          "type": "string"
                        },
                        "text": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "design_mode": {
                          "type": "string"
                        },
                        "accessibility_warnings": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired token."
          },
          "403": {
            "description": "The token lacks `read:events`, is restricted to other events, or AI features are off for the organization."
          },
          "404": {
            "description": "The event is not in the token's organization, there is no email with that key, or there is no proposed design."
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/signatures": {
      "get": {
        "operationId": "get-sharing-email-signatures",
        "summary": "Get a webinar's email signatures",
        "description": "The email signatures your team adds before a webinar: a small banner (480×120) and a one-line invite,\nevery link going to the registration page through the teammate's own tracked link.\n\n`banner_url` is stable: it shows the \"Save your seat\" banner until the webinar starts and the \"Watch the\nrecording\" banner after, so a signature already pasted changes by itself. `stale: true` means the\ntitle, date, registration link or brand changed since the signatures were made. `team` lists each\nteammate with their link, when they were emailed, opened and copied their signature, and the clicks and\nregistrations it brought.\n\nWebinars only (`409` otherwise). Requires `read:events` and a user whose role on the webinar can read sharing.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "responses": {
          "200": {
            "description": "The signatures and the team.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingSignatures"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired token."
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "404": {
            "description": "The event is not in the token's organization."
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      },
      "post": {
        "operationId": "make-sharing-email-signatures",
        "summary": "Make a webinar's email signatures",
        "description": "Makes (or remakes) the signature banners, before and after the start, from the webinar as it is now and\nin the event's brand. Signatures already pasted pick up the new banner through their stable image URL.\nSends nothing. Returns the same payload as the GET. Requires `write:marketing`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signatures and the team.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingSignatures"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired token."
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/signatures/team": {
      "post": {
        "operationId": "add-sharing-signature-teammates",
        "summary": "Add teammates to a webinar's email signatures",
        "description": "Gives organization members their own tracked link for the webinar's email signatures, without emailing\nthem. Returns the GET payload. Requires `write:marketing` and a user whose role on the webinar can\nedit sharing.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SharingUserIds"
              },
              "example": {
                "user_ids": [
                  1042,
                  1077
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signatures and the team.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingSignatures"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`user_ids` missing, empty or longer than 50, or a user who is not an active member of the organization."
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/signatures/team/{teammateId}": {
      "delete": {
        "operationId": "remove-sharing-signature-teammate",
        "summary": "Take a teammate off a webinar's email signatures",
        "description": "A signature they already pasted keeps linking (the tracked link stays live); their signature page\ncloses. Returns the GET payload. Requires `write:marketing`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          },
          {
            "name": "teammateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`team[].id` from the GET."
          }
        ],
        "responses": {
          "200": {
            "description": "The signatures and the team.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingSignatures"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "404": {
            "description": "No such teammate on this webinar."
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/signatures/send": {
      "post": {
        "operationId": "send-sharing-email-signatures",
        "summary": "Email teammates their email signature",
        "description": "Puts these organization members on the team (if they are not on it) and emails each one a link to a\npage where they copy their signature into their email client. Refused once the webinar has started.\n\nFrom an AI assistant (an MCP or OAuth connection) this does not send: it answers `202` with\n`status: needs_approval` and a link, a person approves it in Sessionboard, and it then sends as them.\nDo not call again for the same request. Requires `write:marketing`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SharingUserIds"
              },
              "example": {
                "user_ids": [
                  1042
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "type": "object",
                      "properties": {
                        "sent": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "recipient": {
                                "type": "string"
                              },
                              "reason": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "state": {
                          "$ref": "#/components/schemas/SharingSignatures"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Waiting for a person's OK in Sessionboard; nothing was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "needs_approval"
                          ]
                        },
                        "approval_id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`user_ids` missing, empty or longer than 50."
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "description": "Not a webinar, or the webinar has started."
          },
          "429": {
            "description": "Too many sends; wait before retrying."
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/share-cards": {
      "get": {
        "operationId": "get-sharing-share-cards",
        "summary": "Get a webinar's share cards",
        "description": "Six on-brand images (1200×627) for the weeks before a webinar: three with the speakers' faces\n(`spotlight`, `lineup`, `portrait`) and three without (`headline`, `calendar`, `ticket`). Each carries\nthe title, the date and time in the webinar's time zone, the speakers and the registration link as text\nand a QR code. `cards` is empty until they are made; `in_advocacy` says whether a card is on the\nspeakers' and attendees' sharing pages. `stale: true` means the title, date, speakers, link or brand\nchanged since they were made. Requires `read:events`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "responses": {
          "200": {
            "description": "The share cards.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingShareCards"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      },
      "post": {
        "operationId": "make-sharing-share-cards",
        "summary": "Make a webinar's share cards",
        "description": "Makes (or remakes) all six cards, or `designs`, from the webinar as it is now. Takes a few seconds.\nRemaking updates the same cards wherever they are used and keeps which ones are on the sharing pages.\nReturns the GET payload. Requires `write:marketing`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "designs": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "spotlight",
                        "lineup",
                        "portrait",
                        "headline",
                        "calendar",
                        "ticket"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The share cards.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingShareCards"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/speaker-links": {
      "get": {
        "operationId": "get-sharing-speaker-links",
        "summary": "Get speakers' sharing links",
        "description": "Each speaker's and co-presenter's personal tracked link for a webinar (≤ 200, by name), with their shares.\nA speaker with no link yet comes back `share_url: null, pending: true`; give speakers links to fix that.\n`campaign` and `speaker_campaign` say whether sharing is on for attendees and speakers. Sessionboard does\nnot email speakers their link. Requires `read:events` and a user whose role on the webinar can read sharing.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "responses": {
          "200": {
            "description": "The speakers and their links.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "$ref": "#/components/schemas/SharingSpeakerLinks"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      },
      "post": {
        "operationId": "give-sharing-speaker-links",
        "summary": "Give speakers sharing links",
        "description": "Turns sharing on for the webinar (attendees and speakers) if it is not, and gives every current speaker and\nco-presenter a personal tracked link. Safe to repeat; emails no one. Returns the GET payload plus `created`\n(sharing was just turned on). Requires `write:marketing` and a user whose role on the webinar can edit sharing.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The speakers and their links.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/SharingSpeakerLinks"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "created": {
                              "type": "boolean"
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      }
    },
    "/v1/event/{eventId}/sharing/team-kit": {
      "post": {
        "operationId": "make-sharing-team-kit",
        "summary": "Draft a team sharing kit",
        "description": "Drafts a kit your team shares: one LinkedIn post per image with its copy. Before the webinar starts it uses\nthe share cards (\"Save your seat\", spread over the days left); after, the recording's clips (\"Watch\non-demand\"; `clip_ids` picks them, else the first three). Returns the draft's `dispatch_id` and `url` (a\nrelative admin path) where a person picks the team and sends it. Nothing is sent; the webinar's open draft\nis returned instead of a second one. Requires `write:marketing`.\n",
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SharingEventId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "channel"
                ],
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "email",
                      "slack",
                      "teams",
                      "both"
                    ],
                    "description": "How the team will get it (`both` = chat and email). Preselects the recipients tab."
                  },
                  "clip_ids": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "channel": "email"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The draft.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "payload": {
                      "type": "object",
                      "properties": {
                        "dispatch_id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/SharingForbidden"
          },
          "409": {
            "$ref": "#/components/responses/SharingNotAWebinar"
          }
        }
      }
    },
    "/v1/gdpr/requests": {
      "get": {
        "operationId": "list-gdpr-requests",
        "summary": "List GDPR requests",
        "description": "Returns the organization's GDPR data access and erasure requests,\nnewest first.\n\nThe response is a bare JSON array, not a `results` envelope. This page\npreviously showed an envelope; the endpoint has always returned the\narray.\n\nPaginated with `page` and `pageSize` (default 25, maximum 100). Keep\nrequesting pages until one comes back with fewer than `pageSize`\nentries.\n\nBoth parameters are validated. A `page` or `pageSize` outside its\ndocumented range, and any query parameter this operation does not\ndeclare, are rejected with a `400`. Out-of-range values used to be\naccepted and silently clamped.\n",
        "tags": [
          "GDPR"
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 1
            },
            "description": "1-based page number, 1 to 999. Outside that range is a `400`."
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Requests per page, 1 to 100. Outside that range is a `400`; values above 100 are no longer clamped."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GDPRRequest"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`page` or `pageSize` is outside its documented range, or an undeclared query parameter was sent."
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "create-gdpr-request",
        "summary": "Create a GDPR request",
        "description": "Submit a GDPR data access or erasure request for one email address, and\nprocess it synchronously against the organization's data.\n\nFor `requestType: erasure` the call returns once the erasure has run.\nRead `status` to find out what happened — it is recorded by the\nerasure itself and is never assumed:\n\n- `complete` — the email matched at least one record and erasure ran\n  against it.\n- `no_records_found` — nothing in this organization matched the email.\n  Nothing was erased. Treat this as an outcome to escalate, not a\n  fulfilled request.\n\n`response` carries the identifiers that were matched, and on requests\nprocessed recently also `counts`, `users_scrubbed` and\n`users_retained` — the compliance evidence of what the erasure actually\ndid. A user account shared with another organization is retained rather\nthan scrubbed, and appears in `users_retained`.\n\nA `502` means the erasure did not run and **nothing was recorded or\nerased**; retry the request.\n",
        "tags": [
          "GDPR"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "requestType",
                  "identityType",
                  "identityValue"
                ],
                "properties": {
                  "requestType": {
                    "type": "string",
                    "enum": [
                      "erasure",
                      "access"
                    ],
                    "description": "The type of GDPR request."
                  },
                  "identityType": {
                    "type": "string",
                    "enum": [
                      "email"
                    ],
                    "description": "The type of identity to look up."
                  },
                  "identityValue": {
                    "type": "string",
                    "description": "The identity value (e.g., an email address).",
                    "examples": [
                      "jane.doe@example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request was recorded and, for an erasure, processed. Check `status` for the outcome.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GDPRRequest"
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "502": {
            "description": "The erasure service could not be reached. Nothing was recorded and nothing was erased — retry."
          }
        }
      }
    },
    "/v1/insights/execute": {
      "post": {
        "operationId": "execute-query",
        "summary": "Execute a SbQL query",
        "description": "Execute a SbQL query against event data and return results. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "The SbQL query string to execute.",
                    "examples": [
                      "SELECT sessions.title, sessions.status FROM sessions"
                    ]
                  },
                  "eventId": {
                    "type": "integer",
                    "description": "Scope query to a single event."
                  },
                  "eventIds": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Scope query to multiple events."
                  },
                  "obfuscatePii": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to mask personal-data fields (such as emails and phone numbers) in the results. Results are not masked unless you send `true`."
                  },
                  "format": {
                    "type": "string",
                    "description": "Output format for results."
                  },
                  "page": {
                    "type": "integer",
                    "description": "Page number for paginated results."
                  },
                  "limit": {
                    "type": "integer",
                    "description": "Maximum number of rows to return."
                  },
                  "search": {
                    "type": "string",
                    "description": "Full-text search within results."
                  },
                  "sortBy": {
                    "type": "string",
                    "description": "Column name to sort results by."
                  },
                  "sortDirection": {
                    "type": "string",
                    "enum": [
                      "asc",
                      "desc"
                    ],
                    "description": "Sort direction."
                  },
                  "groupBy": {
                    "type": "string",
                    "description": "Column name to group results by."
                  },
                  "pivot": {
                    "type": "string",
                    "description": "Column name to pivot results on."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/insights/ai/generate": {
      "post": {
        "operationId": "generate-query",
        "summary": "Generate a SbQL query from natural language",
        "description": "Use AI to translate a natural language prompt into a SbQL query. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "Natural language description of the data you want to query.",
                    "examples": [
                      "Show me all accepted sessions with their speakers"
                    ]
                  },
                  "eventId": {
                    "type": "integer",
                    "description": "Scope to a single event for context."
                  },
                  "eventIds": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Scope to multiple events for context."
                  },
                  "conversationHistory": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "role": {
                          "type": "string",
                          "description": "The message role (e.g., user, assistant)."
                        },
                        "content": {
                          "type": "string",
                          "description": "The message content."
                        }
                      }
                    },
                    "description": "Previous conversation turns for multi-turn query refinement."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "description": "The generated SbQL query."
                    },
                    "explanation": {
                      "type": "string",
                      "description": "Human-readable explanation of the generated query."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/insights/schema": {
      "get": {
        "operationId": "get-schema",
        "summary": "Get insights schema",
        "description": "Returns the SbQL schema for the organization, including available entities and fields. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The SbQL schema definition."
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/insights/events/{eventId}/schema": {
      "get": {
        "operationId": "get-event-schema",
        "summary": "Get event-specific insights schema",
        "description": "Returns the SbQL schema scoped to a specific event, including event-specific custom fields. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The event-scoped SbQL schema definition."
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/insights/suggestions": {
      "get": {
        "operationId": "get-suggestions",
        "summary": "Get query suggestions",
        "description": "Returns contextual SbQL query suggestions. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Scope suggestions to a specific event."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter suggestions by category."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "query": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/insights/queries": {
      "get": {
        "operationId": "list-queries",
        "summary": "List saved queries",
        "description": "Returns a list of saved SbQL queries. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Filter queries by event."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter queries by category."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Page number."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Results per page."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "query": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          },
                          "eventId": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          }
        }
      }
    },
    "/v1/insights/queries/{queryId}/run": {
      "post": {
        "operationId": "run-query",
        "summary": "Run a saved query",
        "description": "Execute a previously saved SbQL query by ID. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "queryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The saved query ID."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eventId": {
                    "type": "integer",
                    "description": "Override the event scope for this run."
                  },
                  "eventIds": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Override with multiple event scopes."
                  },
                  "obfuscatePii": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to mask personal-data fields (such as emails and phone numbers) in the results. Results are not masked unless you send `true`."
                  },
                  "format": {
                    "type": "string"
                  },
                  "page": {
                    "type": "integer"
                  },
                  "limit": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Saved query not found"
          }
        }
      }
    },
    "/v1/insights/dashboards/{id}": {
      "get": {
        "operationId": "get-dashboard",
        "summary": "Get a dashboard",
        "description": "Retrieve a dashboard with all its widget data. Requires the `read:insights` scope.",
        "tags": [
          "Insights"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The dashboard ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "widgets": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Dashboard not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/create": {
      "post": {
        "operationId": "create-session",
        "summary": "Create a session",
        "description": "Create a new session in an event. Requires the `write:sessions` scope. Subject to rate limiting (100 req/15min) and daily write quota (10,000/day per token).",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "Session title."
                  },
                  "description": {
                    "type": "string",
                    "description": "Session description (HTML allowed)."
                  },
                  "starts_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Session start time."
                  },
                  "ends_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Session end time."
                  },
                  "capacity": {
                    "type": "integer",
                    "description": "Maximum capacity for the session."
                  },
                  "room_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Room ID to assign."
                  },
                  "track_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Track ID to assign."
                  },
                  "level_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Level ID to assign."
                  },
                  "format_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Format ID to assign."
                  },
                  "language_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Language ID to assign."
                  },
                  "parent_session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Parent session ID (for subsessions)."
                  },
                  "tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Tag IDs to assign."
                  },
                  "status": {
                    "type": "string",
                    "description": "Session status (e.g., pending, accepted)."
                  },
                  "is_public": {
                    "type": "boolean",
                    "description": "Whether the session is publicly visible."
                  },
                  "is_abstract": {
                    "type": "boolean",
                    "default": false,
                    "description": "Create an abstract (CFP) submission instead of a program session.\nRequires the Sessions 2.0 feature on the event.\n"
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope or feature not enabled"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/restore": {
      "post": {
        "operationId": "restore-session",
        "summary": "Restore a deleted session",
        "description": "Restore a previously soft-deleted session. Requires the `write:sessions` scope.",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The session ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Session restored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "Session not found or not deleted"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/bulk": {
      "post": {
        "operationId": "bulk-sessions",
        "summary": "Bulk session operations",
        "description": "Create, update, or delete multiple sessions in a single request (max 100 operations). Requires the `write:sessions` scope.",
        "tags": [
          "Session Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkOperations"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts/create": {
      "post": {
        "operationId": "create-contact",
        "summary": "Create a contact",
        "description": "Create a new contact in an event. Requires the `write:contacts` scope. Subject to rate limiting (100 req/15min) and daily write quota (10,000/day per token).\n\nFields an event marks **Required** in Record Settings (the Add Contact layout) are not enforced here or by `POST /v1/event/{eventId}/contacts/bulk`; they apply only to the event's Add Contact form in the app. Validate them in your integration if you rely on them.\n",
        "tags": [
          "Contact Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Contact email address (required, must be unique within the event)."
                  },
                  "first_name": {
                    "type": "string",
                    "description": "First name."
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Last name."
                  },
                  "company": {
                    "type": "string",
                    "description": "Company or organization name."
                  },
                  "title": {
                    "type": "string",
                    "description": "Job title."
                  },
                  "phone": {
                    "type": "string",
                    "description": "Phone number."
                  },
                  "about": {
                    "type": "string",
                    "description": "Biography. HTML is allowed and stored as rich text."
                  },
                  "salutation": {
                    "type": "string"
                  },
                  "honorific": {
                    "type": "string"
                  },
                  "address_line_1": {
                    "type": "string"
                  },
                  "address_line_2": {
                    "type": "string"
                  },
                  "address_city": {
                    "type": "string"
                  },
                  "address_state": {
                    "type": "string"
                  },
                  "address_postal_code": {
                    "type": "string"
                  },
                  "address_country": {
                    "type": "string",
                    "description": "ISO 3166-1 numeric code (as GET returns), alpha-2 or alpha-3 code, or English country name. Stored and returned as the numeric code. An unknown value returns `400` naming the field and nothing is written."
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope or feature not enabled"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts/{contactId}/restore": {
      "post": {
        "operationId": "restore-contact",
        "summary": "Restore a deleted contact",
        "description": "Restore a previously soft-deleted contact. Requires the `write:contacts` scope.",
        "tags": [
          "Contact Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The contact ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Contact restored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:contacts scope"
          },
          "404": {
            "description": "Contact not found or not deleted"
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts/bulk": {
      "post": {
        "operationId": "bulk-contacts",
        "summary": "Bulk contact operations",
        "description": "Create, update, or delete multiple contacts in a single request (max\n100 operations). Requires the `write:contacts` scope. Fields an event\nmarks **Required** in Record Settings are not enforced on create, as\nwith `contacts/create`.\n\nSend the `{ action, id, data }` envelope every other bulk endpoint\nuses. This endpoint previously read the contact fields off the\noperation itself and rejected the documented envelope with\n`email is required` on every action; that is fixed, and the flat form\nbelow is still accepted for existing integrations.\n\nOperations are applied **in request order, one transaction each**. An\noperation that fails leaves nothing behind — no partially written\ncontact, no dangling event association — and the operations around it\nstill apply. `results` comes back in request order, so\n`results[i]` always describes `operations[i]`.\n\n`data` accepts the same fields as `POST /contacts/create`, including\n`custom_fields` and `translated_fields`. A create whose email already\nexists in the organization links that contact to the event instead of\nduplicating it, and reports `status: \"associated\"`.\n\n<Warning>\n  **Deprecated: flat operations.** An operation with no `action` key is\n  treated as a create, with the operation object itself as its `data`:\n  `{ \"email\": \"a@b.com\", \"first_name\": \"Ada\" }` behaves like\n  `{ \"action\": \"create\", \"data\": { \"email\": \"a@b.com\", \"first_name\": \"Ada\" } }`.\n  This shape is supported for existing callers only and will not gain\n  new capabilities. Send the envelope.\n</Warning>\n",
        "tags": [
          "Contact Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkOperations"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:contacts scope"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/exhibitors/create": {
      "post": {
        "operationId": "create-exhibitor",
        "summary": "Create an exhibitor",
        "description": "Create a new exhibitor in an event. Requires the `write:exhibitors` scope. Subject to rate limiting (100 req/15min) and daily write quota (10,000/day per token).",
        "tags": [
          "Exhibitor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Exhibitor name. Required if `account_id` is not provided."
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Existing account ID to link, instead of creating a new account. Required if `name` is not provided. This is also how a group takes its second role: pass the `account_id` of a record that is already a sponsor or an exhibitor and it holds both roles on this event, under the same id. Repeating a link it already holds is a no-op.\n"
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Exhibitor created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exhibitor"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope or feature not enabled"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/exhibitors/{exhibitorId}/restore": {
      "post": {
        "operationId": "restore-exhibitor",
        "summary": "Restore a deleted exhibitor",
        "description": "Restore a previously soft-deleted exhibitor. Requires the `write:exhibitors` scope.\n\nRestore has the same reach as the delete it reverses: it restores the **group**, so a group that held both roles comes back as both a sponsor and an exhibitor, and it reappears on every event it was linked to — not only the event in the path.\n",
        "tags": [
          "Exhibitor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "exhibitorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The exhibitor ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Exhibitor restored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Exhibitor"
                }
              }
            }
          },
          "400": {
            "description": "The exhibitor is not deleted, so there is nothing to restore. Restore is not idempotent — check before retrying.\n"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:exhibitors scope"
          },
          "404": {
            "description": "No exhibitor with this id on this event. A record that exists but does not hold the exhibitor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          }
        }
      }
    },
    "/v1/event/{eventId}/exhibitors/bulk": {
      "post": {
        "operationId": "bulk-exhibitors",
        "summary": "Bulk exhibitor operations",
        "description": "Create, update, or delete multiple exhibitors in a single request (max 100 operations). Requires the `write:exhibitors` scope.",
        "tags": [
          "Exhibitor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkOperations"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:exhibitors scope"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/sponsors/create": {
      "post": {
        "operationId": "create-sponsor",
        "summary": "Create a sponsor",
        "description": "Create a new sponsor in an event. Requires the `write:sponsors` scope. Subject to rate limiting (100 req/15min) and daily write quota (10,000/day per token).",
        "tags": [
          "Sponsor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Sponsor name. Required if `account_id` is not provided."
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Existing account ID to link, instead of creating a new account. Required if `name` is not provided. This is also how a group takes its second role: pass the `account_id` of a record that is already a sponsor or an exhibitor and it holds both roles on this event, under the same id. Repeating a link it already holds is a no-op.\n"
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Custom field values keyed by field internal name.\n\nFor `number`, `currency`, and `percent` fields, an empty\nstring (`\"\"`) clears the stored value — identical to\nsending `null`. `0` and `\"0\"` store an actual zero.\n\nFor `checkbox` fields, send boolean `true` or `false`.\nOn read, a checked box serializes as the string `\"Yes\"`, an\nexplicitly unchecked one as `\"No\"`, and a box that was never\nset as `null`.\n\nFields owned by an integration (for example\n`swoogo_session_id`, `cvent_session_id`,\n`visit_session_id`) are hydrated by the connector and\nreject writes with `400` `FIELD_READ_ONLY`, naming the\nfield in `details.field`. Omit them from `custom_fields`.\n"
                  },
                  "translated_fields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TranslatedFieldWrite"
                    },
                    "description": "Language variants to write using the same shape returned on reads.\nOmit this key on update to leave existing translations unchanged.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sponsor created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sponsor"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Insufficient scope or feature not enabled"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/sponsors/{sponsorId}/restore": {
      "post": {
        "operationId": "restore-sponsor",
        "summary": "Restore a deleted sponsor",
        "description": "Restore a previously soft-deleted sponsor. Requires the `write:sponsors` scope.\n\nRestore has the same reach as the delete it reverses: it restores the **group**, so a group that held both roles comes back as both a sponsor and an exhibitor, and it reappears on every event it was linked to — not only the event in the path.\n",
        "tags": [
          "Sponsor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          },
          {
            "name": "sponsorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The sponsor ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Sponsor restored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Sponsor"
                }
              }
            }
          },
          "400": {
            "description": "The sponsor is not deleted, so there is nothing to restore. Restore is not idempotent — check before retrying.\n"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sponsors scope"
          },
          "404": {
            "description": "No sponsor with this id on this event. A record that exists but does not hold the sponsor role — a contact, or a group linked only as the other role — is also a `404` here; look it up on the endpoint for the role it holds.\n"
          }
        }
      }
    },
    "/v1/event/{eventId}/sponsors/bulk": {
      "post": {
        "operationId": "bulk-sponsors",
        "summary": "Bulk sponsor operations",
        "description": "Create, update, or delete multiple sponsors in a single request (max 100 operations). Requires the `write:sponsors` scope.",
        "tags": [
          "Sponsor Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The event ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkOperations"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk operation completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:sponsors scope"
          },
          "429": {
            "description": "Rate limit or daily quota exceeded"
          }
        }
      }
    },
    "/v1/event/{eventId}/fields/create": {
      "post": {
        "operationId": "create-field",
        "summary": "Create a custom field",
        "description": "Create a new custom field for an event module. Requires the `write:fields` scope.",
        "tags": [
          "Field Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string"
                  },
                  "module_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Field created"
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Missing write:fields scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/fields/{fieldId}": {
      "put": {
        "operationId": "update-field",
        "summary": "Update a custom field",
        "tags": [
          "Field Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Field updated"
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      },
      "delete": {
        "operationId": "delete-field",
        "summary": "Delete a custom field",
        "tags": [
          "Field Writes"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Field deleted. No response body."
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/oauth/authorize": {
      "get": {
        "operationId": "oauth-authorize",
        "summary": "Validate authorization request",
        "description": "Validates OAuth authorization request parameters (client_id, redirect_uri, scopes, PKCE challenge). Returns the validated request for display on the consent page. No authentication required.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "parameters": [
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "code"
              ]
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "S256"
              ]
            }
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Space-separated scopes"
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authorization request validated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "authorization_request": {
                      "type": "object",
                      "properties": {
                        "client_id": {
                          "type": "string"
                        },
                        "client_name": {
                          "type": "string"
                        },
                        "redirect_uri": {
                          "type": "string"
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters"
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "operationId": "oauth-token",
        "summary": "Exchange code for tokens",
        "description": "Exchange an authorization code for access and refresh tokens (authorization_code grant), or refresh an expired access token (refresh_token grant). Uses PKCE verification — no client secret required.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "title": "Authorization Code Exchange",
                    "required": [
                      "grant_type",
                      "code",
                      "redirect_uri",
                      "client_id",
                      "code_verifier"
                    ],
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "enum": [
                          "authorization_code"
                        ]
                      },
                      "code": {
                        "type": "string"
                      },
                      "redirect_uri": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string"
                      },
                      "code_verifier": {
                        "type": "string",
                        "description": "PKCE code verifier"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "title": "Refresh Token",
                    "required": [
                      "grant_type",
                      "refresh_token",
                      "client_id"
                    ],
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "enum": [
                          "refresh_token"
                        ]
                      },
                      "refresh_token": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tokens issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "example": "Bearer"
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 3600
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid grant or parameters"
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "operationId": "oauth-revoke",
        "summary": "Revoke a token",
        "description": "Revoke an access or refresh token. Conforms to RFC 7009. Always returns 200 regardless of whether the token was found.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "type": "string",
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token revoked (or was already invalid)"
          }
        }
      }
    },
    "/oauth/.well-known/oauth-authorization-server": {
      "get": {
        "operationId": "oauth-metadata",
        "summary": "Authorization server metadata",
        "description": "Returns OAuth 2.0 Authorization Server Metadata per RFC 8414. Includes supported scopes, grant types, and endpoint URLs.",
        "tags": [
          "OAuth"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Server metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string"
                    },
                    "authorization_endpoint": {
                      "type": "string"
                    },
                    "token_endpoint": {
                      "type": "string"
                    },
                    "revocation_endpoint": {
                      "type": "string"
                    },
                    "response_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "grant_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "scopes_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "code_challenge_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/event/{eventId}/contacts/{contactId}/sessions": {
      "get": {
        "operationId": "get-contact-sessions",
        "summary": "Get a contact's sessions",
        "description": "Returns all sessions associated with a specific contact within an\nevent, including linked composition sources. Each session summary\nincludes `is_abstract` and `composition_status`. The full\n`composition` graph is not available on this lightweight endpoint —\nuse session GET or search with `expand=composition` for details.\n",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactSessionsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/v1/organization/{orgId}/contacts/{contactId}/sessions": {
      "get": {
        "operationId": "get-org-contact-sessions",
        "summary": "Get an org contact's sessions",
        "description": "Returns all sessions associated with a specific contact across the\norganization, including linked composition sources. Each session\nsummary includes `is_abstract`, `composition_status`, and\n`event_id`. The full `composition` graph is not available on this\nlightweight endpoint.\n",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgContactSessionsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "404": {
            "description": "Contact not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/content": {
      "get": {
        "operationId": "list-event-content",
        "summary": "List composed session content for an event",
        "description": "Paginated list of session content packs (composed transcript, preferred summary,\ninsights, podcast status, and document links). Prefer this over the raw\npolymorphic transcriptions list for mobile and partner apps.\n\nRequires `read:transcriptions` scope (legacy tokens with empty scopes pass).\n\nDefault packs are compact (`elements` empty on transcription items). Pass\n`expand=items` (plus other types) for full element arrays.\n",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "session_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated item types. Default `transcription,summary,insight,podcast,document`.\nAdd `items` on the event list for full transcription elements (list is compact by default).\n`expand=items` alone still includes the default types. Session GET always returns full elements.\n",
            "schema": {
              "type": "string",
              "example": "transcription,summary,items"
            }
          },
          {
            "name": "interval_sec",
            "in": "query",
            "description": "Optional time window (seconds) for rechunking same-speaker transcript elements. Omit for speaker turns only. Clamped to 3600.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 3600
            }
          },
          {
            "name": "provider",
            "in": "query",
            "description": "Preferred summary provider when multiple exist.",
            "schema": {
              "type": "string",
              "enum": [
                "claude",
                "openai"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionContentListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/content/event": {
      "get": {
        "operationId": "get-event-content",
        "summary": "Get event-level content artifacts",
        "description": "Event report document metadata and recap rollup (quotes, topics, summary excerpts).\nRequires `read:transcriptions` scope. Default expand is `document,recap`.\n",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated. Default `document,recap`. Pass only the types you want.",
            "schema": {
              "type": "string",
              "example": "document,recap"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventContentResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/content/items/{itemId}": {
      "get": {
        "operationId": "get-content-item",
        "summary": "Get a single content item",
        "description": "Resolve one content item. `itemId` may be a session UUID (composed transcription),\na summary/insight/podcast UUID, or a document type (`summary_pdf`, `summary_card`,\n`event_report`, `recap`). Document types `summary_pdf` / `summary_card` require\n`session_id`. Requires `read:transcriptions` scope.\n",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "session_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "interval_sec",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "provider",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentItemResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/content/documents/{documentType}": {
      "get": {
        "operationId": "download-event-content-document",
        "summary": "Download an event content document",
        "description": "Streams `event_report` PDF. Requires `read:transcriptions` scope.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "event_report"
              ]
            }
          },
          {
            "name": "variant",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "daily",
                "theme"
              ],
              "default": "full"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF bytes",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not available"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/content": {
      "get": {
        "operationId": "get-session-content",
        "summary": "Get composed content for a session",
        "description": "Canonical one-call session pack for mobile and partner apps — composed\ntranscription elements, preferred summary, insights, podcast URL/status,\nand summary PDF/card links. Distinct from session **composition**\n(abstract/parent-child linking).\n\nRequires `read:transcriptions` scope (legacy tokens with empty scopes pass).\n",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated item types. Default `transcription,summary,insight,podcast,document`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "interval_sec",
            "in": "query",
            "description": "Optional time window (seconds) for rechunking same-speaker elements.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "provider",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "claude",
                "openai"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionContentResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Session not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/content/documents/{documentType}": {
      "get": {
        "operationId": "download-session-content-document",
        "summary": "Download a session content document",
        "description": "Streams `summary_pdf` or `summary_card`. Requires `read:transcriptions` scope.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "summary_pdf",
                "summary_card"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Document bytes",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not available"
          }
        }
      }
    },
    "/v1/event/{eventId}/transcriptions": {
      "get": {
        "operationId": "list-event-transcriptions",
        "summary": "List transcriptions for an event",
        "description": "Paginated list of transcription artifacts across all sessions. Filter by type, session_id, or language_code. Requires `read:transcriptions` scope (legacy tokens with empty scopes pass). Prefer `/content` for composed mobile-friendly packs.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "fragment",
                "summary",
                "insight",
                "translation"
              ]
            }
          },
          {
            "name": "session_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "language_code",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_partial",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/transcriptions/{transcriptionId}": {
      "get": {
        "operationId": "get-transcription",
        "summary": "Get a transcription by ID",
        "description": "Requires `read:transcriptions` scope (legacy tokens with empty scopes pass).",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "name": "transcriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/transcriptions": {
      "get": {
        "operationId": "list-session-transcriptions",
        "summary": "List transcriptions for a session",
        "description": "Requires `read:transcriptions` scope (legacy tokens with empty scopes pass).",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          }
        }
      },
      "post": {
        "operationId": "create-transcription",
        "summary": "Create a transcription artifact",
        "description": "Requires `write:transcriptions` scope.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TranscriptionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing write:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/transcriptions/{transcriptionId}": {
      "get": {
        "operationId": "get-session-transcription",
        "summary": "Get a session transcription by ID",
        "description": "Requires `read:transcriptions` scope (legacy tokens with empty scopes pass).",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "transcriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not found"
          }
        }
      },
      "put": {
        "operationId": "update-transcription",
        "summary": "Update a transcription artifact",
        "description": "Requires `write:transcriptions` scope.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "transcriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing write:transcriptions scope"
          }
        }
      },
      "delete": {
        "operationId": "delete-transcription",
        "summary": "Delete a transcription artifact",
        "description": "Requires `write:transcriptions` scope.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "transcriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "403": {
            "description": "Missing write:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/recordings": {
      "get": {
        "operationId": "list-session-recordings",
        "summary": "List session audio recordings",
        "description": "Requires `read:transcriptions` scope (legacy tokens with empty scopes pass).",
        "tags": [
          "Session Recordings"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Recording"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          }
        }
      },
      "post": {
        "operationId": "create-session-recording",
        "summary": "Initiate session audio upload",
        "description": "Returns a presigned upload URL for the audio file. Requires `write:transcriptions`.",
        "tags": [
          "Session Recordings"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "size_bytes"
                ],
                "properties": {
                  "filename": {
                    "type": "string"
                  },
                  "content_type": {
                    "type": "string"
                  },
                  "size_bytes": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordingCreateResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing write:transcriptions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}": {
      "get": {
        "operationId": "get-session-recording",
        "summary": "Get a session audio recording",
        "description": "Requires `read:transcriptions` scope (legacy tokens with empty scopes pass).",
        "tags": [
          "Session Recordings"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "recordingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordingResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:transcriptions scope"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete": {
      "post": {
        "operationId": "complete-session-recording",
        "summary": "Finalize session audio upload",
        "description": "Marks the recording as completed and normalizes common audio formats for playback.\nAlready-completed recordings return 200 without re-processing. Requires `write:transcriptions`.\n",
        "tags": [
          "Session Recordings"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "recordingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "duration_seconds": {
                    "type": "number"
                  },
                  "file_size_bytes": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordingResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing write:transcriptions scope"
          },
          "422": {
            "description": "PCM transcode failed (TRANSCODE_ERROR)"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/media/upload/initiate": {
      "post": {
        "operationId": "initiate-media-upload",
        "summary": "Start multipart media upload",
        "description": "Begins a multipart upload for a video or audio file on a session. Requires `write:media`.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "size_bytes"
                ],
                "properties": {
                  "filename": {
                    "type": "string"
                  },
                  "content_type": {
                    "type": "string"
                  },
                  "size_bytes": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "403": {
            "description": "Missing write:media scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/media/upload/sign-part": {
      "post": {
        "operationId": "sign-media-upload-part",
        "summary": "Sign multipart upload parts",
        "description": "Requires `write:media`.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "upload_id",
                  "part_numbers"
                ],
                "properties": {
                  "key": {
                    "type": "string"
                  },
                  "upload_id": {
                    "type": "string"
                  },
                  "part_numbers": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Missing write:media scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/media/upload/abort": {
      "post": {
        "operationId": "abort-media-upload",
        "summary": "Abort multipart upload",
        "description": "Requires `write:media`.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "upload_id"
                ],
                "properties": {
                  "key": {
                    "type": "string"
                  },
                  "upload_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Missing write:media scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/media/upload/complete": {
      "post": {
        "operationId": "complete-media-upload",
        "summary": "Complete multipart media upload",
        "description": "Finalizes the upload and starts automatic transcription. When you upload on a session URL,\ntranscript lines appear in the session transcription list when processing finishes.\nRequires `write:media`.\n",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key",
                  "upload_id",
                  "parts",
                  "filename",
                  "size_bytes"
                ],
                "properties": {
                  "key": {
                    "type": "string"
                  },
                  "upload_id": {
                    "type": "string"
                  },
                  "parts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "part_number",
                        "etag"
                      ],
                      "properties": {
                        "part_number": {
                          "type": "integer"
                        },
                        "etag": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "filename": {
                    "type": "string"
                  },
                  "size_bytes": {
                    "type": "integer"
                  },
                  "duration_seconds": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          },
          "403": {
            "description": "Missing write:media scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/media/{mediaItemId}": {
      "get": {
        "operationId": "get-media-item",
        "summary": "Get media item status",
        "description": "Check upload and transcription progress after completing an upload. Requires `read:media` (legacy tokens with empty scopes pass).",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "mediaItemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaItemResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing read:media scope"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/content-slots": {
      "get": {
        "operationId": "list-content-slots",
        "summary": "List upload slots",
        "description": "The files an event asks its speakers for — one slot per ask (Poster,\nPresentation, Handout, …), each with its own deadline, accepted file\ntypes and file count, in the order speakers see them. Configured by\norganizers under **Program → Settings → Files → Use upload slots**.\n\n`content_slot_id` on a [session file](/api-reference/session-files/list-files-attached-to-a-session)\npoints at one of these slots, so you can tell a poster from a deck without\nparsing filenames.\n\nRead-only. Active slots only unless `include_archived=true`. An event\nthat still uses a single file request for every session (the switch\nis off) returns an empty list. Requires `read:sessions` scope (legacy\ntokens with empty scopes pass).\n\nPass `session_id` to get only the slots that apply to one session\n(organizers can scope a slot to, say, poster-format sessions). That is\nthe list to pick a `content_slot_id` from before\n[creating a file](/api-reference/session-files/create-a-file-upload-for-a-session)\non that session.\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "name": "include_archived",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Also return archived slots (`is_active: false`). Ignored when `session_id` is set — an archived slot never applies to a session."
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Return only the active slots that apply to this session, in the\norder its speakers see them. `404` if the session is not on the\nevent.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentSlotListResponse"
                },
                "examples": {
                  "two-slots": {
                    "summary": "A poster and a presentation ask",
                    "value": {
                      "data": [
                        {
                          "id": "2783cb27-958a-4a24-89d9-2d71387f04cc",
                          "name": "Poster",
                          "content_type": "poster",
                          "description": "Upload your poster as a single-page PDF.",
                          "due_date": null,
                          "due_date_extended": null,
                          "allowed_file_types": [
                            "pdf"
                          ],
                          "required": true,
                          "min_files": null,
                          "max_files": 1,
                          "allow_after_deadline": false,
                          "order": 0,
                          "is_active": true,
                          "created_at": "2026-10-02T12:04:11.000Z",
                          "updated_at": "2026-10-02T19:48:30.000Z"
                        },
                        {
                          "id": "9a1c6f0e-4a0b-4a4e-8e3f-0c2b1d5e7f90",
                          "name": "Presentation",
                          "content_type": "presentation",
                          "description": null,
                          "due_date": "2026-08-30T21:15:00.000Z",
                          "due_date_extended": null,
                          "allowed_file_types": [
                            "word",
                            "pdf"
                          ],
                          "required": false,
                          "min_files": null,
                          "max_files": 1,
                          "allow_after_deadline": false,
                          "order": 1,
                          "is_active": true,
                          "created_at": "2026-10-02T12:04:11.000Z",
                          "updated_at": "2026-10-02T12:04:11.000Z"
                        }
                      ]
                    }
                  },
                  "single-request": {
                    "summary": "Event still on a single file request",
                    "value": {
                      "data": []
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Missing read:sessions scope"
          },
          "404": {
            "description": "Event not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/files": {
      "get": {
        "operationId": "list-session-files",
        "summary": "List files attached to a session",
        "description": "Returns completed files on the session (latest version per file group).\nIncomplete uploads (create/replace without complete) are omitted.\nEach file carries `content_slot_id` — the [upload slot](/api-reference/session-files/list-upload-slots)\nit answers — once the event uses upload slots; `null` otherwise.\nRequires `read:sessions` scope (legacy tokens with empty scopes pass).\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only return files of these types. `type` is the organizer-facing\nfile type (`presentation`, `handout`, `poster`, `holding_slide`, …).\nPass one value, a comma-separated list, or repeat the parameter\n(`?type=holding_slide&type=handout`). Values are matched\ncase-insensitively; at most 20 values per request. A value with\ncharacters other than letters, digits, `_` and `-` answers `400`.\n",
            "schema": {
              "type": "string"
            },
            "examples": {
              "holdingSlide": {
                "summary": "Generated holding slides only",
                "value": "holding_slide"
              },
              "several": {
                "summary": "Several types",
                "value": "presentation,handout"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed `type` filter"
          },
          "403": {
            "description": "Missing read:sessions scope"
          },
          "404": {
            "description": "Session not found"
          }
        }
      },
      "post": {
        "operationId": "create-session-file",
        "summary": "Initiate session file upload",
        "description": "Creates a file record and returns a short-lived S3 upload URL.\nRequires `write:sessions`.\n\nNext: `PUT` the file bytes to `data.upload.url`, then call\n`POST .../files/{fileId}/complete`. For files up to **50 MB**, prefer\n`POST .../files/upload` (one multipart call). This direct-to-storage\npath supports up to **500 MB**.\nSee [Uploading session files](/guides/uploading-session-files).\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionFileCreateRequest"
              },
              "examples": {
                "powerpoint": {
                  "summary": "PowerPoint slides",
                  "value": {
                    "filename": "keynote-slides.pptx",
                    "size_bytes": 2457600,
                    "content_type": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                    "title": "Keynote slides"
                  }
                },
                "pdf": {
                  "summary": "PDF handout",
                  "value": {
                    "filename": "handout.pdf",
                    "size_bytes": 512000,
                    "content_type": "application/pdf",
                    "title": "Session handout"
                  }
                },
                "posterSlot": {
                  "summary": "Poster into the event's Poster slot",
                  "value": {
                    "filename": "poster.pdf",
                    "size_bytes": 3145728,
                    "content_type": "application/pdf",
                    "title": "Poster",
                    "content_slot_id": "2783cb27-958a-4a24-89d9-2d71387f04cc"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — upload URL included",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error (missing fields, oversize, denied type, or a `content_slot_id` that is inactive, does not apply to the session, rejects the file type or is full)"
          },
          "403": {
            "description": "Missing write:sessions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/files/upload": {
      "post": {
        "operationId": "upload-session-file",
        "summary": "Upload a session file (simple)",
        "description": "Upload a file in one multipart request. Sessionboard detects size and\nMIME type from the bytes, runs security scanning, and returns the\nfinalized file. Max **50 MB**. Requires `write:sessions`.\n\nFor files larger than 50 MB (up to 500 MB), use the direct-to-storage\nflow: `POST .../files` → PUT to signed URL → `POST .../complete`.\nSee [Uploading session files](/guides/uploading-session-files).\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file to attach (field name must be `file`)."
                  },
                  "title": {
                    "type": "string",
                    "description": "Display title. Defaults to the uploaded filename."
                  },
                  "assigned_participant_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Contact UUID of a session participant."
                  },
                  "content_slot_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional [upload slot](/api-reference/session-files/list-upload-slots)\nthis file answers. Same rules as `content_slot_id` on\n`POST .../files`: the slot must be active, apply to the\nsession, accept the file's type and have room; `400`\nnames the slot otherwise. Sets the file's `type`.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — file attached and scanned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error (missing file, oversize, denied type)"
          },
          "403": {
            "description": "Missing write:sessions scope"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/files/{fileId}/complete": {
      "post": {
        "operationId": "complete-session-file",
        "summary": "Finalize session file upload",
        "description": "Verifies the object in Sessionboard storage, runs security scanning\n(type deny-list + magic-byte checks; SVG sanitization when applicable),\nand finalizes the file on the session. Requires `write:sessions`.\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Upload missing, empty, or failed security checks"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "File not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/files/{fileId}/replace": {
      "post": {
        "operationId": "replace-session-file",
        "summary": "Replace session file bytes",
        "description": "Issues a new upload URL for the same file record. After `PUT`ing the new\nbytes, call `complete` again. Requires `write:sessions`. Max **500 MB**\n(direct-to-storage flow).\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionFileCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK — new upload URL included",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "File not found"
          }
        }
      }
    },
    "/v1/event/{eventId}/sessions/{sessionId}/files/{fileId}": {
      "put": {
        "operationId": "update-session-file",
        "summary": "Update session file metadata",
        "description": "Updates display title and/or assigned participant. Does not change file\nbytes — use `replace` for that. Unknown fields are ignored.\nRequires `write:sessions`.\n",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionFileUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "File not found"
          }
        }
      },
      "delete": {
        "operationId": "delete-session-file",
        "summary": "Delete a session file",
        "description": "Soft-deletes the file from the session. Requires `write:sessions`.",
        "tags": [
          "Session Files"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          },
          {
            "$ref": "#/components/parameters/SessionId"
          },
          {
            "$ref": "#/components/parameters/FileId"
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Missing write:sessions scope"
          },
          "404": {
            "description": "File not found"
          }
        }
      }
    },
    "/v1/tasks": {
      "get": {
        "operationId": "list-tasks",
        "summary": "List tasks",
        "description": "Your organization's tasks, open ones first by due date. Filters combine.\n\n- `assignee`: `me` (the API key's user), a user id, the email of a\n  member of your organization, `none` (unassigned) or `any` (everyone).\n- `due`: `overdue`, `today`, `upcoming` or `none` (no due date),\n  judged in each task's time zone. `due_from` / `due_to` bound the due\n  date (`YYYY-MM-DD`, inclusive).\n- `record_type` + `record_id`: tasks linked to that record.\n\n`counts` gives open, today, overdue, upcoming, no-date, milestone and\ncompleted totals for the same filters, ignoring `status` and `due`.\n\nTasks are read as the API key's user: a key that belongs to no user\ngets `400 USER_REQUIRED`. Needs `read:tasks`. Tasks are part of\nSessionboard Platform.\n",
        "tags": [
          "Tasks"
        ],
        "parameters": [
          {
            "name": "event_id",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Only this event's tasks."
          },
          {
            "name": "assignee",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "`me`, a user id, an email, `none` or `any`.",
            "example": "me"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "completed"
              ]
            },
            "description": "`open` (the default; includes in progress) or `completed`."
          },
          {
            "name": "due",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "overdue",
                "today",
                "upcoming",
                "none"
              ]
            },
            "description": "With no `status`, only open tasks."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "task",
                "milestone"
              ],
              "default": "task"
            }
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "low",
                "normal",
                "high",
                "urgent"
              ]
            }
          },
          {
            "name": "due_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Due on or after this date."
          },
          {
            "name": "due_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Due on or before this date."
          },
          {
            "name": "record_type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "contact",
                "session",
                "sponsor",
                "exhibitor",
                "group"
              ]
            }
          },
          {
            "name": "record_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "With `record_type`, the linked record's id."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Words in the title or description."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "due",
                "title",
                "assignee",
                "priority",
                "event",
                "created",
                "records"
              ],
              "default": "due"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "tz",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "IANA time zone that decides \"today\" for `due` and `counts`. Defaults to the key's user's time zone.",
            "example": "America/Chicago"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskList"
                },
                "examples": {
                  "overdue": {
                    "summary": "My overdue tasks",
                    "value": {
                      "data": [
                        {
                          "id": "7d1c2b8e-4f0a-4c3e-9b1d-2a6f8e0c41a1",
                          "org_id": "3f6a1c2e-8d7b-4e90-a1b2-c3d4e5f60718",
                          "event_id": 7001,
                          "event": {
                            "id": 7001,
                            "name": "Annual Meeting 2027",
                            "timezone": "America/Chicago"
                          },
                          "kind": "task",
                          "title": "Chase Dr. Okafor's disclosure",
                          "description": null,
                          "status": "open",
                          "priority": "high",
                          "assignee": {
                            "id": 4211,
                            "first_name": "Dana",
                            "last_name": "Reyes",
                            "email": "dana@example.org",
                            "photo_url": null
                          },
                          "creator": {
                            "id": 3087,
                            "first_name": "Sam",
                            "last_name": "Lee",
                            "email": "sam@example.org",
                            "photo_url": null
                          },
                          "completed_by": null,
                          "records": [
                            {
                              "type": "contact",
                              "id": "9b2e4c1a-0d3f-4a5b-8c7d-6e5f4a3b2c1d",
                              "label": "Dr. Ada Okafor",
                              "restricted": false
                            }
                          ],
                          "due_at": "2026-11-13T23:00:00.000Z",
                          "has_due_time": true,
                          "due_date": "2026-11-13",
                          "due_time": "17:00",
                          "timezone": "America/Chicago",
                          "record_type": "contact",
                          "record_id": "9b2e4c1a-0d3f-4a5b-8c7d-6e5f4a3b2c1d",
                          "parent_id": null,
                          "start_at": null,
                          "reminder": "9am",
                          "reminder_at": "2026-11-13T15:00:00.000Z",
                          "milestone": null,
                          "source": "api",
                          "source_note_id": null,
                          "completion_note": null,
                          "completed_at": null,
                          "follower_ids": [
                            3087
                          ],
                          "is_overdue": true,
                          "can_edit": true,
                          "can_delete": false,
                          "created_at": "2026-11-09T16:12:44.000Z",
                          "updated_at": "2026-11-09T16:12:44.000Z"
                        }
                      ],
                      "pagination": {
                        "total_results": 1,
                        "limit": 25,
                        "offset": 0,
                        "has_more": false
                      },
                      "counts": {
                        "open": 4,
                        "today": 0,
                        "overdue": 1,
                        "upcoming": 2,
                        "none": 1,
                        "milestones": 0,
                        "completed": 7
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "An invalid filter (`VALIDATION_ERROR`), or a key that belongs to no user (`USER_REQUIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          }
        }
      },
      "post": {
        "operationId": "create-task",
        "summary": "Create a task",
        "description": "Creates a task and tells the assignee. Without `event_id` the task\nbelongs to the whole organization.\n\n- **Assignee**: `assignee_email` or `assignee_id`; they must be a member\n  of the organization, or a user on the task's event. The task's\n  creator is the API key's user.\n- **Dates**: `due_date` (`YYYY-MM-DD`) and an optional `due_time`\n  (`HH:mm`, 24-hour) in the event's time zone. For an organization task\n  it is the assignee's time zone, else `America/New_York`. Without a\n  time the task is due at 23:59 that day and `has_due_time` is `false`.\n- **Records**: the records the task is about, each `{ type, id }`; the\n  first is the primary. Every record must be in your organization,\n  and in the task's event when the task has one.\n- **Reminder**: with a due date and no `reminder`, the assignee is\n  reminded at 09:00 on the due date (`9am`). Send `none` to skip it.\n\nUnknown fields are a `400`. `source` is `api`. Needs `write:tasks`.\n",
        "tags": [
          "Tasks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskCreate"
              },
              "examples": {
                "followUp": {
                  "summary": "Remind Dana to chase a disclosure by Friday",
                  "value": {
                    "event_id": 7001,
                    "title": "Chase Dr. Okafor's disclosure",
                    "records": [
                      {
                        "type": "contact",
                        "id": "9b2e4c1a-0d3f-4a5b-8c7d-6e5f4a3b2c1d"
                      }
                    ],
                    "assignee_email": "dana@example.org",
                    "due_date": "2026-11-20",
                    "reminder": "9am",
                    "priority": "high"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "A missing title, a bad date or time, an unknown reminder or field, an assignee who cannot be assigned, a record outside your organization or the event (`VALIDATION_ERROR`), or a key that belongs to no user (`USER_REQUIRED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          }
        }
      }
    },
    "/v1/tasks/{taskId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/TaskId"
        }
      ],
      "get": {
        "operationId": "get-task",
        "summary": "Get a task",
        "description": "One task. Needs `read:tasks`.",
        "tags": [
          "Tasks"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          },
          "404": {
            "description": "No such task, or the key's user cannot read it (`NOT_FOUND`)."
          }
        }
      },
      "patch": {
        "operationId": "update-task",
        "summary": "Update a task",
        "description": "Changes only the fields you send; `null` clears a field. `records`\nreplaces the list. Changing the due date or time, the reminder or the\nassignee recomputes the reminder. When someone other than the assignee\nchanges the due date, reassigns or retitles a task, the assignee is told.\n\nThe assignee, the creator, a follower or an admin can update a task.\nNeeds `write:tasks`.\n",
        "tags": [
          "Tasks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskUpdate"
              },
              "examples": {
                "reschedule": {
                  "summary": "Move it to Monday at 2 pm",
                  "value": {
                    "due_date": "2026-11-23",
                    "due_time": "14:00"
                  }
                },
                "reassign": {
                  "summary": "Hand it to someone else",
                  "value": {
                    "assignee_email": "priya@example.org"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "Invalid field values.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          },
          "404": {
            "description": "No such task, or the key's user cannot read it (`NOT_FOUND`)."
          }
        }
      },
      "delete": {
        "operationId": "delete-task",
        "summary": "Delete a task",
        "description": "Deletes a task. The creator or an admin can delete one. Needs `write:tasks`.",
        "tags": [
          "Tasks"
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "7d1c2b8e-4f0a-4c3e-9b1d-2a6f8e0c41a1",
                    "deleted": true
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          },
          "404": {
            "description": "No such task, or the key's user cannot read it (`NOT_FOUND`)."
          }
        }
      }
    },
    "/v1/tasks/{taskId}/complete": {
      "parameters": [
        {
          "$ref": "#/components/parameters/TaskId"
        }
      ],
      "post": {
        "operationId": "complete-task",
        "summary": "Complete a task",
        "description": "Marks a task done, with an optional short reply in `completion_note`.\nPending reminders are cancelled, and the creator and followers are told\n(not the person who completed it). Needs `write:tasks`.\n",
        "tags": [
          "Tasks"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "completion_note": {
                    "type": "string",
                    "description": "A short reply, shown with the completed task."
                  }
                }
              },
              "example": {
                "completion_note": "Forms received"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          },
          "404": {
            "description": "No such task, or the key's user cannot read it (`NOT_FOUND`)."
          }
        }
      }
    },
    "/v1/tasks/{taskId}/reopen": {
      "parameters": [
        {
          "$ref": "#/components/parameters/TaskId"
        }
      ],
      "post": {
        "operationId": "reopen-task",
        "summary": "Reopen a task",
        "description": "Reopens a completed task. Its reminder is re-armed when it is still in\nthe future. Needs `write:tasks`.\n",
        "tags": [
          "Tasks"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TasksForbidden"
          },
          "404": {
            "description": "No such task, or the key's user cannot read it (`NOT_FOUND`)."
          }
        }
      }
    },
    "/v1/products": {
      "get": {
        "operationId": "get-products",
        "summary": "List the products your organization owns",
        "description": "What your organization owns, so an integration or an AI assistant can\ntell a self-serve workspace from a Platform customer and show the right\nproducts. Read-only.\n\nOne entry per product, always in this order: `platform`, `sessions`,\n`crm`, `awards`, `learning`, `marketing`.\n\n- `owned`: the organization can open the product now.\n- `via`: `self_serve` (a self-serve plan or trial), `platform` (your\n  Platform contract includes it) or `null` when not owned.\n- `days_left`: whole days left on a self-serve trial, otherwise `null`.\n\n`platform_customer` is `true` for an organization with a Platform\ncontract (including every organization created before the self-serve\nproducts). Any `read:*` scope is enough; the answer is the\norganization's, the same for every key.\n",
        "tags": [
          "Products"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationProducts"
                },
                "examples": {
                  "selfServe": {
                    "summary": "A self-serve workspace (Marketing on a trial)",
                    "value": {
                      "apps": [
                        {
                          "key": "platform",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "sessions",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "crm",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "awards",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "learning",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "marketing",
                          "owned": true,
                          "via": "self_serve",
                          "days_left": 9
                        }
                      ],
                      "platform_customer": false
                    }
                  },
                  "platform": {
                    "summary": "A Platform customer whose contract includes Awards",
                    "value": {
                      "apps": [
                        {
                          "key": "platform",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "sessions",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "crm",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "awards",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "learning",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "marketing",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        }
                      ],
                      "platform_customer": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The key has no `read:*` scope (`SCOPE_REQUIRED`)"
          }
        }
      }
    },
    "/v1/organization/{orgId}/products": {
      "get": {
        "operationId": "get-organization-products",
        "summary": "List the products an organization owns",
        "description": "The same as `GET /v1/products`, with the organization in the path.\nAny other organization returns `404`.\n",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Your organization ID."
          }
        ],
        "tags": [
          "Products"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationProducts"
                },
                "examples": {
                  "selfServe": {
                    "summary": "A self-serve workspace (Marketing on a trial)",
                    "value": {
                      "apps": [
                        {
                          "key": "platform",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "sessions",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "crm",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "awards",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "learning",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "marketing",
                          "owned": true,
                          "via": "self_serve",
                          "days_left": 9
                        }
                      ],
                      "platform_customer": false
                    }
                  },
                  "platform": {
                    "summary": "A Platform customer whose contract includes Awards",
                    "value": {
                      "apps": [
                        {
                          "key": "platform",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "sessions",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "crm",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "awards",
                          "owned": true,
                          "via": "platform",
                          "days_left": null
                        },
                        {
                          "key": "learning",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        },
                        {
                          "key": "marketing",
                          "owned": false,
                          "via": null,
                          "days_left": null
                        }
                      ],
                      "platform_customer": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "The key has no `read:*` scope (`SCOPE_REQUIRED`)"
          },
          "404": {
            "description": "Another organization's `orgId` (`NOT_FOUND`)"
          }
        }
      }
    },
    "/v1/logs/api-requests": {
      "get": {
        "operationId": "list-log-api-requests",
        "summary": "List API request logs",
        "description": "Every request made to this Public API, the MCP server and Insights with your\norganization's credentials, including requests rejected at authentication\nwhen the credential can be tied to your organization (`reason` carries\n`revoked_token`, `expired_token`, `org_archived`, `member_inactive`,\n`owner_inactive`, `ai_disabled`, `log_export_only`, `cross_org_event` or\n`event_not_allowed`). A request with no key or with a key Sessionboard\ndoes not recognize belongs to no organization and is not exported.\nKept for 365 days.\nRequest bodies are omitted unless you ask for them with `include=request_body`.\n",
        "tags": [
          "Log Export"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LogCursor"
          },
          {
            "$ref": "#/components/parameters/LogSince"
          },
          {
            "$ref": "#/components/parameters/LogLimit"
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "success",
                "failure"
              ]
            },
            "description": "Only successful or only failed events."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "public-api",
                "mcp",
                "insights"
              ]
            },
            "description": "Only requests that arrived through one surface."
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "request_body"
              ]
            },
            "description": "Add the logged request body to `details.request_body`."
          }
        ],
        "responses": {
          "200": {
            "description": "One page of events, oldest first.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogPage"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` for a bad parameter; `INVALID_CURSOR` for a cursor that is malformed or was issued for another stream or organization;\n`CURSOR_FILTER_MISMATCH` when the filters differ from the ones the cursor was issued with;\n`SINCE_BEFORE_RETENTION` when `since` is older than the stream keeps.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired API token."
          },
          "403": {
            "description": "The token does not hold `read:audit_logs`, or it is an OAuth token. Log export accepts API tokens only."
          },
          "410": {
            "description": "`CURSOR_EXPIRED` — the cursor points before the start of retention. Restart from `since`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. 60 requests per minute per token; honor `Retry-After`."
          }
        }
      }
    },
    "/v1/logs/security-events": {
      "get": {
        "operationId": "list-log-security-events",
        "summary": "List security events",
        "description": "Sign-ins, sign-in failures, two-factor and passkey events, password resets and\nsession changes for the people in your organization. Covers events recorded\nagainst the organization and those of its current members.\nSessionboard staff activity is not included. No retention limit.\n",
        "tags": [
          "Log Export"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LogCursor"
          },
          {
            "$ref": "#/components/parameters/LogSince"
          },
          {
            "$ref": "#/components/parameters/LogLimit"
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "success",
                "failure"
              ]
            },
            "description": "Only successful or only failed events."
          }
        ],
        "responses": {
          "200": {
            "description": "One page of events, oldest first.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogPage"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` for a bad parameter; `INVALID_CURSOR` for a cursor that is malformed or was issued for another stream or organization;\n`CURSOR_FILTER_MISMATCH` when the filters differ from the ones the cursor was issued with;\n`SINCE_BEFORE_RETENTION` when `since` is older than the stream keeps.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired API token."
          },
          "403": {
            "description": "The token does not hold `read:audit_logs`, or it is an OAuth token. Log export accepts API tokens only."
          },
          "410": {
            "description": "`CURSOR_EXPIRED` — the cursor points before the start of retention. Restart from `since`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. 60 requests per minute per token; honor `Retry-After`."
          }
        }
      }
    },
    "/v1/logs/audit-trail": {
      "get": {
        "operationId": "list-log-audit-trail",
        "summary": "List audit trail",
        "description": "Every recorded change to your organization's data — who changed which record,\nwhich property, and (by default) the new value. `action` is\n`<subject_type>.<operation>`, for example `session.update`. No retention limit.\n",
        "tags": [
          "Log Export"
        ],
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LogCursor"
          },
          {
            "$ref": "#/components/parameters/LogSince"
          },
          {
            "$ref": "#/components/parameters/LogLimit"
          },
          {
            "name": "subject_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "session,contact"
            },
            "description": "Comma-separated record types to include, for example `session,contact`."
          },
          {
            "name": "include_values",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Set `false` to omit changed values (`details.value`) — useful when the SIEM must not hold personal data."
          }
        ],
        "responses": {
          "200": {
            "description": "One page of events, oldest first.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogPage"
                }
              }
            }
          },
          "400": {
            "description": "`VALIDATION_ERROR` for a bad parameter; `INVALID_CURSOR` for a cursor that is malformed or was issued for another stream or organization;\n`CURSOR_FILTER_MISMATCH` when the filters differ from the ones the cursor was issued with;\n`SINCE_BEFORE_RETENTION` when `since` is older than the stream keeps.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired API token."
          },
          "403": {
            "description": "The token does not hold `read:audit_logs`, or it is an OAuth token. Log export accepts API tokens only."
          },
          "410": {
            "description": "`CURSOR_EXPIRED` — the cursor points before the start of retention. Restart from `since`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogExportError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. 60 requests per minute per token; honor `Retry-After`."
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs": {
      "get": {
        "operationId": "list-awards-programs",
        "summary": "List programs",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/AwardsPageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsProgram"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/create": {
      "post": {
        "operationId": "create-awards-program",
        "summary": "Create a program",
        "description": "Creates the program with its submission form, a default round, and the token owner as program manager — the same as creating it in the admin app. Counts against the plan's Awards program limit. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AwardsProgramWrite"
                  }
                ],
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Program created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsProgram"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Your plan allows 3 Awards programs (403 also means the token lacks `write:awards`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "FORBIDDEN",
                  "message": "Your plan allows 3 Awards programs (403 also means the token lacks `write:awards`)"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}": {
      "get": {
        "operationId": "get-awards-program",
        "summary": "Get a program",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsProgram"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ]
      },
      "put": {
        "operationId": "update-awards-program",
        "summary": "Update a program",
        "description": "Fields you omit keep their stored value. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsProgramWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Program updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsProgram"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch-awards-program",
        "summary": "Update a program (PATCH)",
        "description": "Fields you omit keep their stored value. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsProgramWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Program updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsProgram"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-program",
        "summary": "Delete a program",
        "description": "Soft-deletes the program (it moves to Trash and can be restored in the admin app). A program that has submissions returns `409` unless `force=true` is sent — the API equivalent of the admin app's confirmation dialog. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsForce"
          }
        ],
        "responses": {
          "204": {
            "description": "Program deleted"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Program has 12 submissions; send force=true to delete it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Program has 12 submissions; send force=true to delete it"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/categories": {
      "get": {
        "operationId": "list-awards-categorys",
        "summary": "List categorys",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/AwardsPageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsCategory"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/categories/create": {
      "post": {
        "operationId": "create-awards-category",
        "summary": "Create a category",
        "description": "Set `parent_category_id` to another category in the same program to create a subcategory. `order` defaults to the end of the list. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AwardsCategoryWrite"
                  }
                ],
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Category created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsCategory"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/categories/{categoryId}": {
      "get": {
        "operationId": "get-awards-category",
        "summary": "Get a category",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsCategory"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "categoryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The category ID."
          }
        ]
      },
      "put": {
        "operationId": "update-awards-category",
        "summary": "Update a category",
        "description": "A parent in another program, the category itself, or one of its own subcategories returns `400`. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "categoryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The category ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsCategoryWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Category updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsCategory"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch-awards-category",
        "summary": "Update a category (PATCH)",
        "description": "A parent in another program, the category itself, or one of its own subcategories returns `400`. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "categoryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The category ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsCategoryWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Category updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsCategory"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-category",
        "summary": "Delete a category",
        "description": "Soft-deletes the category. One with subcategories returns `409` unless `cascade=true` is sent, which deletes the whole subtree. One that submissions are filed under (directly or through a subcategory) also returns `409` unless `force=true` is sent. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "categoryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The category ID."
          },
          {
            "$ref": "#/components/parameters/AwardsCascade"
          },
          {
            "$ref": "#/components/parameters/AwardsForce"
          }
        ],
        "responses": {
          "204": {
            "description": "Category deleted"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Category has 2 subcategories; send cascade=true to delete them too",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Category has 2 subcategories; send cascade=true to delete them too"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/rounds": {
      "get": {
        "operationId": "list-awards-rounds",
        "summary": "List rounds",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/AwardsPageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsRound"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/rounds/create": {
      "post": {
        "operationId": "create-awards-round",
        "summary": "Create a round",
        "description": "Adds a review round to the program. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AwardsRoundWrite"
                  }
                ],
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Round created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsRound"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/rounds/{roundId}": {
      "get": {
        "operationId": "get-awards-round",
        "summary": "Get a round",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsRound"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "roundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The round ID."
          }
        ]
      },
      "put": {
        "operationId": "update-awards-round",
        "summary": "Update a round",
        "description": "Fields you omit keep their stored value. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "roundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The round ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsRoundWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Round updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsRound"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch-awards-round",
        "summary": "Update a round (PATCH)",
        "description": "Fields you omit keep their stored value. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "roundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The round ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsRoundWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Round updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsRound"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-round",
        "summary": "Delete a round",
        "description": "Soft-deletes the round and moves its submissions back to the previous round, as the admin app does. The program's default (first) round cannot be deleted and returns `422`. A round with reviewer assignments returns `409` unless `force=true` is sent. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "roundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The round ID."
          },
          {
            "$ref": "#/components/parameters/AwardsForce"
          }
        ],
        "responses": {
          "204": {
            "description": "Round deleted"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Round has 8 reviewer assignments; send force=true to delete it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Round has 8 reviewer assignments; send force=true to delete it"
                }
              }
            }
          },
          "422": {
            "description": "The default round cannot be deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "The default round cannot be deleted"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/promo-codes": {
      "get": {
        "operationId": "list-awards-promo-codes",
        "summary": "List promo codes",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/AwardsPageSize"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsPromoCode"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/promo-codes/create": {
      "post": {
        "operationId": "create-awards-promo-code",
        "summary": "Create a promo code",
        "description": "Codes are stored upper-case and must be unique within the program. A `percentage` amount above 100 returns `400`; `percentage` 100 waives the fee entirely. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AwardsPromoCodeWrite"
                  }
                ],
                "required": [
                  "code",
                  "type",
                  "amount"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Promo code created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsPromoCode"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Promo code SAVE20 already exists in this program",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Promo code SAVE20 already exists in this program"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/promo-codes/{promoCodeId}": {
      "get": {
        "operationId": "get-awards-promo-code",
        "summary": "Get a promo code",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsPromoCode"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "promoCodeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The promo code ID."
          }
        ]
      },
      "put": {
        "operationId": "update-awards-promo-code",
        "summary": "Update a promo code",
        "description": "Renaming to a code already used in the program returns `409`. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "promoCodeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The promo code ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsPromoCodeWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Promo code updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsPromoCode"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Promo code SAVE20 already exists in this program",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Promo code SAVE20 already exists in this program"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch-awards-promo-code",
        "summary": "Update a promo code (PATCH)",
        "description": "Renaming to a code already used in the program returns `409`. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "promoCodeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The promo code ID."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsPromoCodeWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Promo code updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsPromoCode"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Promo code SAVE20 already exists in this program",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Promo code SAVE20 already exists in this program"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-promo-code",
        "summary": "Delete a promo code",
        "description": "Soft-deletes the code. A code already applied to a submission returns `409` unless `force=true` is sent; those submissions keep their discount. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "name": "promoCodeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The promo code ID."
          },
          {
            "$ref": "#/components/parameters/AwardsForce"
          }
        ],
        "responses": {
          "204": {
            "description": "Promo code deleted"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          },
          "409": {
            "description": "Promo code has been redeemed 3 times; send force=true to delete it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "CONFLICT",
                  "message": "Promo code has been redeemed 3 times; send force=true to delete it"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/submissions": {
      "get": {
        "operationId": "list-awards-submissions",
        "summary": "List submissions",
        "description": "Lists top-level submissions (merged duplicates are folded into their primary). Submissions are created by submitters through the program's portal, not through the API. Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/AwardsPageSize"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only submissions in this status, e.g. `submitted`."
          },
          {
            "name": "category_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "current_round_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsSubmission"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/ListPagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/submissions/{submissionId}": {
      "get": {
        "operationId": "get-awards-submission",
        "summary": "Get a submission",
        "description": "Includes `values`, the form answers keyed by form field ID. Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsSubmission"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          }
        ]
      },
      "put": {
        "operationId": "update-awards-submission",
        "summary": "Update a submission",
        "description": "Writes answers to the submission form, keyed by form field ID, with the same required-field checks and edit history as an admin edit. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsSubmissionWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Submission updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsSubmission"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "patch-awards-submission",
        "summary": "Update a submission (PATCH)",
        "description": "Writes answers to the submission form, keyed by form field ID, with the same required-field checks and edit history as an admin edit. `PUT` and `PATCH` behave the same: send only the fields you are changing. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AwardsSubmissionWrite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Submission updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsSubmission"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "VALIDATION_ERROR",
                  "message": "\"name\" is not allowed to be empty"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-submission",
        "summary": "Delete a submission",
        "description": "Soft-deletes the submission (it moves to Trash and can be restored in the admin app). Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          }
        ],
        "responses": {
          "204": {
            "description": "Submission deleted"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/submissions/{submissionId}/reviews": {
      "get": {
        "operationId": "list-awards-reviews",
        "summary": "List reviews",
        "description": "One entry per reviewer assigned to the submission, with their scores. Reviews are written by reviewers in the review portal, not through the API. Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AwardsReview"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/awards/programs/{programId}/submissions/{submissionId}/reviews/{reviewId}": {
      "get": {
        "operationId": "get-awards-review",
        "summary": "Get a review",
        "description": "Requires the `read:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          },
          {
            "name": "reviewId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The review (reviewer assignment) ID."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AwardsReview"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `read:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: read:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-awards-review",
        "summary": "Remove a review",
        "description": "Unassigns the reviewer from the submission for that round and removes their scores, as unassigning in the admin app does. Requires the `write:awards` scope.",
        "tags": [
          "Awards"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AwardsOrgId"
          },
          {
            "$ref": "#/components/parameters/AwardsProgramId"
          },
          {
            "$ref": "#/components/parameters/AwardsSubmissionId"
          },
          {
            "name": "reviewId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The review (reviewer assignment) ID."
          }
        ],
        "responses": {
          "204": {
            "description": "Review removed"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Token lacks `write:awards`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:awards"
                }
              }
            }
          },
          "404": {
            "description": "Not found — also returned for any id belonging to another organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AwardsError"
                },
                "example": {
                  "error": "NOT_FOUND",
                  "message": "Not found"
                }
              }
            }
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/media": {
      "get": {
        "operationId": "list-learning-media",
        "summary": "List videos a course can be made from",
        "description": "Media-section recordings, uploads and clips, newest first. A course is written from what is said, so only items with `has_transcript: true` can be used (a clip uses its recording's transcript). Requires `read:learning`. Also served at `GET /v1/learning/media` with the organization taken from the token.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "video",
                "clip"
              ]
            },
            "description": "`video` for recordings and uploads, `clip` for clips cut from them. Omit for both."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Words from the title."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payload": {
                      "type": "object",
                      "properties": {
                        "media": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/LearningMedia"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/library": {
      "get": {
        "operationId": "get-learning-library",
        "summary": "List lessons and courses",
        "description": "The organization's lessons and courses (series), with ids and external keys — what an assignment can target. Requires `read:learning`. Also at `GET /v1/learning/library`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          }
        ],
        "responses": {
          "200": {
            "description": "`payload.lessons[]` and `payload.courses[]`."
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/drafts": {
      "get": {
        "operationId": "list-course-drafts",
        "summary": "List course drafts",
        "description": "Course drafts made from videos, newest first. Requires `read:learning`. Also at `GET /v1/learning/drafts`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payload": {
                      "type": "object",
                      "properties": {
                        "drafts": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/CourseDraftSummary"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/drafts/create": {
      "post": {
        "operationId": "create-course-draft",
        "summary": "Draft a course from videos",
        "description": "Starts making a course from 1–10 videos or clips. The videos are checked now (same organization, a transcript, no cuts); then the course is generated in the background: lesson-sized segments, a clip cut for each, and per lesson a short reading, in-video questions and a quiz, every question grounded in that clip's transcript. Answers `202` with the draft (`status: queued`); poll `GET /v1/organization/{orgId}/learning/drafts/{draftId}` until `status` is `ready` or `failed` (usually a minute or two per video). Nothing is published and no one is notified. Requires `write:learning`. Also at `POST /v1/learning/drafts/create`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mediaItemIds"
                ],
                "properties": {
                  "mediaItemIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Videos / clips from List videos, in course order."
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Course title. Defaults to the video's title when there is one video."
                  },
                  "audience": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Who the course is for. Shapes the writing; it does not decide who is assigned."
                  },
                  "certification": {
                    "type": "boolean",
                    "description": "Add a certification earned by completing every lesson."
                  },
                  "validityMonths": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 120,
                    "description": "How long the certification lasts. Omit for never expires."
                  },
                  "questionTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "multiple_choice",
                        "true_false",
                        "short_answer",
                        "multi_select",
                        "ordering",
                        "matching",
                        "numeric"
                      ]
                    },
                    "description": "Default `multiple_choice`, `true_false`, `multi_select`."
                  },
                  "checkpointsPerLesson": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 3,
                    "description": "Questions that pause the video, per lesson. Default 2."
                  },
                  "quizQuestions": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "description": "Final quiz questions per lesson. Default 4."
                  },
                  "maxLessonsPerVideo": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 12,
                    "description": "Upper bound on lessons from one long video, default 8. Exceeded only when fewer lessons would each run past 10 minutes."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payload": {
                      "type": "object",
                      "properties": {
                        "draft": {
                          "$ref": "#/components/schemas/CourseDraftSummary"
                        },
                        "poll": {
                          "type": "string",
                          "description": "Internal path of the draft; poll the Get a course draft operation."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A video is not in this organization, has no transcript, or has cuts."
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/drafts/{draftId}": {
      "get": {
        "operationId": "get-course-draft",
        "summary": "Get a course draft",
        "description": "While generating: `status` and `progress`. When `ready`: the `bundle` (lessons, the course, the certification), the `diff` publishing would make, `warnings` (questions left out because the clip doesn't answer them) and `media` — per clip, its `status` and a short-lived playable `url`. Requires `read:learning`. Also at `GET /v1/learning/drafts/{draftId}`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          },
          {
            "$ref": "#/components/parameters/CourseDraftId"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payload": {
                      "type": "object",
                      "properties": {
                        "draft": {
                          "$ref": "#/components/schemas/CourseDraft"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          },
          "404": {
            "description": "Not found — also returned for another organization's draft."
          }
        }
      },
      "put": {
        "operationId": "update-course-draft",
        "summary": "Save edits to a course draft",
        "description": "Replaces the draft's bundle with your edited copy (send the whole bundle — anything left out is dropped) and returns the draft with a fresh `diff`. Pass the draft's `updated_at` from the read you edited as `baseUpdatedAt`: if the draft changed since, the save answers `409` with `code: COURSE_DRAFT_STALE` and writes nothing. Requires `write:learning`. Also at `PUT /v1/learning/drafts/{draftId}`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          },
          {
            "$ref": "#/components/parameters/CourseDraftId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "bundle"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "baseUpdatedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "bundle": {
                    "$ref": "#/components/schemas/CourseBundle"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved; the draft as in Get a course draft."
          },
          "400": {
            "description": "The bundle failed validation (the message names the lesson and question)."
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          },
          "409": {
            "description": "The draft changed since `baseUpdatedAt` (`code: COURSE_DRAFT_STALE`, with the current `updated_at`)."
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/drafts/{draftId}/apply": {
      "post": {
        "operationId": "apply-course-draft",
        "summary": "Publish and assign a course draft",
        "description": "Publishes the draft's lessons, course and certification to every learner in the organization. Lessons upsert by key, so publishing an edited draft again updates the same lessons and keeps learners' progress. With `assign`, assigns the certification (or the course when there is none) and messages each assignee (Slack DM, or email when Slack can't reach them); repeating the same `assign` does not assign or message again. With `announce.slackChannelId`, posts the announcement in that channel. Refused while clips are still being cut unless `allowPendingMedia`. The token's user needs the Lessons create and update permissions. Requires `write:learning`. Also at `POST /v1/learning/drafts/{draftId}/apply`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          },
          {
            "$ref": "#/components/parameters/CourseDraftId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "assign": {
                    "type": "object",
                    "properties": {
                      "allTeam": {
                        "type": "boolean",
                        "description": "Everyone on the team, including people who join later."
                      },
                      "userIds": {
                        "type": "array",
                        "items": {
                          "type": "integer"
                        }
                      },
                      "dueInDays": {
                        "type": [
                          "integer",
                          "null"
                        ],
                        "minimum": 1,
                        "maximum": 365
                      },
                      "required": {
                        "type": "boolean",
                        "default": true
                      }
                    }
                  },
                  "announce": {
                    "type": "object",
                    "properties": {
                      "slackChannelId": {
                        "type": "string",
                        "maxLength": 32
                      }
                    }
                  },
                  "allowPendingMedia": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Published; the draft with `apply_result` (`diff`, the assignment and its delivery report)."
          },
          "400": {
            "description": "A clip could not be cut, or there is nothing to assign."
          },
          "403": {
            "description": "Token lacks `write:learning`, the user lacks the Lessons permissions, clips are still being cut, or the draft changed or is being published (reload it)."
          }
        }
      }
    },
    "/v1/organization/{orgId}/learning/assignments/create": {
      "post": {
        "operationId": "create-learning-assignment",
        "summary": "Assign a certification, course or lesson",
        "description": "Assigns already-published training to the whole team or named teammates and messages each of them. Requires `write:learning`. Also at `POST /v1/learning/assignments/create`.",
        "tags": [
          "Learning"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LearningOrgId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetKind",
                  "targetId",
                  "audience"
                ],
                "properties": {
                  "targetKind": {
                    "type": "string",
                    "enum": [
                      "certification",
                      "series",
                      "lesson"
                    ],
                    "description": "`series` is a course."
                  },
                  "targetId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "audience": {
                    "type": "object",
                    "properties": {
                      "allTeam": {
                        "type": "boolean"
                      },
                      "userIds": {
                        "type": "array",
                        "items": {
                          "type": "integer"
                        }
                      }
                    }
                  },
                  "dueInDays": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 365
                  },
                  "required": {
                    "type": "boolean"
                  },
                  "slackChannelId": {
                    "type": "string",
                    "maxLength": 32
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Assigned; `payload.assignment` and `payload.delivery` (who was messaged, and how)."
          },
          "403": {
            "$ref": "#/components/responses/LearningForbidden"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-access-token",
        "description": "Organization API token. Generate from Organization Settings → API Tokens."
      },
      "BearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "OAuth 2.1 access token. Obtained via the OAuth PKCE flow at `/oauth/token`."
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Requests allowed in the current window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Requests left in the current window.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "parameters": {
      "SharingEventId": {
        "name": "eventId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "integer"
        },
        "description": "The webinar's event id."
      },
      "TaskId": {
        "name": "taskId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "The task's `id`."
      },
      "LearningOrgId": {
        "name": "orgId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Your organization ID. Any other organization returns `404`."
      },
      "CourseDraftId": {
        "name": "draftId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "AwardsOrgId": {
        "name": "orgId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Your organization ID. Any other organization returns `404`."
      },
      "AwardsProgramId": {
        "name": "programId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "The Awards program ID."
      },
      "AwardsSubmissionId": {
        "name": "submissionId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "The submission ID."
      },
      "AwardsPageSize": {
        "name": "pageSize",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        },
        "description": "Results per page. `page_size` is also accepted."
      },
      "AwardsForce": {
        "name": "force",
        "in": "query",
        "required": false,
        "schema": {
          "type": "boolean",
          "default": false
        },
        "description": "Delete even though the record is in use (see the `409` response)."
      },
      "AwardsCascade": {
        "name": "cascade",
        "in": "query",
        "required": false,
        "schema": {
          "type": "boolean",
          "default": false
        },
        "description": "Also delete the category's subcategories."
      },
      "LogCursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 2048
        },
        "description": "`next_cursor` from the previous page. Store it after each page and send it back unchanged;\nit remembers your filters, so repeat the same filters with it.\n"
      },
      "LogSince": {
        "name": "since",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date-time"
        },
        "description": "Where to start when you have no cursor. Defaults to 24 hours ago. Ignored when `cursor` is sent."
      },
      "LogLimit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000,
          "default": 500
        },
        "description": "Events per page."
      },
      "EventId": {
        "name": "eventId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "integer"
        },
        "description": "Event ID"
      },
      "SessionId": {
        "name": "sessionId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Session UUID"
      },
      "FileId": {
        "name": "fileId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Session file (Content) UUID"
      },
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 999,
          "default": 1
        },
        "description": "Page number for pagination."
      },
      "PageSize": {
        "name": "pageSize",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        },
        "description": "Number of results per page.\n\nThe event-settings list endpoints (tags, tracks, levels, formats,\nrooms, languages, statuses) also accept the older spelling\n`page_size`, and used to accept only that — a request sending\n`pageSize` silently got the default 25. Both now work, `pageSize`\nwins when both are sent, and on these endpoints a value outside\n1–100 is clamped rather than rejected. Everywhere else `pageSize`\nis the only spelling.\n"
      },
      "Expand": {
        "name": "expand",
        "in": "query",
        "required": false,
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "translated_fields",
              "subsession_details",
              "linked_sources",
              "composition"
            ]
          }
        },
        "description": "Expand records with additional data.\n\nPossible values:\n- `translated_fields` — includes the `translated_fields` array on records when the event has language variants configured.\n- `subsession_details` — applies to session responses. Each subsession inside `parent.subsessions[]` is returned with full parent-session field parity (`status`, `custom_status`, `custom_fields`, `chairpersons`, `moderators`, `sponsors`, `exhibitors`, `tags`, `language`, `track`, `level`, `room`, `is_public`, `external_url`, `client_session_id`, `ceu_credits`, `capacity`, `source`) instead of the default minimal shape. Subsessions inherit `is_abstract`, `composition_status`, and optional `composition` from the parent. Not required when calling `GET /v1/event/{eventId}/sessions/{sessionId}` with a subsession UUID — that endpoint always returns the full shape at the top level.\n- `linked_sources` — include sessions that are linked as composition sources (excluded from list/search results by default).\n- `composition` — attach a full `composition` object with target and source details on each returned session. Recommended for single-session GET; use cautiously on broad searches.\n\nA single value can be passed directly, and multiple values repeat\nthe parameter — all of these are accepted:\n- `?expand=composition`\n- `?expand=translated_fields&expand=composition`\n- `?expand[]=translated_fields&expand[]=composition`\n"
      },
      "ListEventsExpand": {
        "name": "expand",
        "in": "query",
        "required": false,
        "style": "form",
        "explode": true,
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "custom_fields",
              "integration_mappings"
            ]
          }
        },
        "description": "Extra collections on each event in `GET /v1/events`. Not the same enum\nas session `Expand` (`translated_fields`, `composition`, …).\n\nRepeat the parameter (`?expand=custom_fields&expand=integration_mappings`)\nor comma-separate (`?expand=custom_fields,integration_mappings`).\n\n- `custom_fields` — org-defined Event custom field values. Omitted from\n  the payload when this expand is not requested. Present as `[]` when\n  requested and the event has no values.\n- `integration_mappings` — `{ name, source, external_event_id }` rows\n  from conference `Integration_*_Event_Mappings` (via the union view).\n  `source` uses underscores (`expo_platform`, not `expo-platform`).\n  LiveBuzz / apps-engine campaign IDs are not included.\n"
      }
    },
    "schemas": {
      "SharingSignatures": {
        "type": "object",
        "properties": {
          "generated": {
            "type": "boolean"
          },
          "generated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "stale": {
            "type": "boolean"
          },
          "started": {
            "type": "boolean"
          },
          "starts_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ]
          },
          "registration_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "width": {
            "type": "integer"
          },
          "height": {
            "type": "integer"
          },
          "banner_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stable banner URL; \"Save your seat\" until the start, \"Watch the recording\" after."
          },
          "banners": {
            "type": "object",
            "properties": {
              "live": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "on_demand": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "variants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "enum": [
                    "banner",
                    "line",
                    "text"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "html": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                }
              }
            }
          },
          "variants_available": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "team": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "user_id": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "share_url": {
                  "type": "string"
                },
                "emailed_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "opened_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "copied_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "clicks": {
                  "type": "integer"
                },
                "registrations": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "SharingUserIds": {
        "type": "object",
        "required": [
          "user_ids"
        ],
        "properties": {
          "user_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "integer"
            },
            "description": "Organization members' user ids."
          }
        }
      },
      "SharingShareCards": {
        "type": "object",
        "properties": {
          "cards": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "template_id": {
                  "type": "string"
                },
                "design": {
                  "type": "string",
                  "enum": [
                    "spotlight",
                    "lineup",
                    "portrait",
                    "headline",
                    "calendar",
                    "ticket"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "faces": {
                  "type": "boolean"
                },
                "url": {
                  "type": "string"
                },
                "width": {
                  "type": "integer"
                },
                "height": {
                  "type": "integer"
                },
                "in_advocacy": {
                  "type": "boolean",
                  "description": "On the speakers' and attendees' sharing pages."
                },
                "generated_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "generated": {
            "type": "boolean"
          },
          "generated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "stale": {
            "type": "boolean"
          },
          "started": {
            "type": "boolean"
          },
          "starts_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ]
          },
          "speakers": {
            "type": "integer"
          },
          "speakers_with_photos": {
            "type": "integer"
          },
          "registration_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "designs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "faces": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "SharingSpeakerLinks": {
        "type": "object",
        "properties": {
          "campaign": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "live": {
                "type": "boolean"
              },
              "attendee_share_count": {
                "type": "integer"
              }
            }
          },
          "speaker_campaign": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "live": {
                "type": "boolean"
              }
            }
          },
          "speakers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "contact_id": {
                  "type": "string"
                },
                "recipient_id": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "share_url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "shares": {
                  "type": "integer"
                },
                "last_shared_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "removed": {
                  "type": "boolean"
                },
                "pending": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "TaskPerson": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": "string"
          },
          "photo_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "TaskRecord": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "contact",
              "session",
              "sponsor",
              "exhibitor",
              "group"
            ],
            "description": "A submission is a `session`."
          },
          "id": {
            "type": "string"
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "The contact's name, the session's title, or the sponsor's, exhibitor's or group's name. `null` when `restricted`."
          },
          "restricted": {
            "type": "boolean",
            "description": "The key's user cannot read this record, so its label is withheld."
          }
        }
      },
      "TaskRecordRef": {
        "type": "object",
        "required": [
          "type",
          "id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "contact",
              "session",
              "sponsor",
              "exhibitor",
              "group"
            ]
          },
          "id": {
            "type": "string"
          }
        }
      },
      "Task": {
        "type": "object",
        "description": "A to-do for your team, about one or more records, in an event or across the organization.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "org_id": {
            "type": "string"
          },
          "event_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "event": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "integer"
              },
              "name": {
                "type": "string"
              },
              "timezone": {
                "type": "string"
              }
            }
          },
          "kind": {
            "type": "string",
            "enum": [
              "task",
              "milestone"
            ]
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "in_progress",
              "completed",
              "cancelled"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          },
          "assignee": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TaskPerson"
              },
              {
                "type": "null"
              }
            ]
          },
          "creator": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TaskPerson"
              },
              {
                "type": "null"
              }
            ]
          },
          "completed_by": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TaskPerson"
              },
              {
                "type": "null"
              }
            ]
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskRecord"
            }
          },
          "due_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "has_due_time": {
            "type": "boolean",
            "description": "`false` when only a date was set (due at 23:59 that day in the time zone)."
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "The due date in `timezone`."
          },
          "due_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "The due time (`HH:mm`) in `timezone`; `null` when `has_due_time` is `false`."
          },
          "timezone": {
            "type": "string",
            "description": "The IANA time zone of `due_date` and `due_time` — the event's, or for an organization task the assignee's (else `America/New_York`)."
          },
          "record_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "The primary record's type (the same as `records[0].type`)."
          },
          "record_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The primary record's id."
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "start_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "reminder": {
            "type": "string",
            "enum": [
              "none",
              "due",
              "9am",
              "1h",
              "1d",
              "1w"
            ]
          },
          "reminder_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the reminder goes to the assignee."
          },
          "milestone": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "title": {
                "type": "string"
              },
              "due_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "source": {
            "type": [
              "string",
              "null"
            ],
            "description": "Where the task came from, such as `api`, `custom`, `note` or `milestone`."
          },
          "source_note_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The note this task follows up, when it was created from one."
          },
          "completion_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "follower_ids": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "is_overdue": {
            "type": "boolean"
          },
          "can_edit": {
            "type": "boolean",
            "description": "The key's user can update, complete or reopen it."
          },
          "can_delete": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TaskEnvelope": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Task"
          }
        }
      },
      "TaskList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Task"
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "total_results": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              },
              "has_more": {
                "type": "boolean"
              }
            }
          },
          "counts": {
            "type": "object",
            "description": "Totals for the same filters, ignoring `status`, `due` and `kind`.",
            "properties": {
              "open": {
                "type": "integer"
              },
              "today": {
                "type": "integer"
              },
              "overdue": {
                "type": "integer"
              },
              "upcoming": {
                "type": "integer"
              },
              "none": {
                "type": "integer"
              },
              "milestones": {
                "type": "integer"
              },
              "completed": {
                "type": "integer"
              }
            }
          }
        }
      },
      "TaskCreate": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "event_id": {
            "type": "integer",
            "description": "The event the task belongs to. Omit for an organization task."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskRecordRef"
            }
          },
          "assignee_id": {
            "type": "integer"
          },
          "assignee_email": {
            "type": "string",
            "format": "email",
            "description": "Instead of `assignee_id`."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "example": "2026-11-20"
          },
          "due_time": {
            "type": "string",
            "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
            "example": "14:00",
            "description": "24-hour `HH:mm` in the event's time zone. Omit for the end of the day."
          },
          "reminder": {
            "type": "string",
            "enum": [
              "none",
              "due",
              "9am",
              "1h",
              "1d",
              "1w"
            ],
            "description": "Default: `9am` when the task has a due date, otherwise `none`.\n\n`due` at the due time, `9am` at 09:00 on the due date, `1h` an hour\nbefore, `1d` / `1w` at 09:00 one day or one week before.\n"
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ],
            "default": "normal"
          }
        }
      },
      "TaskUpdate": {
        "type": "object",
        "description": "Any of the create fields except `event_id`; `null` clears a field.",
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskRecordRef"
            }
          },
          "assignee_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "assignee_email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "due_time": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
          },
          "reminder": {
            "type": "string",
            "enum": [
              "none",
              "due",
              "9am",
              "1h",
              "1d",
              "1w"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          }
        }
      },
      "TaskApiError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "`VALIDATION_ERROR`, `USER_REQUIRED`, `FORBIDDEN`, `NOT_FOUND`, `TASKS_PLATFORM_ONLY`, `SCOPE_REQUIRED`, `ORG_WIDE_TOKEN_REQUIRED` or `INTERNAL_ERROR`."
          },
          "message": {
            "type": "string"
          }
        }
      },
      "OrganizationProducts": {
        "type": "object",
        "required": [
          "apps",
          "platform_customer"
        ],
        "properties": {
          "apps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrganizationProduct"
            }
          },
          "platform_customer": {
            "type": "boolean",
            "description": "The organization has a Platform contract (or predates the self-serve products)."
          }
        }
      },
      "OrganizationProduct": {
        "type": "object",
        "required": [
          "key",
          "owned",
          "via",
          "days_left"
        ],
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "platform",
              "sessions",
              "crm",
              "awards",
              "learning",
              "marketing"
            ]
          },
          "owned": {
            "type": "boolean",
            "description": "The organization can open this product now."
          },
          "via": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "self_serve",
              "platform",
              null
            ],
            "description": "How the organization has it, or `null` when not owned."
          },
          "days_left": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Whole days left on a self-serve trial, otherwise `null`."
          }
        }
      },
      "LearningMedia": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "recording",
              "audio",
              "clip"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "has_transcript": {
            "type": "boolean"
          },
          "chapter_count": {
            "type": "integer"
          },
          "clip_count": {
            "type": "integer",
            "description": "Clips cut from this recording."
          },
          "parent": {
            "type": [
              "object",
              "null"
            ],
            "description": "A clip's recording.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "can_make_course": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CourseDraftSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "generating",
              "ready",
              "applying",
              "applied",
              "failed"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "media_item_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "progress": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "step": {
                "type": "string"
              },
              "done": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "lesson_count": {
            "type": "integer"
          },
          "applied_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Send back as `baseUpdatedAt` when you save."
          }
        }
      },
      "CourseDraft": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CourseDraftSummary"
          },
          {
            "type": "object",
            "properties": {
              "bundle": {
                "$ref": "#/components/schemas/CourseBundle"
              },
              "diff": {
                "type": "object",
                "description": "What publishing would do — `created` / `updated` / `unchanged` for lessons, courses and certifications."
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "lesson": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              },
              "media": {
                "type": "object",
                "description": "Per clip id — `status` (ready, processing, failed, missing), a short-lived `url`, `duration_s`, `poster_url`.",
                "additionalProperties": true
              },
              "apply_result": {
                "type": [
                  "object",
                  "null"
                ]
              }
            }
          }
        ]
      },
      "CourseBundle": {
        "type": "object",
        "description": "Lessons, the course and the certification. A lesson's watch step plays a clip (`mediaItemId`) and may carry `checkpoints` — questions with `atSeconds`, seconds into the clip. A question has `prompt`, `type`, `options`, `answer` (multi-select, ordering and matching answers are JSON strings), optional `config` and `feedback` (`correct`, `incorrect`, `hint`). Keys are permanent: publishing upserts by key.",
        "required": [
          "lessons"
        ],
        "properties": {
          "lessons": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "courses": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "certifications": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "AwardsError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "VALIDATION_ERROR",
              "SCOPE_REQUIRED",
              "FORBIDDEN",
              "NOT_FOUND",
              "CONFLICT"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AwardsProgram": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "org_id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "examples": [
              "2027 Excellence Awards"
            ]
          },
          "slug": {
            "type": "string",
            "examples": [
              "2027-excellence-awards"
            ]
          },
          "nomenclature": {
            "type": "string",
            "enum": [
              "awards",
              "grants",
              "scholarships"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "open",
              "reviewing",
              "closed",
              "archived"
            ]
          },
          "year": {
            "type": [
              "integer",
              "null"
            ]
          },
          "deadline": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "collects_fees": {
            "type": "boolean"
          },
          "pricing_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "base_fee": {
            "type": [
              "number",
              "null"
            ]
          },
          "submitter_editing_policy": {
            "type": "string",
            "enum": [
              "never",
              "while_open",
              "while_open_after_payment"
            ]
          },
          "notify_on_submitter_edit": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AwardsProgramWrite": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "nomenclature": {
            "type": "string",
            "enum": [
              "awards",
              "grants",
              "scholarships"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "slug": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Defaults to one derived from `name` on create."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "open",
              "reviewing",
              "closed",
              "archived"
            ],
            "description": "Update only."
          },
          "year": {
            "type": [
              "integer",
              "null"
            ]
          },
          "deadline": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "collects_fees": {
            "type": "boolean",
            "description": "Update only."
          },
          "submitter_editing_policy": {
            "type": "string",
            "enum": [
              "never",
              "while_open",
              "while_open_after_payment"
            ]
          },
          "notify_on_submitter_edit": {
            "type": "boolean"
          },
          "default_submission_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "submitted",
              "under_review",
              "accepted",
              "rejected",
              "",
              null
            ],
            "description": "Status a new submission starts in. Empty string or `null` clears it."
          }
        }
      },
      "AwardsCategory": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "program_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "examples": [
              "Best Innovation"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "parent_category_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "submission_limit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "expertise_tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "order": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AwardsCategoryWrite": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 10000
          },
          "parent_category_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Another category in the same program. `null` makes it top-level."
          },
          "submission_limit": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Most submissions one submitter may file in this category."
          },
          "expertise_tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "order": {
            "type": "integer"
          }
        }
      },
      "AwardsRound": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "program_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "examples": [
              "Final judging"
            ]
          },
          "round_type": {
            "type": "string",
            "enum": [
              "submission_review",
              "review_only"
            ]
          },
          "is_default": {
            "type": "boolean",
            "description": "The program's first round. It cannot be deleted."
          },
          "submission_start_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "submission_end_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "review_start_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "review_end_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "passing_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "blind_review": {
            "type": "boolean"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AwardsRoundWrite": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "round_type": {
            "type": "string",
            "enum": [
              "submission_review",
              "review_only"
            ]
          },
          "submission_start_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "`YYYY-MM-DD` or an ISO 8601 timestamp."
          },
          "submission_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "`YYYY-MM-DD` or an ISO 8601 timestamp."
          },
          "review_start_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "`YYYY-MM-DD` or an ISO 8601 timestamp."
          },
          "review_end_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "`YYYY-MM-DD` or an ISO 8601 timestamp."
          },
          "passing_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "blind_review": {
            "type": "boolean",
            "description": "Hide submitter identity from reviewers."
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 20000
          }
        }
      },
      "AwardsPromoCode": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "program_id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "examples": [
              "SAVE20"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "percentage",
              "flat"
            ]
          },
          "amount": {
            "type": "number",
            "examples": [
              20
            ]
          },
          "starts_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ends_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "redemption_count": {
            "type": "integer",
            "description": "Submissions the code has been applied to. Returned by the single-code GET only."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AwardsPromoCodeWrite": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 255,
            "pattern": "^[A-Za-z0-9]+$",
            "description": "Letters and digits; stored upper-case."
          },
          "type": {
            "type": "string",
            "enum": [
              "percentage",
              "flat"
            ]
          },
          "amount": {
            "type": "number",
            "minimum": 0,
            "description": "Percent off (at most 100) or a flat amount in the program's currency."
          },
          "starts_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ends_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "AwardsSubmission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "program_id": {
            "type": "string",
            "format": "uuid"
          },
          "category_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string",
            "examples": [
              "AWD-0042"
            ]
          },
          "status": {
            "type": "string",
            "examples": [
              "submitted"
            ]
          },
          "current_round_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "payment_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "promo_code_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "submitted_by_user_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "submitted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "total_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "merged_into_submission_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "values": {
            "type": "object",
            "additionalProperties": true,
            "description": "Form answers keyed by form field ID. Returned by the single-submission GET and by updates."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AwardsSubmissionWrite": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "values": {
            "type": "object",
            "additionalProperties": true,
            "description": "Answers keyed by form field ID. Fields you omit are left unchanged; a required field sent empty returns `400`."
          },
          "allow_submitter_editing_override": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Let this submitter edit regardless of the program's editing policy. `null` clears the override."
          }
        }
      },
      "AwardsReview": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "submission_id": {
            "type": "string",
            "format": "uuid"
          },
          "round_id": {
            "type": "string",
            "format": "uuid"
          },
          "reviewer_user_id": {
            "type": "integer"
          },
          "is_abstained": {
            "type": "boolean"
          },
          "abstain_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "scores": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "field_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "value": {
                  "description": "Number, text, or JSON depending on the scorecard field."
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "LogPage": {
        "type": "object",
        "required": [
          "data",
          "next_cursor",
          "has_more"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LogEvent"
            }
          },
          "next_cursor": {
            "type": "string",
            "description": "Send this as `cursor` on the next call. On an empty page it is the cursor you sent,\nso a caught-up poller keeps it and waits.\n"
          },
          "has_more": {
            "type": "boolean",
            "description": "`true` when more events are ready now — fetch again immediately. `false` means wait before polling."
          }
        }
      },
      "LogEvent": {
        "type": "object",
        "description": "One event, in the same shape on every stream. Events appear about a minute after they happen\nand are ordered by when Sessionboard recorded them, so a late-arriving event is never skipped.\n",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable event id. Use it to de-duplicate if you replay a page."
          },
          "stream": {
            "type": "string",
            "enum": [
              "api_request",
              "security_event",
              "audit"
            ],
            "description": "Which log the event came from — `api_request` from `/v1/logs/api-requests`, `security_event` from `/v1/logs/security-events`, `audit` from `/v1/logs/audit-trail`."
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the event happened."
          },
          "ingested_at": {
            "type": "string",
            "format": "date-time",
            "description": "When Sessionboard recorded it. Pages are ordered by this."
          },
          "action": {
            "type": "string",
            "description": "`GET /v1/events` for API requests, the event type (for example `login.password_ok` or `login.challenge_failed`) for security events, `<subject_type>.<operation>` for the audit trail.",
            "example": "GET /v1/events"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "success",
              "failure",
              "unknown"
            ]
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "Why it failed, when it did."
          },
          "actor": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "description": "`api_token`, `oauth_token` or `anonymous` for API requests; `user` or `admin` for security events; `user`, `system` or `rule` (an automation) for the audit trail."
              },
              "id": {
                "type": "string",
                "nullable": true
              },
              "name": {
                "type": "string",
                "nullable": true
              },
              "token_hint": {
                "type": "string",
                "nullable": true,
                "description": "Last characters of the token id, for API requests."
              },
              "user_email": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "src_ip": {
            "type": "string",
            "nullable": true
          },
          "user_agent": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "nullable": true,
            "description": "HTTP status, for API requests."
          },
          "duration_ms": {
            "type": "integer",
            "nullable": true,
            "description": "Response time, for API requests."
          },
          "target": {
            "type": "object",
            "nullable": true,
            "properties": {
              "type": {
                "type": "string",
                "example": "event"
              },
              "id": {
                "type": "string"
              }
            }
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Stream-specific fields (for example `source` and `request_id` for API requests, `property` and `value` for the audit trail)."
          }
        }
      },
      "LogExportError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "VALIDATION_ERROR",
              "INVALID_CURSOR",
              "CURSOR_FILTER_MISMATCH",
              "SINCE_BEFORE_RETENTION",
              "CURSOR_EXPIRED"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AskRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "question"
        ],
        "properties": {
          "question": {
            "type": "string",
            "minLength": 2,
            "maxLength": 500,
            "description": "The question, in plain language. Whitespace is collapsed before the length check:\nunder 2 or over 500 characters returns `422` (`empty` / `too_long`), and a value over\n1000 characters is rejected with `400`.\n"
          },
          "conversation_id": {
            "type": "string",
            "format": "uuid",
            "description": "The `conversation_id` from a previous answer, to ask a follow-up in the same thread."
          },
          "lang": {
            "type": "string",
            "maxLength": 16,
            "pattern": "^[A-Za-z]{2,3}([-_][A-Za-z0-9]{2,8})?$",
            "description": "Answer language as a language tag, e.g. `en`, `fr`, `pt-BR`."
          }
        }
      },
      "AskCitation": {
        "type": "object",
        "description": "A source card built from a record. `index` matches the `[n]` marker in `answer`. The\nfields beyond `index`, `type` and `id` depend on `type` — for example `title` and\n`starts_at` on a session, `name` on a speaker, `session_id`, `session_title`, `start_ms`\nand `text` on a transcript excerpt.\n",
        "required": [
          "index",
          "type",
          "id"
        ],
        "properties": {
          "index": {
            "type": "integer",
            "description": "The `n` in the answer's `[n]` marker."
          },
          "type": {
            "type": "string",
            "enum": [
              "session",
              "speaker",
              "exhibitor",
              "sponsor",
              "product",
              "poster",
              "room",
              "pin",
              "info",
              "transcript",
              "doc",
              "pinned",
              "help"
            ]
          },
          "id": {
            "type": "string",
            "description": "The id of the cited record."
          },
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "session_id": {
            "type": "string"
          },
          "session_title": {
            "type": "string"
          },
          "start_ms": {
            "type": "integer",
            "description": "Offset into the session recording, for a transcript excerpt."
          },
          "text": {
            "type": "string",
            "description": "The quoted passage, for a transcript excerpt."
          }
        },
        "additionalProperties": true
      },
      "AskResponse": {
        "type": "object",
        "required": [
          "status",
          "answer",
          "citations",
          "actions",
          "conversation_id",
          "message_id"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "answer": {
            "type": "string",
            "description": "The answer as Markdown. `[n]` marks citation `n`."
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AskCitation"
            }
          },
          "actions": {
            "type": "array",
            "maxItems": 0,
            "items": {},
            "description": "Always empty — this endpoint is read-only."
          },
          "conversation_id": {
            "type": "string",
            "format": "uuid",
            "description": "Send this back with a follow-up question to continue the conversation."
          },
          "message_id": {
            "type": "string",
            "format": "uuid",
            "description": "The id of this answer."
          }
        }
      },
      "TooManyRequestsError": {
        "type": "object",
        "description": "Body of a `429` from the API's own request limits (per token, and per organization and user). Wait `Retry-After` seconds.",
        "required": [
          "name",
          "message"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "example": 429
          },
          "success": {
            "type": "boolean",
            "example": false
          },
          "message": {
            "type": "string",
            "example": "Error while trying to reach the endpoint: Too many requests"
          },
          "name": {
            "type": "string",
            "enum": [
              "TooManyRequestsError"
            ]
          }
        }
      },
      "AskError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "VALIDATION_ERROR",
              "SCOPE_REQUIRED",
              "EVENT_NOT_ALLOWED",
              "AI_DISABLED",
              "FORBIDDEN",
              "RATE_LIMITED",
              "QUOTA_EXCEEDED",
              "INTERNAL_ERROR"
            ]
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "description": "`reason`, and for `RATE_LIMITED` also `retry_after_seconds` and `remaining_today`.",
            "properties": {
              "reason": {
                "type": "string",
                "enum": [
                  "empty",
                  "too_long",
                  "blocked",
                  "repeated",
                  "per_minute",
                  "daily",
                  "busy",
                  "off",
                  "ai_disabled",
                  "ai_credits"
                ]
              },
              "retry_after_seconds": {
                "type": "integer"
              },
              "remaining_today": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          }
        }
      },
      "DateRangeFilter": {
        "type": "object",
        "description": "Filter by a date range using before and/or after bounds.",
        "properties": {
          "before": {
            "type": "string",
            "format": "date-time",
            "description": "Return records before this date-time."
          },
          "after": {
            "type": "string",
            "format": "date-time",
            "description": "Return records after this date-time."
          }
        }
      },
      "NestedSortField": {
        "type": "object",
        "description": "One sort key. `sort` is the direction; `order` is the priority when\nmultiple keys are set (lower numbers apply first).\n",
        "properties": {
          "sort": {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ]
          },
          "order": {
            "type": "integer"
          }
        }
      },
      "SortOptions": {
        "type": "object",
        "description": "Nested sort keys matching the search POST body (`createdAt.sort`, not a\nflat `order` enum). Each key is optional.\n",
        "properties": {
          "createdAt": {
            "$ref": "#/components/schemas/NestedSortField"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/NestedSortField"
          }
        }
      },
      "SessionSortOptions": {
        "type": "object",
        "description": "Session search sort. Same nested shape as `SortOptions`, plus `startsAt`.",
        "properties": {
          "createdAt": {
            "$ref": "#/components/schemas/NestedSortField"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/NestedSortField"
          },
          "startsAt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NestedSortField"
              }
            ],
            "description": "Sort by session start time. Null `starts_at` values always sort last.\n"
          }
        }
      },
      "RecordSearchBody": {
        "type": "object",
        "description": "Common search request body used across multiple endpoints.",
        "properties": {
          "filters": {
            "type": "object",
            "properties": {
              "createdAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "updatedAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "accept_queue",
                  "pending",
                  "decline_queue",
                  "declined"
                ],
                "description": "Filter by session status (applicable to session searches)."
              }
            }
          },
          "sort": {
            "$ref": "#/components/schemas/SortOptions"
          },
          "expand": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "translated_fields",
                "subsession_details",
                "linked_sources",
                "composition"
              ]
            },
            "description": "Expand records with additional data. See the `Expand` parameter for `linked_sources` and `composition` details.\n"
          }
        }
      },
      "SessionSearchBody": {
        "type": "object",
        "description": "Search request body for sessions with status filtering.",
        "properties": {
          "filters": {
            "type": "object",
            "properties": {
              "createdAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "updatedAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "accept_queue",
                  "pending",
                  "decline_queue",
                  "declined"
                ]
              },
              "isAbstract": {
                "type": "boolean",
                "description": "Filter to abstract submissions (`true`) or program sessions (`false`)."
              },
              "sessionIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "trackIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Match sessions with any of these track IDs (OR). Combined with other filters using AND. Send at least one ID — an empty array is rejected with a 400; to apply no track filter, omit the property."
              },
              "levelIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "formatIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "languageIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "tagIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Match sessions tagged with any of these tag IDs (OR). Send at least one ID — an empty array is rejected with a 400."
              }
            }
          },
          "sort": {
            "$ref": "#/components/schemas/SessionSortOptions"
          },
          "expand": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "translated_fields",
                "subsession_details",
                "linked_sources",
                "composition"
              ]
            }
          }
        }
      },
      "SpeakerSearchBody": {
        "type": "object",
        "description": "Search request body for speakers, including session metadata filters.\nCategorization filters (`trackIds`, `levelIds`, `formatIds`,\n`languageIds`, `tagIds`) match against the speaker's **top-level\nsession** — a speaker on a subsession matches via the subsession's\nparent (root) session, mirroring session search semantics.\n",
        "properties": {
          "filters": {
            "type": "object",
            "properties": {
              "createdAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "updatedAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "accept_queue",
                  "pending",
                  "decline_queue",
                  "declined"
                ]
              },
              "trackIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Send at least one ID — an empty array is rejected with a 400; to apply no track filter, omit the property."
              },
              "levelIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "formatIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "languageIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "tagIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          },
          "sort": {
            "$ref": "#/components/schemas/SortOptions"
          },
          "expand": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "translated_fields"
              ]
            }
          }
        }
      },
      "ParticipantSearchBody": {
        "type": "object",
        "description": "Search request body for participants. Every `SpeakerSearchBody` filter\nis accepted with the same semantics (categorization filters match the\nparticipant's **top-level** session), plus `roleIds`, `roleSlugs` and `email`.\n",
        "properties": {
          "filters": {
            "type": "object",
            "properties": {
              "createdAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "updatedAt": {
                "$ref": "#/components/schemas/DateRangeFilter"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "accept_queue",
                  "pending",
                  "decline_queue",
                  "declined"
                ],
                "description": "Match participants on sessions with this session status."
              },
              "trackIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Send at least one ID — an empty array is rejected with a 400; to apply no track filter, omit the property."
              },
              "levelIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "formatIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "languageIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "tagIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "roleIds": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "description": "Return participants holding at least one of these roles\n(standard or custom). Ids come from\n`GET /v1/event/{eventId}/participant-roles`. An empty array is a\n400; omit the property to match every role.\n"
              },
              "roleSlugs": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Return participants holding at least one role with these slugs —\nthe standard `speaker`, `chairperson`, `moderator`, or a custom\nrole's `slug` from `GET .../participant-roles`. Works on events\nwhose roles have `roleId: null`. Case-insensitive. Combines with\n`roleIds` as AND. An empty array is a 400.\n"
              },
              "email": {
                "type": "string",
                "minLength": 1,
                "maxLength": 320,
                "description": "Exact, case-insensitive match on the contact's email. An\nunknown address returns an empty result set, not an error.\n"
              }
            }
          },
          "sort": {
            "$ref": "#/components/schemas/SortOptions"
          },
          "expand": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "translated_fields"
              ]
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "description": "Pagination metadata returned with POST search responses. The event-settings GET lists return the same numbers under snake_case keys — see `ListPagination`.",
        "properties": {
          "currentPage": {
            "type": "integer",
            "examples": [
              1
            ]
          },
          "pageSize": {
            "type": "integer",
            "examples": [
              25
            ]
          },
          "totalPages": {
            "type": "integer",
            "examples": [
              4
            ]
          },
          "totalResults": {
            "type": "integer",
            "examples": [
              97
            ]
          }
        }
      },
      "ListPagination": {
        "type": "object",
        "description": "Pagination metadata returned by the event-settings GET lists (tags, tracks, levels, formats, rooms, languages, statuses). Same numbers as `Pagination`, snake_case keys — these endpoints are served by a different layer, and the casing is longstanding.",
        "properties": {
          "current_page": {
            "type": "integer",
            "examples": [
              1
            ]
          },
          "page_size": {
            "type": "integer",
            "examples": [
              25
            ]
          },
          "total_pages": {
            "type": "integer",
            "examples": [
              4
            ]
          },
          "total_results": {
            "type": "integer",
            "examples": [
              97
            ]
          }
        }
      },
      "CompositionTargetSummary": {
        "type": "object",
        "description": "Summary of a related session in a composition relationship.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "is_abstract": {
            "type": "boolean"
          }
        }
      },
      "CompositionStatus": {
        "type": "object",
        "description": "Summary of how this session participates in a composition (merge or link).\nAlways present on session responses.\n",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "standalone",
              "target",
              "source"
            ],
            "description": "- `standalone` — normal editable record\n- `target` — composite parent with one or more linked sources\n- `source` — linked into another record (still editable)\n"
          },
          "is_linked": {
            "type": "boolean"
          },
          "is_read_only": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always `false`. Linked sources stay editable; the key is kept for compatibility."
          },
          "source_count": {
            "type": "integer",
            "description": "Number of records merged or linked into this session."
          },
          "target": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CompositionTargetSummary"
              }
            ],
            "nullable": true,
            "description": "Present when `role` is `source`."
          }
        }
      },
      "CompositionSource": {
        "type": "object",
        "properties": {
          "composition_id": {
            "type": "string",
            "format": "uuid"
          },
          "relationship_type": {
            "type": "string",
            "enum": [
              "merged_session",
              "merged_abstract",
              "composed_into_session"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "is_abstract": {
            "type": "boolean"
          }
        }
      },
      "CompositionDetail": {
        "type": "object",
        "description": "Full composition graph. Present when `expand=composition`.",
        "properties": {
          "target": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CompositionTargetSummary"
              }
            ],
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompositionSource"
            }
          }
        }
      },
      "ContactSessionSummary": {
        "type": "object",
        "description": "Lightweight session summary for contact session lists. Includes\ncomposition summary fields but not the full `composition` graph.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "custom_status": {
            "type": "string",
            "nullable": true
          },
          "is_abstract": {
            "type": "boolean"
          },
          "composition_status": {
            "$ref": "#/components/schemas/CompositionStatus"
          }
        }
      },
      "OrgContactSessionSummary": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ContactSessionSummary"
          },
          {
            "type": "object",
            "properties": {
              "event_id": {
                "type": "integer",
                "description": "Event the session belongs to."
              }
            }
          }
        ]
      },
      "ContactSessionsResponse": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactSessionSummary"
            }
          },
          "status": {
            "type": "string",
            "description": "Aggregated contact status derived from linked sessions\n(`accepted`, `pending`, or a single session's status).\n"
          }
        }
      },
      "OrgContactSessionsResponse": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrgContactSessionSummary"
            }
          },
          "status": {
            "type": "string",
            "description": "Aggregated contact status derived from linked sessions\n(`accepted`, `pending`, or a single session's status).\n"
          }
        }
      },
      "Event": {
        "type": "object",
        "description": "An event on the Sessionboard platform.",
        "properties": {
          "id": {
            "type": "integer",
            "examples": [
              3960
            ]
          },
          "name": {
            "type": "string",
            "examples": [
              "Acme Conference"
            ]
          },
          "timezone": {
            "type": "string",
            "examples": [
              "America/Chicago"
            ]
          },
          "starts_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "ends_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "features": {
            "type": "object",
            "properties": {
              "primary_speakers": {
                "type": "boolean"
              },
              "speaker_acceptance": {
                "type": "boolean"
              },
              "translated_fields": {
                "type": "boolean"
              }
            }
          },
          "custom_fields": {
            "type": "array",
            "description": "Present only when `expand=custom_fields` is passed to\n`GET /v1/events`. Empty array when the event has no values.\n",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "integration_mappings": {
            "type": "array",
            "description": "Present only when `expand=integration_mappings` is passed to\n`GET /v1/events`. Conference connector event IDs only — LiveBuzz\n/ apps-engine campaign IDs are not included. Empty array when\nnone are mapped.\n",
            "items": {
              "$ref": "#/components/schemas/EventIntegrationMapping"
            }
          }
        }
      },
      "EventIntegrationMapping": {
        "type": "object",
        "description": "A conference integration's identifier for this Sessionboard event.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name (for example `Cvent`, `Grip`).",
            "examples": [
              "Cvent"
            ]
          },
          "source": {
            "type": "string",
            "description": "Integration key from `Integration_Event_Mapping_Union` (table name minus `Integration_` / `_Event_Mappings`, lowercased). Multi-word vendors use underscores, e.g. `expo_platform`.\n",
            "examples": [
              "cvent",
              "expo_platform"
            ]
          },
          "external_event_id": {
            "type": "string",
            "description": "Vendor event id, always a string.",
            "examples": [
              "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
            ]
          }
        }
      },
      "Session": {
        "type": "object",
        "description": "A session within an event (e.g., talk, workshop, panel, or CFP abstract submission).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "accepted",
              "accept_queue",
              "pending",
              "decline_queue",
              "declined"
            ]
          },
          "custom_status_id": {
            "type": "string"
          },
          "custom_status": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time"
          },
          "is_public": {
            "type": "boolean"
          },
          "is_abstract": {
            "type": "boolean",
            "description": "True for CFP abstract submissions; false for program sessions."
          },
          "composition_status": {
            "$ref": "#/components/schemas/CompositionStatus"
          },
          "composition": {
            "$ref": "#/components/schemas/CompositionDetail",
            "description": "Present when `expand=composition` is requested."
          },
          "external_url": {
            "type": "string",
            "format": "uri"
          },
          "client_session_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "ceu_credits": {
            "type": "number",
            "format": "float"
          },
          "capacity": {
            "type": "integer"
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "speakers": {
            "type": "array",
            "description": "Legacy junction-table speakers (`Session_Speakers`). Retained for backwards\ncompatibility. Each entry includes `participant_role` when the event has\nSessions 2.0 roles configured. Prefer `participants` for new integrations\nthat need custom program roles or a single flat participant list.\n",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "chairpersons": {
            "type": "array",
            "description": "Legacy junction-table chairpersons (`Session_Chairpersons`). See `speakers`\nfor migration guidance.\n",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "moderators": {
            "type": "array",
            "description": "Legacy junction-table moderators (`Session_Moderators`). See `speakers`\nfor migration guidance.\n",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "participants": {
            "type": "array",
            "description": "Flat list of session participants from the Sessions 2.0 data model\n(`Session_Participants` + `Session_Roles`). Always returned on session\nsearch and get (no expand flag). Includes custom program roles (for example\nAuthor, Panelist) in addition to the legacy speaker/chairperson/moderator\njunction tables. Legacy arrays above remain for backwards compatibility;\neach legacy entry also includes `participant_role` when event roles are\nconfigured. Contact profile fields (`photo_url`, `company_name`, `title`,\n`address_country`, etc.) are hydrated from the contact record in the event's\ndefault language without requiring expand.\n",
            "items": {
              "$ref": "#/components/schemas/SessionParticipant"
            }
          },
          "sponsors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionSponsor"
            }
          },
          "exhibitors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionExhibitor"
            }
          },
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Content"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Language"
              }
            ],
            "description": "Assigned session language. Includes `id`, `event_id`, `name`, `order`,\n`created_at`, and `updated_at` when set. Unassigned values are an\nempty object `{}` on `POST` session search responses and `null` on\nCRUD proxy responses (`GET` list, create, update, restore).\n"
          },
          "track": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Track"
              }
            ],
            "description": "Assigned session track. Includes `id`, `event_id`, `name`, `color`,\n`order`, `created_at`, and `updated_at` when set. Unassigned values\nare `{}` on `POST` session search and `null` on CRUD proxy responses.\n"
          },
          "level": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Level"
              }
            ],
            "description": "Assigned session level. Includes `id`, `name`, `order`, `created_at`,\nand `updated_at` when set (no `event_id` on nested objects). Unassigned\nvalues are `{}` on `POST` session search and `null` on CRUD proxy responses.\n"
          },
          "format": {
            "type": "object",
            "description": "Assigned session format. Nested session objects include only `id` and\n`name` (not the full standalone `Format` schema).\n",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "room": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Room"
              }
            ],
            "description": "Assigned room when `location` is `room`. Includes `id`, `name`,\n`order`, `capacity`, `created_at`, and `updated_at` when set. Omitted\nwhen location is `external` or unset (`{}` on `POST` search, `null` on\nCRUD proxy). `event_id` is not included on nested room objects.\n"
          },
          "subsessions": {
            "type": "array",
            "description": "Subsessions of this parent session. Each item defaults to the\nminimal `Subsession` shape; pass `expand=subsession_details` to\nreceive the full `SubsessionDetailed` shape on every subsession\nin the array. Composition fields (`is_abstract`,\n`composition_status`, optional `composition`) are inherited from\nthe parent session.\n\nItems are returned in the order set by the event admin\n(`subsession_order`), falling back to subsession number and then\nstart time for subsessions that have never been reordered.\n",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/Subsession"
                },
                {
                  "$ref": "#/components/schemas/SubsessionDetailed"
                }
              ]
            }
          },
          "admin_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Deep link to this entity in the Sessionboard admin UI."
          }
        },
        "examples": [
          {
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "friendly_id": "SESS-8",
            "friendly_id_raw": 8,
            "title": "Networking",
            "description": "<p>Networking session description</p>",
            "status": "accepted",
            "starts_at": "2024-03-15T09:00:00Z",
            "ends_at": "2024-03-15T10:00:00Z",
            "is_public": true,
            "created_at": "2024-01-10T14:30:00Z",
            "updated_at": "2024-03-01T09:15:00Z",
            "ceu_credits": 1.5,
            "capacity": 200,
            "language": {
              "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
              "event_id": 42,
              "name": "English",
              "order": 0,
              "created_at": "2024-01-01T00:00:00Z",
              "updated_at": "2024-01-01T00:00:00Z"
            },
            "track": {
              "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
              "event_id": 42,
              "name": "Artificial Intelligence & ML",
              "color": "#329af0",
              "order": 1,
              "created_at": "2024-01-01T00:00:00Z",
              "updated_at": "2024-01-01T00:00:00Z"
            },
            "level": {
              "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
              "name": "Beginner",
              "order": 2,
              "created_at": "2024-01-01T00:00:00Z",
              "updated_at": "2024-01-01T00:00:00Z"
            },
            "format": {
              "id": "d4e5f6a7-b8c9-0123-def0-234567890123",
              "name": "Session"
            },
            "room": {
              "id": "e5f6a7b8-c9d0-1234-ef01-345678901234",
              "name": "Workshop Room 1",
              "order": 3,
              "capacity": 120,
              "created_at": "2024-01-01T00:00:00Z",
              "updated_at": "2024-01-01T00:00:00Z"
            },
            "tags": [],
            "speakers": [],
            "content": [],
            "custom_fields": [],
            "admin_url": "https://app.sessionboard.com/event/42/sessions/497f6eca-6276-4993-bfeb-53cbbbba6f08"
          }
        ]
      },
      "SessionStatus": {
        "type": "object",
        "description": "A lightweight representation of a session's status, including\nsoft-deleted sessions. Parent rows additionally include a\n`subsessions` array with the same minimal status-focused shape for\neach child subsession. Subsession rows that appear in the flat list\nreturn an empty `subsessions` array.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          },
          "custom_status_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "custom_status": {
            "$ref": "#/components/schemas/SessionCustomStatus"
          },
          "is_abstract": {
            "type": "boolean"
          },
          "composition_status": {
            "$ref": "#/components/schemas/CompositionStatus"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "subsessions": {
            "type": "array",
            "description": "Empty for subsession rows. Populated with `SubsessionStatus` items for parent rows, in the admin-defined order (`subsession_order`, falling back to subsession number and start time).",
            "items": {
              "$ref": "#/components/schemas/SubsessionStatus"
            }
          }
        }
      },
      "Contact": {
        "type": "object",
        "description": "A contact (speaker, attendee, or organizational contact) in Sessionboard.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "full_name": {
            "type": "string"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the contact last changed, from any source: an admin or portal edit, a sync, or a Public API write (create, update or bulk). Send it back as `updated_at` on `PUT /v1/event/{eventId}/contacts/{contactId}` or a bulk update for optimistic concurrency; the write returns the new value."
          },
          "photo_url": {
            "type": "string",
            "description": "URL of the contact's headshot. Images larger than 2 MB are delivered resized from this URL, scaled to fit within 2400 x 2400 pixels (a PNG may arrive as WebP for clients that accept it). The uploaded file is stored unchanged; for full-resolution originals use the bulk download tools in Sessionboard, such as **Download Headshots** (Contacts, More menu)."
          },
          "company_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "about": {
            "type": "string"
          },
          "phone_home": {
            "type": "string"
          },
          "phone_mobile": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_country": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "facebook_url": {
            "type": "string"
          },
          "honorific": {
            "type": "string"
          },
          "salutation": {
            "type": "string"
          },
          "pronouns": {
            "type": "string"
          },
          "gender": {
            "type": "string"
          },
          "past_companies": {
            "type": "string"
          },
          "educational_affiliation": {
            "type": "string"
          },
          "highest_level_of_education": {
            "type": "string"
          },
          "ethnicity": {
            "type": "string"
          },
          "languages": {
            "type": "string"
          },
          "speaker_score": {
            "type": "string"
          },
          "organization_contact": {
            "type": "string"
          },
          "speaker_fee": {
            "type": "string"
          },
          "availability": {
            "type": "string"
          },
          "preferred_session_format": {
            "type": "string"
          },
          "annual_revenue": {
            "type": "string"
          },
          "headcount": {
            "type": "string"
          },
          "years_in_operation": {
            "type": "string"
          },
          "organization_structure": {
            "type": "string"
          },
          "industry": {
            "type": "string"
          },
          "global_region": {
            "type": "string"
          },
          "audience_type": {
            "type": "string"
          },
          "target_age_range": {
            "type": "string"
          },
          "topic_expertise": {
            "type": "string"
          },
          "brand": {
            "type": "string"
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "admin_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Deep link to this entity in the Sessionboard admin UI."
          }
        },
        "examples": [
          {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "friendly_id": "SPK-42",
            "full_name": "Dr. Jane Smith",
            "first_name": "Jane",
            "last_name": "Smith",
            "email": "jane.smith@university.edu",
            "created_at": "2023-11-01T10:00:00Z",
            "updated_at": "2024-02-15T16:30:00Z",
            "photo_url": "https://cdn.sessionboard.com/photos/jane-smith.jpg",
            "company_name": "State University",
            "title": "Professor of Computer Science",
            "about": "Dr. Smith is a leading researcher in distributed systems.",
            "address_city": "Austin",
            "address_state": "TX",
            "address_country": "US",
            "honorific": "Dr.",
            "pronouns": "she/her",
            "topic_expertise": "Distributed Systems, Cloud Computing",
            "custom_fields": [],
            "translated_fields": []
          }
        ]
      },
      "SessionSpeaker": {
        "type": "object",
        "description": "A contact embedded on a session (speaker, chairperson, moderator, or other\nprogram role). Standard contact profile fields (`photo_url`, `company_name`,\n`title`, `address_country`, etc.) are hydrated from the contact's module field\nvalues in the event's default language. No expand is required for these fields;\nuse `expand=translated_fields` for other locales.\n",
        "properties": {
          "id": {
            "type": "string"
          },
          "participant_role": {
            "$ref": "#/components/schemas/ParticipantRole",
            "description": "The event's configured program role for this participant (Sessions 2.0).\n`name` and `slug` reflect the configured `Session_Roles` record (for example\nAuthor, Panelist). `core_role` is the legacy junction category mapping only\n(`speaker`, `chairperson`, `moderator`) and must not be used as the display\nrole label. Present on legacy `speakers`, `chairpersons`, and `moderators`\nentries when the event has `Session_Roles` configured.\n"
          },
          "session_affiliation": {
            "$ref": "#/components/schemas/SessionAffiliation"
          },
          "friendly_id": {
            "type": "string"
          },
          "full_name": {
            "type": "string"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "photo_url": {
            "type": "string",
            "description": "URL of the contact's headshot. Images larger than 2 MB are delivered resized from this URL, scaled to fit within 2400 x 2400 pixels (a PNG may arrive as WebP for clients that accept it). The uploaded file is stored unchanged; for full-resolution originals use the bulk download tools in Sessionboard, such as **Download Headshots** (Contacts, More menu)."
          },
          "company_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "about": {
            "type": "string"
          },
          "phone_home": {
            "type": "string"
          },
          "phone_mobile": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_country": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "facebook_url": {
            "type": "string"
          },
          "instagram_url": {
            "type": "string"
          },
          "snapchat_username": {
            "type": "string"
          },
          "tiktok_username": {
            "type": "string"
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          }
        }
      },
      "SessionAffiliation": {
        "type": "object",
        "description": "The person's company and job title for this session only, set by an\norganizer on the session's participant list. A `null` value means\nthis session uses the contact's own `company_name` / `title`, so the\nvalue to display is `session_affiliation.company ?? company_name` and\n`session_affiliation.job_title ?? title`. Both keys are always present.\n",
        "required": [
          "company",
          "job_title"
        ],
        "properties": {
          "company": {
            "type": [
              "string",
              "null"
            ],
            "description": "Company for this session, or `null` to use the contact's."
          },
          "job_title": {
            "type": [
              "string",
              "null"
            ],
            "description": "Job title for this session, or `null` to use the contact's."
          }
        }
      },
      "ParticipantRole": {
        "type": "object",
        "description": "An event-configured session participant role (`Session_Roles`). Use `name` (or\n`slug` for programmatic matching) as the participant's role label. `core_role`\nis the legacy junction category only.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Session_Roles.id"
          },
          "slug": {
            "type": "string",
            "description": "Stable programmatic identifier for the role within the event."
          },
          "name": {
            "type": "string",
            "description": "Display name (singular)."
          },
          "name_plural": {
            "type": "string",
            "description": "Display name (plural)."
          },
          "core_role": {
            "type": "string",
            "enum": [
              "speaker",
              "chairperson",
              "moderator"
            ],
            "description": "Legacy junction category this role maps to for integrations."
          }
        }
      },
      "SessionParticipant": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionSpeaker"
          },
          {
            "type": "object",
            "description": "Sessions 2.0 participant row. Includes the same contact profile fields as\n`SessionSpeaker`. `participant_role` is always present (sourced from\n`Session_Roles`).\n",
            "properties": {
              "session_participant_id": {
                "type": "string",
                "format": "uuid",
                "description": "Primary key of the `Session_Participants` row."
              },
              "acceptance_status": {
                "type": "string",
                "enum": [
                  "pending",
                  "accepted",
                  "declined",
                  "not_accepted"
                ],
                "description": "The participant's answer to their acceptance invitation. Present only\nwhen the event has Participant Acceptance turned on\n(`features.speaker_acceptance`).\n"
              },
              "acceptance_invite_sent_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "When the acceptance invitation for this role was last sent, or `null`\nif it has not been sent. Present only when the event has Participant\nAcceptance turned on.\n"
              }
            }
          }
        ]
      },
      "ParticipantRoleAssignment": {
        "type": "object",
        "description": "One role a participant holds on the event, with the sessions it holds\nit on. Returned inside `Participant.roles`.\n",
        "required": [
          "roleId",
          "roleName",
          "slug",
          "coreRole",
          "isCustom",
          "sessionIds"
        ],
        "properties": {
          "roleId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The role's id — the value to pass in the `roleIds` filter and the\n`id` returned by `GET /v1/event/{eventId}/participant-roles`.\n`null` only for a standard role on an event whose roles have not\nbeen created yet (see the endpoint description).\n"
          },
          "roleName": {
            "type": "string",
            "description": "Display name of the role (singular), e.g. `Speaker`, `Panelist`."
          },
          "slug": {
            "type": "string",
            "description": "Stable programmatic identifier for the role within the event."
          },
          "coreRole": {
            "type": "string",
            "enum": [
              "speaker",
              "chairperson",
              "moderator"
            ],
            "description": "The standard category the role maps to. Not a display label."
          },
          "isCustom": {
            "type": "boolean",
            "description": "`true` for a role the organizer added; `false` for Speaker, Chairperson and Moderator."
          },
          "sessionIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Ids of the sessions (including subsessions) on which the contact holds this role."
          }
        }
      },
      "Participant": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Contact"
          },
          {
            "type": "object",
            "description": "A contact holding at least one session role on the event. Every\n`Contact` field is present with the same values `POST /speakers`\nreturns; `roles` is appended after them.\n",
            "required": [
              "roles"
            ],
            "properties": {
              "roles": {
                "type": "array",
                "description": "Every role the contact holds on the event and the sessions it\nholds each one on. Always the contact's complete set — not\nnarrowed by the request filters. Ordered by the role's\nconfigured sort order.\n",
                "items": {
                  "$ref": "#/components/schemas/ParticipantRoleAssignment"
                }
              }
            }
          }
        ],
        "examples": [
          {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "friendly_id": "SPK-42",
            "full_name": "Dr. Jane Smith",
            "first_name": "Jane",
            "last_name": "Smith",
            "email": "jane.smith@university.edu",
            "created_at": "2023-11-01T10:00:00Z",
            "updated_at": "2024-02-15T16:30:00Z",
            "company_name": "State University",
            "title": "Professor of Computer Science",
            "custom_fields": [],
            "roles": [
              {
                "roleId": "84bd12e5-d5ec-4c64-a604-4051e06c8dc2",
                "roleName": "Speaker",
                "slug": "speaker",
                "coreRole": "speaker",
                "isCustom": false,
                "sessionIds": [
                  "04efb360-2b15-44db-b639-4035fae2772c"
                ]
              },
              {
                "roleId": "4efeb845-050f-4002-9496-cb586cdf10f2",
                "roleName": "Moderator",
                "slug": "moderator",
                "coreRole": "moderator",
                "isCustom": false,
                "sessionIds": [
                  "26e465fc-1fb1-4c04-af52-f4d6314dfca4"
                ]
              },
              {
                "roleId": "52d60237-19db-4bda-a116-8b9fcb6750e9",
                "roleName": "Panelist",
                "slug": "panelist",
                "coreRole": "speaker",
                "isCustom": true,
                "sessionIds": [
                  "140b8e82-41ca-444e-82ab-f7dd1011e95b",
                  "2c198cce-adff-4fb2-81e1-319b601d564b"
                ]
              }
            ]
          }
        ]
      },
      "EventParticipantRole": {
        "type": "object",
        "description": "A participant role configured on an event, as returned by\n`GET /v1/event/{eventId}/participant-roles`.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Use as a `roleIds` filter value on `POST /v1/event/{eventId}/participants`."
          },
          "name": {
            "type": "string",
            "description": "Display name (singular)."
          },
          "name_plural": {
            "type": "string",
            "description": "Display name (plural)."
          },
          "slug": {
            "type": "string",
            "description": "Stable programmatic identifier within the event."
          },
          "core_role": {
            "type": "string",
            "enum": [
              "speaker",
              "chairperson",
              "moderator"
            ],
            "description": "The standard category the role maps to. Not a display label."
          },
          "is_custom": {
            "type": "boolean",
            "description": "`true` for a role the organizer added; `false` for the three standard roles."
          },
          "sort_order": {
            "type": "integer",
            "description": "Position in the Sessions settings page; results are returned in this order."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Sponsor": {
        "type": "object",
        "description": "A sponsor associated with an event.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "logo_image_url": {
            "type": "string"
          },
          "banner_image_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_coutnry": {
            "type": "string",
            "description": "Country (note: field name contains a known typo preserved for backwards compatibility)."
          },
          "facebook_url": {
            "type": "string"
          },
          "instagram_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "snapchat_username": {
            "type": "string"
          },
          "tiktok_username": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the sponsor last changed, from any source, including Public API creates, updates and bulk writes. Send it back as `updated_at` on an update for optimistic concurrency; the write returns the new value."
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountContact"
            }
          },
          "admin_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Deep link to this entity in the Sessionboard admin UI."
          }
        },
        "examples": [
          {
            "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
            "friendly_id": "SPON-3",
            "friendly_id_raw": 3,
            "name": "TechCorp Global",
            "description": "Platinum sponsor and technology partner.",
            "logo_image_url": "https://cdn.sessionboard.com/logos/techcorp.png",
            "phone": "+1-555-0100",
            "address_city": "San Francisco",
            "address_state": "CA",
            "address_coutnry": "US",
            "website_url": "https://www.techcorp.example.com",
            "linkedin_url": "https://www.linkedin.com/company/techcorp",
            "created_at": "2024-01-05T08:00:00Z",
            "updated_at": "2024-02-20T12:00:00Z",
            "custom_fields": [],
            "translated_fields": [],
            "contacts": []
          }
        ]
      },
      "SessionSponsor": {
        "type": "object",
        "description": "A sponsor associated with a session. Same shape as Sponsor.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "logo_image_url": {
            "type": "string"
          },
          "banner_image_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_coutnry": {
            "type": "string"
          },
          "facebook_url": {
            "type": "string"
          },
          "instagram_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "snapchat_username": {
            "type": "string"
          },
          "tiktok_username": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountContact"
            }
          }
        }
      },
      "Exhibitor": {
        "type": "object",
        "description": "An exhibitor associated with an event.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "logo_image_url": {
            "type": "string"
          },
          "banner_image_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_coutnry": {
            "type": "string",
            "description": "Country (note: field name contains a known typo preserved for backwards compatibility)."
          },
          "facebook_url": {
            "type": "string"
          },
          "instagram_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "snapchat_username": {
            "type": "string"
          },
          "tiktok_username": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the exhibitor last changed, from any source, including Public API creates, updates and bulk writes. Send it back as `updated_at` on an update for optimistic concurrency; the write returns the new value."
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountContact"
            }
          },
          "admin_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Deep link to this entity in the Sessionboard admin UI."
          }
        },
        "examples": [
          {
            "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
            "friendly_id": "EXH-7",
            "friendly_id_raw": 7,
            "name": "InnovateTech Labs",
            "description": "Showcasing next-generation event technology solutions.",
            "logo_image_url": "https://cdn.sessionboard.com/logos/innovatetech.png",
            "address_city": "Chicago",
            "address_state": "IL",
            "address_coutnry": "US",
            "website_url": "https://www.innovatetech.example.com",
            "created_at": "2024-01-12T10:00:00Z",
            "updated_at": "2024-03-01T14:00:00Z",
            "custom_fields": [],
            "translated_fields": [],
            "contacts": []
          }
        ]
      },
      "SessionExhibitor": {
        "type": "object",
        "description": "An exhibitor associated with a session. Same shape as Exhibitor.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "logo_image_url": {
            "type": "string"
          },
          "banner_image_url": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address_line_1": {
            "type": "string"
          },
          "address_line_2": {
            "type": "string"
          },
          "address_city": {
            "type": "string"
          },
          "address_state": {
            "type": "string"
          },
          "address_postal_code": {
            "type": "string"
          },
          "address_coutnry": {
            "type": "string"
          },
          "facebook_url": {
            "type": "string"
          },
          "instagram_url": {
            "type": "string"
          },
          "linkedin_url": {
            "type": "string"
          },
          "snapchat_username": {
            "type": "string"
          },
          "tiktok_username": {
            "type": "string"
          },
          "twitter_url": {
            "type": "string"
          },
          "website_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "translated_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranslatedField"
            }
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountContact"
            }
          }
        }
      },
      "AccountContact": {
        "type": "object",
        "description": "A contact associated with a sponsor or exhibitor account.",
        "properties": {
          "id": {
            "type": "string"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "full_name": {
            "type": "string"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "photo_url": {
            "type": "string",
            "description": "URL of the contact's headshot. Images larger than 2 MB are delivered resized from this URL, scaled to fit within 2400 x 2400 pixels (a PNG may arrive as WebP for clients that accept it). The uploaded file is stored unchanged; for full-resolution originals use the bulk download tools in Sessionboard, such as **Download Headshots** (Contacts, More menu)."
          },
          "company_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "about": {
            "type": "string"
          },
          "is_primary": {
            "type": "boolean"
          },
          "contact_created_at": {
            "type": "string"
          },
          "contact_updated_at": {
            "type": "string"
          },
          "relationship_created_at": {
            "type": "string"
          },
          "relationship_updated_at": {
            "type": "string"
          }
        }
      },
      "CustomFieldValue": {
        "type": "object",
        "description": "A custom field value attached to a record.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "value": {
            "type": [
              "string",
              "boolean",
              "null"
            ],
            "description": "The formatted field value, or `null` when the field is empty.\nNumeric field types (`number`, `currency`, `percent`, `quantity`,\n`formula`) serialize a stored zero as its formatted value (for\nexample `\"0\"`) — `null` means the field has no value, not that\nthe value is zero.\n\n`checkbox` fields serialize as the strings `\"Yes\"` (checked) and\n`\"No\"` (explicitly unchecked); a checkbox that was never set is\n`null`. Writes take boolean `true` / `false`.\n\n`datetime` fields serialize as ISO 8601. On event custom fields\n(`GET /v1/events?expand=custom_fields`) the value is event-local\ntime with the event's UTC offset (for example\n`2026-08-15T09:00:00-03:00`), falling back to the raw UTC\ninstant (`2026-08-15T12:00:00.000Z`) when the event has no valid\ntimezone. On session, speaker, sponsor, and exhibitor custom\nfields the value is the raw UTC instant.\n\n`date` (date-only) fields serialize as `M-DD-YYYY`: month without\na leading zero, day with one, four-digit year (for example\n`9-22-2026` for 22 September 2026, `3-04-2026` for 4 March 2026).\nThis is not ISO 8601; parse it with that exact pattern.\n"
          },
          "type": {
            "type": "string"
          },
          "internal_name": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        }
      },
      "TranslatedField": {
        "type": "object",
        "description": "A translated version of a field value.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "parent_field_id": {
            "type": "string"
          },
          "parent_field_source": {
            "type": "string"
          },
          "parent_field_name": {
            "type": "string"
          },
          "parent_field_internal_name": {
            "type": "string"
          },
          "translated_language": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "TranslatedFieldWrite": {
        "type": "object",
        "description": "Write shape for `translated_fields` on create/update. Same identifying\nkeys as the read `TranslatedField` object; extra read-only properties\n(`id`, `name`, `parent_field_id`, …) are ignored if sent.\n\nValidation (applies before anything is written — an invalid entry fails\nthe whole request with `400` `VALIDATION_ERROR` and nothing is\npartially saved):\n- `translated_fields` must be an array of these objects.\n- Every entry must include a non-empty `translated_language`.\n- `translated_language` must be one of the event's enabled locales\n  (the event default plus enabled language variants, e.g. `en_US`,\n  `ar`). The error message lists the enabled locales.\n",
        "required": [
          "parent_field_internal_name",
          "translated_language"
        ],
        "properties": {
          "parent_field_internal_name": {
            "type": "string"
          },
          "translated_language": {
            "type": "string",
            "description": "Locale code for the language variant (for example `fr` or `ar`).\nMust be enabled on the event; otherwise the request fails with `400`.\n"
          },
          "value": {
            "description": "Value for that locale. Same type as the parent field."
          }
        }
      },
      "Content": {
        "type": "object",
        "description": "A content attachment (file, document, or media) associated with a session.\n\n**Approvals.** On events using Approvals (Early Access), a file can be held\nback until it is approved and its release time has passed. The Session Files\nendpoints still list a held file, so an integration knows it exists, but return\n`url: null` until it is released. Publish only files whose `approval_status`\nis `approved` or `not_required`. When a file you already published moves to\nany other status, remove it from your destination.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Download URL. `null` while Approvals holds the file back (see\n`approval_status`), so nothing built on the API can publish it early.\n"
          },
          "title": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "mimetype": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "nullable": true,
            "description": "Organizer-facing file type, e.g. `presentation`, `handout`,\n`poster`, or `holding_slide` for slides generated by Sessionboard.\nFilterable with `?type=` on the list endpoint.\n",
            "example": "holding_slide"
          },
          "label": {
            "type": "string",
            "nullable": true,
            "description": "Display label shown on the session's Files tab, e.g. `Holding Slide`.",
            "example": "Holding Slide"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "assigned_participant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Contact UUID of the session participant this file is assigned to."
          },
          "assigned_participant_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "assigned_participant_name": {
            "type": "string",
            "nullable": true
          },
          "content_slot_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The upload slot this file answers — see\n`GET /v1/event/{eventId}/content-slots`. Present only while the\nevent uses upload slots; `null` for events on a single file\nrequest, and for files uploaded before slots existed or outside\nany slot.\n"
          },
          "approval_status": {
            "type": "string",
            "enum": [
              "not_required",
              "pending",
              "approved",
              "denied",
              "superseded",
              "embargoed"
            ],
            "description": "Approval state, returned by the Session Files endpoints.\n- `not_required`: not under an approval workflow (no workflow, workflow off, or uploaded before it was turned on).\n- `pending`: waiting on a reviewer.\n- `approved`: approved and released.\n- `denied`: sent back to the uploader for changes.\n- `superseded`: a newer version replaced it before it was decided.\n- `embargoed`: approved (or not required) but held until a release time; see `embargo_until`.\n\nOnly `approved` and `not_required` files have a `url`.\n",
            "example": "approved"
          },
          "embargo_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When an `embargoed` file is released (UTC). `null` when it is not\nembargoed, or when it waits for its session to be scheduled (release\n\"when each file's session starts\").\n"
          }
        }
      },
      "ContentSlot": {
        "type": "object",
        "description": "One file an event asks its speakers for (SB \"upload slot\"). Slots are\nconfigured under Program → Settings → Files; `session_filters` and\nrole restrictions are internal and not exposed.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "The name speakers see, e.g. \"Poster\"."
          },
          "content_type": {
            "type": "string",
            "enum": [
              "poster",
              "presentation",
              "handout",
              "abstract",
              "custom"
            ],
            "description": "What kind of file the slot collects. Poster galleries read `poster` slots."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Instructions shown to speakers above the drop zone."
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Deadline shown to speakers. `null` means no deadline."
          },
          "due_date_extended": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Later date the drop zone stays open until, if the organizer set one."
          },
          "allowed_file_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Accepted type keys (`pdf`, `ppt`, `word`, `excel`, `image`, `png`,\n`jpeg`, `gif`, `svg`, `video`, `mp4`, `audio`, `zip`, `csv`,\n`text`). An empty array accepts any type.\n"
          },
          "required": {
            "type": "boolean",
            "description": "Whether the slot counts as missing until a file is uploaded."
          },
          "min_files": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_files": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Maximum files per session; `null` means unlimited."
          },
          "allow_after_deadline": {
            "type": "boolean",
            "description": "Whether uploads are still accepted after the deadline."
          },
          "order": {
            "type": "integer",
            "description": "Position in the list speakers see (0-based)."
          },
          "is_active": {
            "type": "boolean",
            "description": "`false` for archived slots (only returned with `include_archived=true`)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ContentSlotListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentSlot"
            }
          }
        }
      },
      "Tag": {
        "type": "object",
        "description": "An event taxonomy tag that can be applied to sessions.\n\nThe list, create, and update endpoints return `type`, `color`, and\n`order`; tags nested inside a `Session` response and the search\nendpoint (`POST /tags`) return the identifying fields only.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "tag"
            ]
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "order": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Track": {
        "type": "object",
        "description": "A session track (e.g., a conference track or topic area).\n\nWhen nested inside a `Session` response, includes `event_id`. Standalone\nmetadata list and search endpoints (`GET`/`POST /tracks`) omit `event_id`\nbecause the event is implicit from the URL.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Language": {
        "type": "object",
        "description": "A language configured for an event.\n\nWhen nested inside a `Session` response, includes `event_id`. Standalone\nmetadata list and search endpoints (`GET`/`POST /languages`) omit\n`event_id` because the event is implicit from the URL.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Format": {
        "type": "object",
        "description": "A session format (e.g., Workshop, Panel, Keynote).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Level": {
        "type": "object",
        "description": "A session difficulty level (e.g., Beginner, Intermediate, Advanced).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Room": {
        "type": "object",
        "description": "A room or venue location for sessions. When nested inside a `Session`\nresponse, `room` is only populated when the session `location` is\n`room` (not for external URLs).\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "capacity": {
            "type": "integer",
            "nullable": true,
            "description": "Maximum room capacity. Returned on nested session `room` objects and\nstandalone room list/search endpoints.\n"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Subsession": {
        "type": "object",
        "description": "A subsession nested within a parent session. This is the default\nminimal shape returned inside `parent.subsessions[]` when the\n`subsession_details` expand value is not requested.\n\nTo receive the full parent-shape parity (`status`, `custom_status`,\n`custom_fields`, `chairpersons`, `moderators`, `sponsors`,\n`exhibitors`, `tags`, `language`, `track`, `level`, `room`, etc.),\npass `expand=subsession_details` on the GET or POST search request.\nSee the `SubsessionDetailed` schema.\n\n`is_abstract`, `composition_status`, and optional `composition`\n(when `expand=composition`) are inherited from the parent session.\n\nAlternatively, call `GET /v1/event/{eventId}/sessions/{sessionId}`\nwith the subsession's UUID directly — the endpoint always returns the\nfull session shape at the top level.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string",
            "description": "Human-readable id formatted as `<event-prefix>-<parent-friendly-id>-<subsession-number>` (or `<event-prefix>-<subsession-friendly-id>` when the event has `show_subsession_friendly_id` enabled)."
          },
          "friendly_id_raw": {
            "type": "integer",
            "description": "Underlying numeric friendly id (the suffix of `friendly_id`)."
          },
          "parent_session_friendly_id": {
            "type": "string",
            "description": "Human-readable friendly id of the parent session, e.g. `SESS-3370`."
          },
          "parent_session_friendly_id_raw": {
            "type": "integer",
            "description": "Numeric friendly id of the parent session."
          },
          "subsession_order": {
            "type": "integer",
            "nullable": true,
            "description": "Admin-defined position among the parent session's subsessions; subsessions are returned in this order, falling back to subsession number and start time. `null` when the parent's subsessions have never been reordered."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "translated_fields": {
            "type": "array",
            "description": "Present only when `expand=translated_fields` is set and the event has language variants configured.",
            "items": {
              "type": "object"
            }
          },
          "speakers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "participants": {
            "type": "array",
            "description": "Sessions 2.0 participants for this subsession (see `Session.participants`).",
            "items": {
              "$ref": "#/components/schemas/SessionParticipant"
            }
          },
          "is_abstract": {
            "type": "boolean",
            "description": "Inherited from the parent session."
          },
          "composition_status": {
            "$ref": "#/components/schemas/CompositionStatus"
          },
          "format": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Content"
            }
          }
        }
      },
      "SubsessionDetailed": {
        "type": "object",
        "description": "Full-parity subsession returned inside `parent.subsessions[]` when the\n`subsession_details` expand value is set on the request. The shape\nmirrors `Session` (minus the recursive `subsessions` property, since\nsubsessions cannot be nested) and adds the parent-friendly-id fields\nso callers can iterate the array and then call\n`GET /v1/event/{eventId}/sessions/{sessionId}` with each subsession\nid for the same shape at the top level.\n\n`is_abstract`, `composition_status`, and optional `composition`\n(when `expand=composition`) are inherited from the parent session.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "parent_session_friendly_id": {
            "type": "string"
          },
          "parent_session_friendly_id_raw": {
            "type": "integer"
          },
          "subsession_order": {
            "type": "integer",
            "nullable": true,
            "description": "Admin-defined position among the parent session's subsessions; subsessions are returned in this order, falling back to subsession number and start time. `null` when the parent's subsessions have never been reordered."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "custom_status_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "custom_status": {
            "$ref": "#/components/schemas/SessionCustomStatus"
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time"
          },
          "is_public": {
            "type": "boolean"
          },
          "is_abstract": {
            "type": "boolean",
            "description": "Inherited from the parent session."
          },
          "composition_status": {
            "$ref": "#/components/schemas/CompositionStatus"
          },
          "external_url": {
            "type": "string",
            "nullable": true
          },
          "client_session_id": {
            "type": "string",
            "nullable": true
          },
          "ceu_credits": {
            "type": "number",
            "nullable": true
          },
          "capacity": {
            "type": "integer",
            "nullable": true
          },
          "translated_fields": {
            "type": "array",
            "description": "Present only when `expand=translated_fields` is set and the event has language variants configured.",
            "items": {
              "type": "object"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          },
          "speakers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "chairpersons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "moderators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionSpeaker"
            }
          },
          "participants": {
            "type": "array",
            "description": "Sessions 2.0 participants for this subsession (see `Session.participants`).",
            "items": {
              "$ref": "#/components/schemas/SessionParticipant"
            }
          },
          "sponsors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sponsor"
            }
          },
          "exhibitors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Exhibitor"
            }
          },
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Content"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Language"
              }
            ],
            "description": "Same shape as `Session.language` when assigned; `{}` when unassigned."
          },
          "track": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Track"
              }
            ],
            "description": "Same shape as `Session.track` when assigned; `{}` when unassigned."
          },
          "level": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Level"
              }
            ],
            "description": "Same shape as `Session.level` when assigned; `{}` when unassigned."
          },
          "format": {
            "type": "object",
            "description": "Nested format includes only `id` and `name`.",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "room": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Room"
              }
            ],
            "description": "Same shape as `Session.room` when `location` is `room`; `{}` when\nlocation is external or unset.\n"
          },
          "source": {
            "type": "string"
          }
        },
        "examples": [
          {
            "id": "ff14c2e4-2abf-4610-8267-0d2935f19576",
            "friendly_id": "SESS-3370-3",
            "friendly_id_raw": 3052,
            "parent_session_friendly_id": "SESS-3370",
            "parent_session_friendly_id_raw": 3370,
            "title": "Imagining a better tomorrow",
            "status": "accepted",
            "is_public": true,
            "custom_status": null,
            "custom_fields": [
              {
                "id": "749c5737-cde4-44cc-acf6-15a6ccf74a5f",
                "name": "Co-authors",
                "type": "textarea",
                "internal_name": "co_authors",
                "value": "Mohamed Tarik, Mar...",
                "created_at": "2026-01-21T13:15:57.710Z"
              }
            ],
            "chairpersons": [],
            "moderators": [],
            "sponsors": [],
            "exhibitors": [],
            "tags": [],
            "speakers": [],
            "content": [],
            "language": {
              "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
              "event_id": 72,
              "name": "English",
              "order": 0,
              "created_at": "2025-01-01T00:00:00Z",
              "updated_at": "2025-02-01T00:00:00Z"
            },
            "track": {
              "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
              "event_id": 72,
              "name": "Artificial Intelligence & ML",
              "color": "#329af0",
              "order": 1,
              "created_at": "2025-01-01T00:00:00Z",
              "updated_at": "2025-02-01T00:00:00Z"
            },
            "level": {
              "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
              "name": "Beginner",
              "order": 2,
              "created_at": "2025-01-01T00:00:00Z",
              "updated_at": "2025-02-01T00:00:00Z"
            },
            "format": {
              "id": "d4e5f6a7-b8c9-0123-def0-234567890123",
              "name": "Technical Programme Forum Paper"
            },
            "room": {
              "id": "e5f6a7b8-c9d0-1234-ef01-345678901234",
              "name": "Workshop Room 1",
              "order": 3,
              "capacity": 120,
              "created_at": "2025-01-01T00:00:00Z",
              "updated_at": "2025-02-01T00:00:00Z"
            },
            "source": "Manual"
          }
        ]
      },
      "SubsessionStatus": {
        "type": "object",
        "description": "A lightweight representation of a subsession's status, included as part of the parent SessionStatus response.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "friendly_id": {
            "type": "string"
          },
          "friendly_id_raw": {
            "type": "integer"
          },
          "parent_session_friendly_id": {
            "type": "string"
          },
          "parent_session_friendly_id_raw": {
            "type": "integer"
          },
          "subsession_order": {
            "type": "integer",
            "nullable": true,
            "description": "Admin-defined position among the parent session's subsessions; subsessions are returned in this order, falling back to subsession number and start time. `null` when the parent's subsessions have never been reordered."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "The subsession's own approval status from the database. The API does\nnot inherit the parent session's status. May be null when the\nsubsession has no explicit status set.\n"
          },
          "custom_status_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "custom_status": {
            "$ref": "#/components/schemas/SessionCustomStatus"
          },
          "deleted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SessionCustomStatus": {
        "type": "object",
        "description": "A custom session status definition configured for an event.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Approval state this custom label maps onto. Stored NOT NULL, so it\nis always present on a status created through this API.\n",
            "enum": [
              "pending",
              "accepted",
              "declined",
              "accept_queue",
              "decline_queue"
            ]
          },
          "status_name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string"
          },
          "order": {
            "type": "integer"
          },
          "is_custom": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "nullable": true
          },
          "created_by_user_id": {
            "type": "integer",
            "nullable": true
          },
          "created_by_user_name": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "GDPRRequest": {
        "type": "object",
        "description": "A GDPR data access or erasure request, and the record of what it did.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of the stored request. Quote this when evidencing a DSAR."
          },
          "org_id": {
            "type": "string"
          },
          "request_type": {
            "type": "string",
            "enum": [
              "erasure",
              "access"
            ]
          },
          "identity_type": {
            "type": "string",
            "enum": [
              "email"
            ]
          },
          "identity_value": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "complete",
              "no_records_found",
              "pending"
            ],
            "description": "Outcome of the request.\n\n- `complete` — at least one record matched and was processed.\n- `no_records_found` — nothing in this organization matched the\n  email, so nothing was erased.\n- `pending` — the request is stored but has not finished\n  processing.\n"
          },
          "matching_user_exists": {
            "type": "boolean",
            "description": "True when the email matched at least one record of any kind."
          },
          "response": {
            "type": "object",
            "description": "What the request matched and what happened to it. `people`, `users_scrubbed`, `users_retained` and `counts` are present on requests processed recently and absent on older records; an absent field means \"not recorded\", not \"zero\".",
            "properties": {
              "users": {
                "type": "array",
                "description": "User accounts identified for this email.",
                "items": {
                  "type": "integer"
                }
              },
              "org_users": {
                "type": "array",
                "description": "Organization membership records removed.",
                "items": {
                  "type": "string"
                }
              },
              "event_users": {
                "type": "array",
                "description": "Event participation records removed.",
                "items": {
                  "type": "integer"
                }
              },
              "contact_records": {
                "type": "array",
                "description": "Contact records marked deleted.",
                "items": {
                  "type": "string"
                }
              },
              "people": {
                "type": "array",
                "description": "Person records whose personal data was scrubbed in place.",
                "items": {
                  "type": "string"
                }
              },
              "users_scrubbed": {
                "type": "array",
                "description": "User accounts whose personal data was de-identified.",
                "items": {
                  "type": "integer"
                }
              },
              "users_retained": {
                "type": "array",
                "description": "User accounts left intact because they still belong to another organization, with the reason recorded.",
                "items": {
                  "type": "object"
                }
              },
              "counts": {
                "type": "object",
                "description": "Per-category totals for the arrays above.",
                "properties": {
                  "org_users": {
                    "type": "integer"
                  },
                  "event_users": {
                    "type": "integer"
                  },
                  "contact_records": {
                    "type": "integer"
                  },
                  "people": {
                    "type": "integer"
                  },
                  "users_identified": {
                    "type": "integer"
                  },
                  "users_scrubbed": {
                    "type": "integer"
                  },
                  "users_retained": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        }
      },
      "Field": {
        "type": "object",
        "description": "A field definition (standard or custom) for an event module.",
        "properties": {
          "id": {
            "type": "string"
          },
          "internal_name": {
            "type": "string"
          },
          "public_name": {
            "type": "string"
          },
          "field_type": {
            "type": "string"
          },
          "field_source": {
            "type": "string"
          },
          "contains_pii": {
            "type": "boolean",
            "description": "Whether this field contains personally identifiable information (PII)."
          },
          "scope": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        }
      },
      "BulkOperations": {
        "type": "object",
        "description": "Request body for bulk create/update/delete operations.\n\nOperations are applied in request order, each in its own transaction,\nand `results[i]` describes `operations[i]`. A failed operation is\nrolled back whole and does not stop the ones after it.\n",
        "required": [
          "operations"
        ],
        "properties": {
          "operations": {
            "type": "array",
            "maxItems": 100,
            "description": "Array of operations to execute (max 100).",
            "items": {
              "type": "object",
              "required": [
                "action"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "enum": [
                    "create",
                    "update",
                    "delete"
                  ],
                  "description": "The operation to perform."
                },
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Entity ID. Required for `update` and `delete` actions."
                },
                "data": {
                  "type": "object",
                  "description": "Entity-specific fields. Required for `create` and `update` actions.\nSession create supports `is_abstract` (boolean, default false).\n`is_abstract` cannot be changed on update.\n\n`data` takes the same fields as the matching single-record\ncreate/update endpoint, including `custom_fields` and\n`translated_fields`. A `translated_fields` entry for a\nlanguage the event has not enabled fails that operation with\n`400` and rolls it back — it is no longer accepted and\ndiscarded.\n\n`custom_fields` is honoured on the contacts, sessions,\nexhibitors and sponsors bulk endpoints. An unknown\n`internal_name`, a value of the wrong type, or a field owned\nby an integration fails **that operation only** — the\noperations around it in the same batch still commit.\n\n**Exception — draft sessions.** `POST\n/event/{eventId}/agenda-drafts/{draftId}/sessions/bulk` does\nnot accept `custom_fields`, and neither does its\nsingle-record sibling. A draft session is a scheduling\nplacement of an existing session inside a draft agenda, not a\nrecord of its own, so it has no custom fields to write. Set\ncustom fields on the underlying session through\n`/event/{eventId}/sessions`.\n"
                }
              }
            }
          }
        }
      },
      "BulkResponse": {
        "type": "object",
        "description": "Response body for bulk operations, including per-item results.",
        "properties": {
          "batch_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for this bulk batch."
          },
          "results": {
            "type": "array",
            "description": "Per-operation results in the same order as the request.",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "description": "Zero-based index of the operation in the request array."
                },
                "action": {
                  "type": "string",
                  "description": "The action that was performed (create, update, delete)."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "success",
                    "created",
                    "associated",
                    "updated",
                    "deleted",
                    "error"
                  ],
                  "description": "Whether this individual operation succeeded or failed.\n\nMost bulk endpoints report `success` or `error`. The contacts\nbulk endpoint instead names the outcome: `created`,\n`associated` (the email already existed in the organization\nand was linked to this event), `updated`, `deleted`, or\n`error`. Treat anything other than `error` as a success.\n"
                },
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "The ID of the created or affected entity."
                },
                "error": {
                  "description": "Error details, present only when `status` is `error`.\n\nAn object with `code` and `message` on most bulk endpoints.\nOn the contacts bulk endpoint `error` is a plain string and\nthe code is returned alongside it as `error_code`; that\ndifference is longstanding and is kept so existing callers\nreading the string keep working.\n",
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Machine-readable error code."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable error description."
                        },
                        "valid_options": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Present only when `code` is `TYPE_MISMATCH` on a\n`dropdown` field: every value the field accepts,\none array entry per option, in the field's option\norder. An option label can itself contain a comma\n(`\"Banana, Chocolate\"`), so read this array rather\nthan splitting the list in `message`. Absent on\nevery other error.\n"
                        }
                      },
                      "example": {
                        "code": "TYPE_MISMATCH",
                        "message": "Field 'product_type' value 'Banana' is not a valid option. Valid options: [\"1\", \"Banana, Chocolate\", \"Blue, Green, Violet\", \"10\"]",
                        "valid_options": [
                          "1",
                          "Banana, Chocolate",
                          "Blue, Green, Violet",
                          "10"
                        ]
                      }
                    },
                    {
                      "type": "string",
                      "description": "Human-readable error description (contacts bulk)."
                    }
                  ]
                },
                "error_code": {
                  "type": "string",
                  "description": "Machine-readable error code. Returned by the contacts bulk endpoint alongside the string `error`."
                }
              }
            }
          },
          "summary": {
            "type": "object",
            "description": "Aggregate counts for the batch. This page previously named the object `stats`; every bulk endpoint has always returned it as `summary`.",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Total number of operations in the batch."
              },
              "succeeded": {
                "type": "integer",
                "description": "Number of operations that succeeded — every row whose `status` is not `error`, including the contacts bulk endpoint's `created`, `associated`, `updated` and `deleted`."
              },
              "failed": {
                "type": "integer",
                "description": "Number of operations that failed."
              }
            }
          }
        }
      },
      "AgendaDraft": {
        "type": "object",
        "description": "An agenda draft workspace for planning session schedule changes before committing them to the live event.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "committed"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "admin_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Deep link to this entity in the Sessionboard admin UI."
          }
        }
      },
      "DraftSession": {
        "type": "object",
        "description": "A session placement within an agenda draft.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "draft_id": {
            "type": "string",
            "format": "uuid"
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "ends_at": {
            "type": "string",
            "format": "date-time"
          },
          "room_id": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EventRule": {
        "type": "object",
        "description": "A scheduling constraint or validation rule for an event.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "config": {
            "type": "object",
            "additionalProperties": true
          },
          "enabled": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Persona": {
        "type": "object",
        "description": "An evaluation persona representing an attendee type for schedule evaluation.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "config": {
            "type": "object",
            "additionalProperties": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TranscriptionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Transcription"
          }
        }
      },
      "TranscriptionListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transcription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "TranscriptionElement": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "speaker": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "name": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "start_time": {
            "type": "number"
          },
          "end_time": {
            "type": "number"
          },
          "fragment_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "ContentItem": {
        "type": "object",
        "description": "Typed item inside a session or event content pack.",
        "properties": {
          "id": {
            "oneOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "transcription",
              "summary",
              "insight",
              "podcast",
              "document",
              "recap"
            ]
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "text": {
            "type": "string",
            "description": "Full joined transcript (transcription items)."
          },
          "elements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TranscriptionElement"
            }
          },
          "fragment_count": {
            "type": "integer"
          },
          "interval_sec": {
            "type": "integer",
            "nullable": true
          },
          "language_code": {
            "type": "string"
          },
          "summary_type": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "content": {
            "type": "object"
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "insight_type": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "duration_sec": {
            "type": "integer",
            "nullable": true
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "document_type": {
            "type": "string",
            "enum": [
              "summary_pdf",
              "summary_card",
              "event_report"
            ]
          },
          "content_type": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "quotes": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "summaries": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SessionContent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Session id"
          },
          "event_id": {
            "type": "integer"
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "starts_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "speakers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "has_transcription": {
            "type": "boolean"
          },
          "has_summary": {
            "type": "boolean"
          },
          "has_podcast": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentItem"
            }
          }
        }
      },
      "SessionContentResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionContent"
          }
        }
      },
      "SessionContentListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionContent"
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "current_page": {
                "type": "integer"
              },
              "page_size": {
                "type": "integer"
              },
              "total_pages": {
                "type": "integer"
              },
              "total_results": {
                "type": "integer"
              }
            }
          }
        }
      },
      "EventContent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Event id"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentItem"
            }
          }
        }
      },
      "EventContentResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/EventContent"
          }
        }
      },
      "ContentItemResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ContentItem"
          }
        }
      },
      "Transcription": {
        "type": "object",
        "description": "Polymorphic transcription artifact. Fields vary by type.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "fragment",
              "summary",
              "insight",
              "translation"
            ]
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "transcription": {
            "type": "string"
          },
          "speaker": {
            "type": "string"
          },
          "is_partial": {
            "type": "boolean"
          },
          "provider": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TranscriptionCreateRequest": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "fragment",
              "summary",
              "insight",
              "translation"
            ]
          },
          "transcription": {
            "type": "string"
          }
        }
      },
      "Recording": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "example": "recording"
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "s3_bucket": {
            "type": "string"
          },
          "s3_key": {
            "type": "string",
            "description": "After complete, non-PCM uploads are stored as `.pcm` keys."
          },
          "encoding": {
            "type": "string",
            "example": "linear16"
          },
          "sample_rate": {
            "type": "integer",
            "example": 16000
          },
          "channels": {
            "type": "integer",
            "example": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "recording",
              "completed"
            ]
          },
          "duration_seconds": {
            "type": "number"
          },
          "file_size_bytes": {
            "type": "integer"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "mp3_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "6-hour presigned HTTPS URL for an MP3 sibling of the original PCM take. Null while the recording is in progress or if transcode has not succeeded yet. Download and store this file — do not hotlink it as a permanent CDN URL. Session PDFs and user-uploaded files stay on `/content` and `/files`.\n"
          },
          "mp3_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When `mp3_url` stops working. Request the recording again to refresh the URL."
          }
        }
      },
      "RecordingResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Recording"
          }
        }
      },
      "RecordingCreateResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Recording"
              },
              {
                "type": "object",
                "properties": {
                  "upload": {
                    "type": "object",
                    "properties": {
                      "url": {
                        "type": "string"
                      },
                      "method": {
                        "type": "string",
                        "example": "PUT"
                      },
                      "headers": {
                        "type": "object",
                        "properties": {
                          "Content-Type": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "MediaItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "example": "media_item"
          },
          "title": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "event_id": {
            "type": "integer"
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "media_s3_key": {
            "type": "string"
          },
          "transcript_status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "ready",
              "failed"
            ]
          },
          "duration_seconds": {
            "type": "number"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MediaItemResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MediaItem"
          }
        }
      },
      "SessionFileCreateRequest": {
        "type": "object",
        "required": [
          "filename",
          "size_bytes"
        ],
        "properties": {
          "filename": {
            "type": "string",
            "description": "Original filename including extension (e.g. `slides.pptx`, `handout.pdf`).",
            "example": "keynote-slides.pptx"
          },
          "size_bytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 524288000,
            "description": "Exact file size in bytes. Maximum 500 MB (524288000) for direct-to-storage upload. Use `POST .../files/upload` for files up to 50 MB without specifying size."
          },
          "content_type": {
            "type": "string",
            "description": "MIME type. Optional; inferred from the filename extension when omitted.",
            "example": "application/vnd.openxmlformats-officedocument.presentationml.presentation"
          },
          "mimetype": {
            "type": "string",
            "description": "Alias for `content_type`."
          },
          "title": {
            "type": "string",
            "description": "Display title. Defaults to `filename`."
          },
          "assigned_participant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Contact UUID of a session participant to assign this file to."
          },
          "content_slot_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "The [upload slot](/api-reference/session-files/list-upload-slots)\nthis file answers. Optional — API callers act as the organization,\nso no slot deadline applies and a file may be attached without a\nslot. When set, the slot must be active, apply to the session\n(`GET .../content-slots?session_id=`), accept the file's declared\ntype and have room under its `max_files`; otherwise `400` names the\nslot. The file's `type` is derived from the slot's `content_type`.\nIgnored on events that still use a single file request.\n"
          }
        }
      },
      "SessionFileUpdateRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "nullable": true
          },
          "assigned_participant_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        }
      },
      "SessionFileResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Content"
          }
        }
      },
      "SessionFileListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Content"
            }
          }
        }
      },
      "SessionFileCreateResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Content"
              },
              {
                "type": "object",
                "properties": {
                  "upload": {
                    "type": "object",
                    "properties": {
                      "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Presigned S3 URL — PUT the file bytes here."
                      },
                      "method": {
                        "type": "string",
                        "example": "PUT"
                      },
                      "headers": {
                        "type": "object",
                        "properties": {
                          "Content-Type": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    },
    "responses": {
      "SharingForbidden": {
        "description": "- `SCOPE_REQUIRED`: the token lacks `read:events` (reads) or `write:marketing` (writes).\n- `EVENT_NOT_ALLOWED`: the event is outside the token's event allow-list.\n- Otherwise the token's user cannot read (or edit) sharing on this webinar.\n"
      },
      "SharingNotAWebinar": {
        "description": "The event is not a webinar."
      },
      "TasksForbidden": {
        "description": "- `TASKS_PLATFORM_ONLY`: the organization uses a self-serve Sessionboard product; Tasks are part of Sessionboard Platform.\n- `SCOPE_REQUIRED`: the key lacks `read:tasks` (reads) or `write:tasks` (writes). Legacy keys with no scopes can read but not write.\n- `ORG_WIDE_TOKEN_REQUIRED`: the key is restricted to particular events; Tasks need a key without an event restriction.\n- `FORBIDDEN`: the key's user can read this task but not change it (only the assignee, the creator, a follower or an admin can; only the creator or an admin can delete), or cannot use Tasks (reviewers and portal users).\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TaskApiError"
            },
            "examples": {
              "platform_only": {
                "summary": "A self-serve organization",
                "value": {
                  "error": "TASKS_PLATFORM_ONLY",
                  "message": "Tasks are part of Sessionboard Platform."
                }
              },
              "scope_required": {
                "summary": "The key lacks write:tasks",
                "value": {
                  "error": "SCOPE_REQUIRED",
                  "message": "Token missing required scope: write:tasks"
                }
              }
            }
          }
        }
      },
      "LearningForbidden": {
        "description": "- `SCOPE_REQUIRED` — the token lacks `read:learning` (reads) or `write:learning` (writes). Legacy tokens with no scopes cannot write.\n- `FORBIDDEN` — Learning is not on for the organization, or the token's user lacks the Lessons permission.\n"
      }
    }
  }
}
