> ## Documentation Index
> Fetch the complete documentation index at: https://support.rallly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a poll

> Creates a poll and responds with `201 Created` and the full poll, exactly as `GET /polls/:pollId` returns it. Share `inviteUrl` with participants. The request mirrors the response: `kind` chooses what participants vote on, and `options` takes the same shape the poll returns, so a poll can be recreated from the body of a `GET`. A poll has at most 100 options.

## Date poll

Pass `kind: "date"` and `options`, one `{ "date": "YYYY-MM-DD" }` per day. Each becomes one all-day option. Dates are floating calendar days with no timezone, so never convert them through one. Duplicate dates are removed.

```json
{
  "title": "Team offsite",
  "kind": "date",
  "options": [{ "date": "2027-03-01" }, { "date": "2027-03-02" }, { "date": "2027-03-03" }]
}
```

## Time poll

Pass `kind: "time"`, optionally a `timeZone` (an IANA zone the times are written in) and a default `duration` in minutes, and the slots as `options`, `generators` or both.

### Explicit slots

Each entry in `options` is one slot: a `startTime` and an optional `duration` that overrides the poll default. A `startTime` with no offset, like `2027-03-01T09:00:00`, is wall clock time in `timeZone` when that is set and a floating time with no conversion otherwise; one with an offset or `Z` is an absolute instant.

```json
{
  "title": "Kickoff",
  "kind": "time",
  "timeZone": "Europe/London",
  "duration": 60,
  "options": [
    { "startTime": "2027-03-01T09:00:00" },
    { "startTime": "2027-03-02T14:00:00", "duration": 90 }
  ]
}
```

### Slot generators

Each object in `generators` expands into recurring slots of `duration` minutes from a schedule, so availability across days or weeks does not have to be listed slot by slot. `duration` is required when `generators` is set.

```json
{
  "title": "Interview availability",
  "kind": "time",
  "timeZone": "America/New_York",
  "duration": 30,
  "generators": [
    {
      "startDate": "2027-03-01",
      "endDate": "2027-03-05",
      "days": ["mon", "tue", "wed", "thu", "fri"],
      "from": "09:00",
      "to": "12:00",
      "interval": 60
    }
  ]
}
```

This produces 30 minute slots at 09:00, 10:00 and 11:00 New York time on each weekday from 1 to 5 March, fifteen options in all. Drop `interval` and the window fills with back to back slots at 09:00, 09:30, 10:00, 10:30, 11:00 and 11:30.

| Field | Meaning |
| --- | --- |
| `startDate`, `endDate` | The date range, inclusive. Fewer than 366 days. |
| `days` | Days of the week to include: `mon` to `sun`. Optional; defaults to every day. |
| `from` | Earliest slot start on each day, `HH:mm` in `timeZone`. |
| `to` | End of the daily window, `HH:mm` in `timeZone`. A slot is only generated if it ends by this time. Must be later than `from`. |
| `interval` | Minutes between slot starts. Optional; defaults to `duration`, which gives back to back slots. |

A generator that cannot produce a slot is rejected with `VALIDATION_ERROR` naming the field: `to` not later than `from`, a window shorter than `duration`, or a range that contains none of the listed days. Generators are expanded when the poll is created, the result is appended to `options`, and duplicate slots are removed. A request that would exceed 100 options fails with `TOO_MANY_OPTIONS`.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/polls
openapi: 3.1.0
info:
  title: Rallly API
  description: >-
    ## Versioning


    `v1` is stable. Additive changes (new endpoints, new optional fields) may
    land on this path at any time; breaking changes only arrive under a new
    version prefix.


    ## Rate limits


    All endpoints share two limits per space: **60 requests per minute** and
    **5000 requests per day**. Both are fixed windows that open with the first
    request and reset when they expire. Both limits are per space, not per API
    key, so creating additional keys does not increase throughput.


    Every response from an authenticated request includes the standard
    `RateLimit-*` headers. Responses sent before the limiter runs (`401`, `403`,
    and the maintenance `503`) do not. `RateLimit-Policy` lists both limits;
    `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` describe
    whichever limit is closest to being exhausted. When either limit is exceeded
    the API responds with `429 Too Many Requests`, a `RATE_LIMIT_EXCEEDED` error
    body, and a `Retry-After` header indicating how many seconds to wait before
    retrying.


    If the rate limit store cannot be reached the API fails closed and responds
    with `503 Service Unavailable`, a `SERVICE_UNAVAILABLE` error body, and a
    `Retry-After` header.


    ## Dates and times


    Every poll has a `kind`. A `date` poll offers calendar days: each option
    carries a `date` in `YYYY-MM-DD` format, which is a floating date with no
    time component and no timezone, so never convert it through a timezone. A
    `time` poll offers time slots: each option carries a `startTime` as an ISO
    8601 instant in UTC and a `duration` in minutes; convert `startTime` into
    the poll's `timeZone` (or the viewer's) for display. Timestamps such as
    `createdAt` and `updatedAt` are always ISO 8601 instants in UTC.


    ## Request bodies


    Request bodies are validated strictly: a field that is not part of the
    documented schema is rejected with `VALIDATION_ERROR` rather than ignored,
    so a misspelt setting never silently falls back to its default.


    ## Enums


    Vote types are an open set. The built-in values are `yes`, `ifNeedBe` and
    `no`; new types may be added without a version change, so clients must
    tolerate values they do not recognise. `status` and `kind` are closed sets.


    ## Lists


    List endpoints return the items in `data`. `GET /polls` is paginated: it
    returns a `nextCursor` beside `data`; pass it as the `cursor` query
    parameter to fetch the next page, and it is `null` on the last page. `GET
    /polls/:pollId/participants` returns every participant in one response.


    ## Errors


    Every failure is `application/json` with the shape `{ "error": { "code",
    "message" } }`. `code` is stable and safe to branch on; `message` is
    human-readable and may change. `VALIDATION_ERROR` messages name each
    offending field.


    | Status | Code | When |

    | --- | --- | --- |

    | 400 | `VALIDATION_ERROR` | The body or query string did not match the
    schema, contained an unknown field, or the body was not valid JSON |

    | 400 | `INVALID_AUTHORIZATION_HEADER` | The `Authorization` header is not
    `Bearer <key>` |

    | 400 | `ORGANIZER_NOT_MEMBER` | The organizer email is not a member of the
    space |

    | 400 | `TOO_MANY_OPTIONS` | More than the maximum number of poll options |

    | 400 | `INAPPROPRIATE_CONTENT` | The title, description or location was
    flagged by content moderation |

    | 401 | `UNAUTHORIZED` | The API key is missing, invalid, expired or
    revoked, or its owner is banned |

    | 403 | `SPACE_NOT_PRO` | The space behind the key has no Pro subscription |

    | 404 | `NOT_FOUND` | No route matches the method and path |

    | 404 | `POLL_NOT_FOUND` | The poll does not exist or belongs to another
    space |

    | 429 | `RATE_LIMIT_EXCEEDED` | A rate limit window is exhausted |

    | 503 | `SERVICE_UNAVAILABLE` | Maintenance, or the rate limit store cannot
    be reached |

    | 500 | `INTERNAL_ERROR` | Unexpected failure; the request id is logged |
  version: 1.0.0
servers:
  - url: https://api.rallly.co
security: []
paths:
  /v1/polls:
    post:
      tags:
        - Polls
      summary: Create a poll
      description: >-
        Creates a poll and responds with `201 Created` and the full poll,
        exactly as `GET /polls/:pollId` returns it. Share `inviteUrl` with
        participants. The request mirrors the response: `kind` chooses what
        participants vote on, and `options` takes the same shape the poll
        returns, so a poll can be recreated from the body of a `GET`. A poll has
        at most 100 options.


        ## Date poll


        Pass `kind: "date"` and `options`, one `{ "date": "YYYY-MM-DD" }` per
        day. Each becomes one all-day option. Dates are floating calendar days
        with no timezone, so never convert them through one. Duplicate dates are
        removed.


        ```json

        {
          "title": "Team offsite",
          "kind": "date",
          "options": [{ "date": "2027-03-01" }, { "date": "2027-03-02" }, { "date": "2027-03-03" }]
        }

        ```


        ## Time poll


        Pass `kind: "time"`, optionally a `timeZone` (an IANA zone the times are
        written in) and a default `duration` in minutes, and the slots as
        `options`, `generators` or both.


        ### Explicit slots


        Each entry in `options` is one slot: a `startTime` and an optional
        `duration` that overrides the poll default. A `startTime` with no
        offset, like `2027-03-01T09:00:00`, is wall clock time in `timeZone`
        when that is set and a floating time with no conversion otherwise; one
        with an offset or `Z` is an absolute instant.


        ```json

        {
          "title": "Kickoff",
          "kind": "time",
          "timeZone": "Europe/London",
          "duration": 60,
          "options": [
            { "startTime": "2027-03-01T09:00:00" },
            { "startTime": "2027-03-02T14:00:00", "duration": 90 }
          ]
        }

        ```


        ### Slot generators


        Each object in `generators` expands into recurring slots of `duration`
        minutes from a schedule, so availability across days or weeks does not
        have to be listed slot by slot. `duration` is required when `generators`
        is set.


        ```json

        {
          "title": "Interview availability",
          "kind": "time",
          "timeZone": "America/New_York",
          "duration": 30,
          "generators": [
            {
              "startDate": "2027-03-01",
              "endDate": "2027-03-05",
              "days": ["mon", "tue", "wed", "thu", "fri"],
              "from": "09:00",
              "to": "12:00",
              "interval": 60
            }
          ]
        }

        ```


        This produces 30 minute slots at 09:00, 10:00 and 11:00 New York time on
        each weekday from 1 to 5 March, fifteen options in all. Drop `interval`
        and the window fills with back to back slots at 09:00, 09:30, 10:00,
        10:30, 11:00 and 11:30.


        | Field | Meaning |

        | --- | --- |

        | `startDate`, `endDate` | The date range, inclusive. Fewer than 366
        days. |

        | `days` | Days of the week to include: `mon` to `sun`. Optional;
        defaults to every day. |

        | `from` | Earliest slot start on each day, `HH:mm` in `timeZone`. |

        | `to` | End of the daily window, `HH:mm` in `timeZone`. A slot is only
        generated if it ends by this time. Must be later than `from`. |

        | `interval` | Minutes between slot starts. Optional; defaults to
        `duration`, which gives back to back slots. |


        A generator that cannot produce a slot is rejected with
        `VALIDATION_ERROR` naming the field: `to` not later than `from`, a
        window shorter than `duration`, or a range that contains none of the
        listed days. Generators are expanded when the poll is created, the
        result is appended to `options`, and duplicate slots are removed. A
        request that would exceed 100 options fails with `TOO_MANY_OPTIONS`.
      operationId: postV1Polls
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePollInput'
            examples:
              Date poll:
                summary: Date poll (all-day options)
                description: >-
                  Let participants pick between calendar days. Each option is
                  one all-day date.
                value:
                  title: Team offsite
                  kind: date
                  description: Which days work for a two day offsite?
                  options:
                    - date: '2027-03-01'
                    - date: '2027-03-02'
                    - date: '2027-03-03'
              Time poll with explicit slots:
                summary: Time poll (explicit slots)
                description: >-
                  Offer specific time slots. Datetimes without an offset are
                  wall clock times in `timeZone`; this example offers 09:00 and
                  14:00 in London. Append `Z` or an offset for an absolute
                  instant instead. A slot may override the poll's `duration`.
                value:
                  title: Project kickoff
                  kind: time
                  location: Zoom
                  timeZone: Europe/London
                  duration: 60
                  options:
                    - startTime: '2027-03-01T09:00:00'
                    - startTime: '2027-03-01T14:00:00'
                      duration: 90
              Time poll with a slot generator:
                summary: Time poll (slot generator)
                description: >-
                  Expand recurring slots across a date range. This example
                  generates 30 minute slots at 09:00, 10:00 and 11:00 (New York
                  time) every weekday from 1 to 5 March.
                value:
                  title: Interview availability
                  kind: time
                  timeZone: America/New_York
                  duration: 30
                  generators:
                    - startDate: '2027-03-01'
                      endDate: '2027-03-05'
                      days:
                        - mon
                        - tue
                        - wed
                        - thu
                        - fri
                      from: '09:00'
                      to: '12:00'
                      interval: 60
              Time poll mixing slots and a generator:
                summary: Time poll (explicit slots + generator)
                description: >-
                  `options` and `generators` combine. When `interval` is omitted
                  it defaults to `duration`, so this generator produces back to
                  back 90 minute slots at 14:00 and 15:30 on Monday and
                  Wednesday.
                value:
                  title: Product workshop
                  kind: time
                  timeZone: Europe/Berlin
                  duration: 90
                  options:
                    - startTime: '2027-03-06T10:00:00'
                  generators:
                    - startDate: '2027-03-08'
                      endDate: '2027-03-10'
                      days:
                        - mon
                        - wed
                      from: '14:00'
                      to: '17:00'
      responses:
        '201':
          description: Poll created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PollResponse'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: >-
            The API key is missing, invalid, expired or revoked, or its owner is
            banned. Includes a `WWW-Authenticate` header.
          headers:
            WWW-Authenticate:
              description: The bearer challenge, per RFC 6750.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            The space associated with the API key does not have a Pro
            subscription
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            Rate limit exceeded. Includes a `Retry-After` header indicating how
            many seconds to wait before retrying.
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            The API is temporarily unavailable, for maintenance or because the
            rate limit store cannot be reached. Includes a `Retry-After` header.
            Maintenance responses are sent before the rate limiter runs and
            carry no `RateLimit-*` headers.
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    CreatePollInput:
      oneOf:
        - $ref: '#/components/schemas/CreateDatePollInput'
        - $ref: '#/components/schemas/CreateTimePollInput'
      description: >-
        `kind` chooses what participants vote on: whole days (`date`) or time
        slots (`time`). The request mirrors the poll the API returns: the same
        settings, and `options` in the same shape as the response.
      discriminator:
        propertyName: kind
        mapping:
          date:
            $ref: '#/components/schemas/CreateDatePollInput'
          time:
            $ref: '#/components/schemas/CreateTimePollInput'
    PollResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Poll'
      required:
        - data
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Machine-readable error code. The full list is in the API
                description.
              example: VALIDATION_ERROR
            message:
              type: string
              description: >-
                Human-readable explanation. For `VALIDATION_ERROR` it names each
                offending field, e.g. `title: Invalid input: expected string,
                received undefined; dates.0: Invalid ISO date`.
              example: 'title: Invalid input: expected string, received undefined'
          required:
            - code
            - message
      required:
        - error
    CreateDatePollInput:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
          example: Team sync
        kind:
          type: string
          const: date
          description: Participants vote on whole days.
        description:
          example: Pick a time that works for everyone
          type: string
          maxLength: 1000
        location:
          example: Zoom
          type: string
          maxLength: 255
        requireEmail:
          description: Require participants to provide their email address
          example: true
          type: boolean
        hideParticipants:
          description: Hide participant names from other participants
          example: false
          type: boolean
        hideScores:
          description: Hide vote counts from participants
          example: false
          type: boolean
        disableComments:
          description: >-
            Disable the comments section. Defaults to true: new polls have
            comments disabled unless this is set to false.
          example: false
          type: boolean
        allowTentativeVotes:
          description: >-
            Allow participants to answer "if need be" as well as yes and no.
            Defaults to true.
          example: true
          type: boolean
        organizer:
          description: >-
            Organizer of the poll. Defaults to the space owner if not provided.
            The organizer must be a member of the space.
          type: object
          properties:
            email:
              type: string
              format: email
              description: Email address of the organizer
              example: organizer@example.com
          required:
            - email
          additionalProperties: false
        options:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/DateOptionInput'
          description: >-
            Calendar days to offer. Dates are floating calendar days with no
            timezone, so never convert them through one. Duplicates are removed.
      required:
        - title
        - kind
        - options
      additionalProperties: false
      title: Date poll
    CreateTimePollInput:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
          example: Team sync
        kind:
          type: string
          const: time
          description: Participants vote on time slots.
        description:
          example: Pick a time that works for everyone
          type: string
          maxLength: 1000
        location:
          example: Zoom
          type: string
          maxLength: 255
        requireEmail:
          description: Require participants to provide their email address
          example: true
          type: boolean
        hideParticipants:
          description: Hide participant names from other participants
          example: false
          type: boolean
        hideScores:
          description: Hide vote counts from participants
          example: false
          type: boolean
        disableComments:
          description: >-
            Disable the comments section. Defaults to true: new polls have
            comments disabled unless this is set to false.
          example: false
          type: boolean
        allowTentativeVotes:
          description: >-
            Allow participants to answer "if need be" as well as yes and no.
            Defaults to true.
          example: true
          type: boolean
        organizer:
          description: >-
            Organizer of the poll. Defaults to the space owner if not provided.
            The organizer must be a member of the space.
          type: object
          properties:
            email:
              type: string
              format: email
              description: Email address of the organizer
              example: organizer@example.com
          required:
            - email
          additionalProperties: false
        timeZone:
          description: >-
            IANA time zone the times are written in. Datetime strings without an
            offset are interpreted in this zone. If omitted, offset-less
            datetimes are floating times (no conversion) and the poll has no
            time zone.
          example: Europe/London
          type: string
        duration:
          description: >-
            Default slot length in minutes. Required when `generators` is set or
            an option omits its own `duration`.
          example: 30
          type: integer
          minimum: 15
          maximum: 1440
        options:
          description: >-
            Explicit slots. Provide `options`, `generators` or both. Duplicates
            are removed.
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/TimeOptionInput'
        generators:
          description: >-
            Slot generators. Each expands into recurring slots from a schedule
            and the result is appended to `options`.
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/SlotGenerator'
      required:
        - title
        - kind
      additionalProperties: false
      title: Time poll
    Poll:
      type: object
      properties:
        id:
          type: string
          example: Xk3pQ9vLm2Ab
        title:
          type: string
          example: Team sync
        description:
          anyOf:
            - type: string
            - type: 'null'
          example: Pick a time that works for everyone
        location:
          anyOf:
            - type: string
            - type: 'null'
          example: Zoom
        timeZone:
          anyOf:
            - type: string
            - type: 'null'
          example: Europe/London
        status:
          $ref: '#/components/schemas/PollStatus'
        kind:
          $ref: '#/components/schemas/PollKind'
        createdAt:
          type: string
          format: date-time
          example: '2025-01-10T12:00:00.000Z'
        updatedAt:
          type: string
          format: date-time
          description: >-
            When the poll was last modified. Changes when the poll's details,
            settings or status change.
          example: '2025-01-12T08:30:00.000Z'
        organizer:
          anyOf:
            - $ref: '#/components/schemas/PollOrganizer'
            - type: 'null'
          description: >-
            The space member the poll belongs to. `null` when the organizer's
            account no longer exists.
        requireEmail:
          type: boolean
          description: Whether participants must provide their email address
          example: false
        hideParticipants:
          type: boolean
          description: Whether participant names are hidden from other participants
          example: false
        hideScores:
          type: boolean
          description: Whether vote counts are hidden from participants
          example: false
        disableComments:
          type: boolean
          description: Whether the comments section is disabled
          example: true
        allowTentativeVotes:
          type: boolean
          description: Whether participants may cast the tentative "if need be" vote
          example: true
        participantCount:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Number of participants who have responded to the poll
          example: 3
        options:
          type: array
          items:
            $ref: '#/components/schemas/PollOption'
        adminUrl:
          type: string
          example: https://app.rallly.co/poll/Xk3pQ9vLm2Ab
        inviteUrl:
          type: string
          example: https://rallly.co/invite/Xk3pQ9vLm2Ab
      required:
        - id
        - title
        - description
        - location
        - timeZone
        - status
        - kind
        - createdAt
        - updatedAt
        - organizer
        - requireEmail
        - hideParticipants
        - hideScores
        - disableComments
        - allowTentativeVotes
        - participantCount
        - options
        - adminUrl
        - inviteUrl
    DateOptionInput:
      type: object
      properties:
        date:
          type: string
          format: date
          description: Calendar day to offer, as a floating `YYYY-MM-DD` date.
          example: '2027-03-01'
      required:
        - date
      additionalProperties: false
      title: Date option
      description: One all-day option. The same shape `DateOption` returns.
    TimeOptionInput:
      type: object
      properties:
        startTime:
          type: string
          format: date-time
          description: >-
            ISO datetime start time. A string without an offset is wall clock
            time in `timeZone` when that is set (`2027-03-01T09:00:00` with
            `timeZone: Europe/London` means 09:00 in London) and a floating time
            with no conversion otherwise. A string with an offset or `Z` is an
            absolute instant.
          example: '2027-03-01T09:00:00'
        duration:
          description: Length of this slot in minutes. Defaults to the poll's `duration`.
          example: 30
          type: integer
          minimum: 15
          maximum: 1440
      required:
        - startTime
      additionalProperties: false
      title: Time option
      description: One time slot. The same shape `TimeOption` returns.
    SlotGenerator:
      type: object
      properties:
        startDate:
          type: string
          format: date
          description: First day of the range to generate slots on, inclusive.
          example: '2027-03-01'
        endDate:
          type: string
          format: date
          description: >-
            Last day of the range, inclusive. The range must span fewer than 366
            days.
          example: '2027-03-05'
        days:
          default:
            - mon
            - tue
            - wed
            - thu
            - fri
            - sat
            - sun
          description: >-
            Days of the week to generate slots on. Days in the range that are
            not listed are skipped. Defaults to every day.
          example:
            - mon
            - tue
            - wed
            - thu
            - fri
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - mon
              - tue
              - wed
              - thu
              - fri
              - sat
              - sun
        from:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
          description: Earliest slot start on each day, as a wall clock time in `timeZone`.
          example: '09:00'
        to:
          type: string
          pattern: ^(?:[01]\d|2[0-3]):[0-5]\d$
          description: >-
            End of the daily window, as a wall clock time in `timeZone`. A slot
            is only generated if it ends at or before this time.
          example: '17:00'
        interval:
          description: >-
            Minutes between consecutive slot starts. Defaults to `duration`,
            which produces back to back slots.
          example: 60
          type: integer
          minimum: 15
          maximum: 1440
      required:
        - startDate
        - endDate
        - from
        - to
      additionalProperties: false
      title: Slot generator
      description: >-
        Expands into one slot of `duration` minutes every `interval` minutes
        between `from` and `to`, on each listed day of the week between
        `startDate` and `endDate`. Slots that would not end by `to` are not
        generated.
    PollStatus:
      type: string
      enum:
        - open
        - closed
        - scheduled
        - canceled
    PollKind:
      type: string
      enum:
        - date
        - time
      description: >-
        Whether the poll offers calendar dates (`date`) or time slots (`time`).
        Determines which option shape the poll uses: every option in a `date`
        poll has a `date`, every option in a `time` poll has a `startTime` and
        `duration`.
      example: time
    PollOrganizer:
      type: object
      properties:
        id:
          type: string
          example: cm3f7d1qa0000t2k9c6b8h4jr
        name:
          type: string
          example: John Doe
        email:
          type: string
          format: email
          example: organizer@example.com
        image:
          anyOf:
            - type: string
            - type: 'null'
          example: https://cdn.rallly.co/avatars/cm3f7d1qa0000t2k9c6b8h4jr.jpg
      required:
        - id
        - name
        - email
        - image
    PollOption:
      anyOf:
        - $ref: '#/components/schemas/DateOption'
        - $ref: '#/components/schemas/TimeOption'
      description: >-
        A poll option. The shape follows the poll's `kind`: a `DateOption` for
        `date` polls, a `TimeOption` for `time` polls.
    DateOption:
      type: object
      properties:
        id:
          type: string
          example: cm5h8x2k40000q9l4f7e2d3an
        date:
          type: string
          format: date
          description: >-
            Calendar date in YYYY-MM-DD format. All-day options are floating
            dates with no time component and no timezone.
          example: '2025-01-15'
      required:
        - id
        - date
      description: 'An all-day option. Only present in polls with `kind: date`.'
    TimeOption:
      type: object
      properties:
        id:
          type: string
          example: cm5h8x2k40000q9l4f7e2d3an
        startTime:
          type: string
          format: date-time
          description: Start of the slot as an ISO 8601 instant in UTC.
          example: '2025-01-15T09:00:00.000Z'
        duration:
          type: integer
          exclusiveMinimum: 0
          maximum: 9007199254740991
          description: Duration in minutes.
          example: 30
      required:
        - id
        - startTime
        - duration
      description: 'A time slot. Only present in polls with `kind: time`.'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````