openapi: 3.0.0
info:
  version: 2.3.0
  title: Pulse Insights Survey API
  description: An API for the Pulse Insights survey servers.

servers:
  - url: https://survey.pulseinsights.com

components:
  responses:
    Error:
      description: Error response.
      content:
        text/plain:
          schema:
            type: array
            items:
              type: string
              example: ["Error: Parameter 'parameter_name' missing", "Error: Parameter 'other_parameter_name' missing"]

    EmptyObject:
      description: Successful response.
      content:
        application/javascript:
          schema:
            $ref: "#/components/schemas/EmptyObject"

    Survey:
      description: Successful response.
      content:
        application/javascript:
          schema:
            $ref: "#/components/schemas/ServedSurvey"

  schemas:
    ClientKey:
      type: string
      description: Used to identify a user across devices and advanced survey targeting. See https://docs.pulseinsights.com/implementing-pulse-insights-dev/implementing-on-web-and-mobile-web/client-key for more details.

    DeviceData:
      type: object
      description: Data associated with the current user's device.

    EmptyObject:
      type: string
      example: "{}"

    DeviceUdid:
      type: string
      description: The device's unique ID.
      example: "00000000-0000-4000-f000-000000000001"

    Submission:
      type: object
      properties:
        udid:
          $ref: '#/components/schemas/SubmissionUdid'

    SubmissionUdid:
      type: string
      description: The survey submission's unique ID.

    QuestionType:
      type: string
      enum: [
        'single_choice_question',
        'multiple_choices_question',
        'free_text_question',
        'slider_question',
        'custom_content_question'
      ]

    QuestionTypeLabel:
      type: string
      enum: [ 'single_choice_question', 'free_text_question', 'custom_content_question', 'multiple_choices_question', 'slider_question' ]
      description: The name of the question type.

    PollResults:
      type: object
      properties:
        poll:
          type: array
          items:
            type: object
            properties:
              id:
                type: number
                description: The ID of the possible answer.
              content:
                type: string
                description: The possible answer's content.
              count:
                type: number
                description: The number of responses for this possible answer.
        content:
          type: string
          description: The question content.
        question_type:
          $ref: '#/components/schemas/QuestionType'
        answers_via_checkbox:
          type: array
          description: An array of strings representing possible answer IDs.
          items:
            type: string
            example: ['12', '42']

    QuestionsAndPossibleAnswers:
      description: An array of questions, each containing their possible answers. Questions are ordered by position.
      type: array
      items:
        type: object
        properties:
          id:
            type: number
            description: The question's unique identifier.

          question_type:
            $ref: '#/components/schemas/QuestionType'

          position:
            type: number
            description: The question's position in the survey.
            minimum: 0
          content:
            type: string
            description: The question content.
          submit_label:
            type: string
            description: The label of the question's submit button.
            default: Submit
          button_type:
            type: number
            enum: [0, 1, 2]
            description: "0 = radio, 1 = standard, 2 = menu"
          desktop_width_type:
            type: number
            enum: [0, 1]
            description: "0 = fixed, 1 = variable"
          answers_alignment_desktop:
            type: number
            enum: [ 0, 1, 2, 3, 4, 5 ]
            description: "0 = left, 1 = center, 2 = right, 3 = space_between, 4 = space_around, 5 = space_evenly"
          answers_per_row_desktop:
            type: number
            description: The number of answers to display in a horizontal row.
          answers_per_row_mobile:
            type: number
            description: The number of answers to display in a horizontal row.
          optional:
            type: string
            description: Whether or not the question is optional.
            enum: [ 't', 'f' ]
          image_type:
            type: number
            enum: [ 0, 1 ]
            description: "0 = image only, 1 = text and image"
          mobile_width_type:
            type: number
            enum: [0, 1]
            description: "0 = fixed, 1 = variable"

          answers_alignment_mobile:
            type: number
            enum: [ 0, 1, 2, 3, 4, 5 ]
            description: "0 = left, 1 = center, 2 = right, 3 = space_between, 4 = space_around, 5 = space_evenly"

          created_at:
            type: number
            description: An integer representing when the question was created.
            example: "1685724174 (represents 2023-06-02 16:42:54 UTC)"

          before_question_text:
            type: string
            description: Text to appear before above the question content. A header.
            example: "Please help us improve"

          after_question_text:
            type: string
            description: Text to appear before above the question content. A footer.
            example: "Which of these most applies to you"

          before_answers_count:
            type: number
            description: The number of additional labels above each possible answer.

          after_answers_count:
            type: number
            description: The number of additional labels below each possible answer.

          before_answers_items:
            description: An array of labels to display before each possible answer.
            type: array
            items:
              type: string
              example: ["first label", "second label"]

          after_answers_items:
            type: array
            description: An array of labels to display after each possible answer.
            items:
              type: string
              example: ["first label", "second label"]

          nps:
            type: string
            description: Whether or not the question is an NPS question.
            enum: ['t', 'f']

          single_choice_default_label:
            type: string
            description: The default option label. Only relevant for menu (aka dropdown) questions.
            default: Select an option

          question_locale_group_id:
            type: number
            description: The unique identifier of the group (if any) that the question belongs to.

          additional_content:
            type: string
            description: Additional content to show next to the question. Could be HTML. Only present if question has show_additional_content enabled.
            example: Never use self-sealing stem bolts without appropriate safety equipment.

          additional_content_position:
            type: number
            enum: [0, 1]
            description: "0 = between, 1 = footer, 2 = header Only present if question.show_additional_content is true"

          empty_error_text:
            type: string
            description: An error message to show when the question has not been answered.
            example: Please fill this in

          maximum_selection:
            type: number
            description: Maximum number of possible answers that can be selected. Only relevant for multiple choices question with maximum selection limit enabled.

          maximum_selections_exceeded_error_text:
            type: string
            description: Error message to show when maximum number of selections is exceeded. Only relevant for multiple choice question with maximum selection limit enabled.
            example: Maximum of 3 please

          next_question_id:
            type: number
            description: ID of next question. Only relevant to multiple_choices_question and free text question.
          hint_text:
            type: string
            description: Hint text for the free text answer field. Only relevant to free text questions.
            example: Let us know what you think.

          error_text:
            type: string
            description: Message to show when the free text question has an error. Only relevant to free text questions.
            example: Please do not enter phone numbers.

          height:
            type: number
            description: The number of vertical lines for the input field. Only relevant to free text questions.

          max_length:
            type: number
            description: The maximum number of characters to accept. Only relevant to free text questions.

          fullscreen:
            type: string
            description: Whether or not the question will operate in fullscreen mode. Only relevant to custom content questions.
            enum: ['t', 'f']

          background_color:
            type: string
            description: The question's background's colour in RGB hexadecimal. Only relevant to custom content questions.
            example: "#ff00aa"

          opacity:
            type: number
            description: The question's background's opacity as a percentage. Only relevant to custom content questions.
            minimum: 0
            maximum: 100

          autoclose_enabled:
            type: string
            description: Whether or not the question will automatically close after being answered. Only relevant to custom content questions.
            enum: ['t', 'f']

          autoclose_delay:
            type: number
            description: The number of seconds to wait before automatically closing. Only relevant to custom content questions.

          autoredirect_enabled:
            type: string
            description: Whether or not the question will automatically redirect after being answered. Only relevant to custom content questions.
            enum: ['t', 'f']

          autoredirect_delay:
            type: number
            description: The number of seconds to wait before automatically redirecting. Only relevant to custom content questions.

          autoredirect_url:
            type: string
            description: The URL where to redirect to.

          show_after_aao:
            type: boolean
            description: Whether the question will be shown after answers have been submitted for an all at once survey, indicating that it will take the place of the "Thank You" card. Only applies to custom content questions.

          slider_start_position:
            type: number
            description: The slider's starting position in "notches" from the left. Only relevant to slider questions.
            minimum: 0

          slider_submit_button_enabled:
            type: string
            description: Whether or not the slider has a submit button. Only relevant to slider questions.
            enum: ['t', 'f']

          possible_answers:
            description: An array of all possible answers for this question. Only relevant to single choice , multiple choice, and slider questions. Ordered by position, but if question.randomize is true, then order will be random.
            type: array
            items:
              type: object
              properties:
                id:
                  type: number
                  description: The possible answer's unique identifier.

                position:
                  type: number
                  description: The possible answer's position.
                  minimum: 0

                content:
                  type: string
                  description: The possible answer's content.
                  example: Option A

                next_question_id:
                  type: number
                  description: The ID of the question to show if this possible answer is selected.

                image_url:
                  type: string
                  description: The URL of the image to show for this possible answer.

                image_alt:
                  type: string
                  description: The alt text of any configured image.

                image_width:
                  type: string
                  description: The width of the image.
                  example: "100px"

                image_height:
                  type: string
                  description: The height of the image.
                  example: "100px"

                image_width_mobile:
                  type: string
                  description: The width of the image on mobile devices.
                  example: "100px"

                image_height_mobile:
                  type: string
                  description: The height of the image on mobile devices.
                  example: "100px"

                image_width_tablet:
                  type: string
                  description: The width of the image on tablets.
                  example: "100px"

                image_height_tablet:
                  type: string
                  description: The height of the image on tablets in pixels.
                  example: "100px"

                image_position:
                  type: string
                  description: 0 = top, 1 = bottom, 2 = right, 3 = left.
                  enum: [ 0, 1, 2, 3 ]

                possible_answer_locale_group_id:
                  type: number
                  description: The unique identifier of the group (if any) that the possible answer belongs to.

    Survey:
      description: A survey object.
      type: object
      properties:
        id:
          type: number
          description: The survey's unique identifier.

        name:
          type: string
          description: The survey's name.
          example: Fall Customer Engagement Survey

        survey_type:
          type: number
          enum: [ 0, 1, 2, 3, 4 ]
          description: 0 = docked widget, 1 = inline, 2 = top bar, 3 = bototm bar, 5 = fullscreen.

        invitation:
          type: string
          description: The survey's invitation.
          example: Would you like to take a survey?

        top_position:
          type: string
          description: The survey's offset from the top of the screen. May be % or px.
          example: "10px. 25%"

        bottom_position:
          type: string
          description: The survey's offset from the bottom of the screen. May be % or px.
          example: "10px. 25%"

        left_position:
          type: string
          description: The survey's offset from the left of the screen. May be % or px.
          example: "10px. 25%"

        right_position:
          type: string
          description: The survey's offset from the right of the screen. May be % or px.
          example: "10px. 25%"

        width:
          type: number
          description: The survey's width.
          example: 300

        background_color:
          type: string
          description: The survey's background's colour in RGB hexadecimal.
          example: "#ff00aa"

        text_color:
          type: string
          description: The survey's text colour in RGB hexadecimal.
          example: "#ff00aa"

        logo:
          deprecated: true

        inline_target_selector:
          type: string
          description: The CSS selector of the element which will house an inline survey.
          example: "#survey_container"

        thank_you:
          type: string
          description: A welcome message inviting user's to the survey.
          example: "Would you like to take a survey?"

        pusher_enabled:
          deprecated: true

        answer_text_color:
          type: string
          description: The survey's answers' colour in RGB hexadecimal.
          example: "#ff00aa"

        mobile_inline_target_selector:
          type: string
          description: The CSS selector of the element which will house an inline survey for mobile device visitors.
          example: "#mobile_survey_container"

        sdk_inline_target_selector:
          type: string
          description: The CSS selector of the element which will house an inline survey viewed via a Pulse Insights mobile app.
          example: "#sdk_survey_container"

        display_all_questions:
          type: string
          description: Whether or not all of the survey's questions are meant to be displayed at the same time.
          enum: [ 't', 'f' ]

        fullscreen_margin:
          type: number
          description: The number of pixels of margin around a fullscreen survey.
          example: 42

        invitation_button:
          type: string
          description: The text of the survey's invitation button.
          example: "Click here to get started"

        invitation_button_disabled:
          type: string
          description: Whether or not the survey's invitation button will be shown.
          default: 'f'
          enum: [ 't', 'f' ]

        single_page:
          type: boolean
          description: Whether or not the survey is meant for a single page application.

        ignore_frequency_cap:
          type: boolean
          description: Whether or not the survey's frequency cap will be ignored.

        randomize_question_order:
          type: string
          description: Whether or not the survey's questions will be shown in random order.
          enum: [ 't', 'f' ]

        all_at_once_empty_error_enabled:
          type: string
          description: Whether or not the survey will show an error when no answers are selected (all-at-once surveys only).
          enum: [ 't', 'f' ]

        all_at_once_submit_label:
          type: string
          description: The text of an all-at-once survey's submit button.
          default: "Submit"

        all_at_once_error_text:
          type: string
          description: The text of an all-at-once survey's errors.
          default: "Please fill answers"

        survey_locale_group_id:
          type: number
          description: The unique identifier of the group (if any) that the survey belongs to.

        personal_data_masking_enabled:
          type: string
          description: Whether or not personal data masking rules should be applied.
          enum: [ 't', 'f' ]

        phone_number_masked:
          type: string
          description: Whether or not phone numbers should be detected and prevented from being submitted.
          enum: [ 't', 'f' ]

        email_masked:
          type: string
          description: Whether or not e-mail addresses should be detected and prevented from being submitted.
          enum: [ 't', 'f' ]

        background:
          type: string
          description: The URL of any background image specified for the survey.
          example: "https://cdn.pulseinsights.com/background/survey/:survey_id/:background_image_url"

        pulse_insights_branding:
          type: boolean
          description: Whether or not to include Pulse Insights branding on the survey widget.

        custom_data_snippet:
          type: string
          description: AKA Impression callback code. JS to be executed on survey impression.

        onclose_callback_code:
          type: string
          description: JS to be execute when the survey is closed by the user.

        oncomplete_callback_code:
          type: string
          description: JS to execute after the survey is complete. Only available if oncomplete callback is enabled.
        onanswer_callback_code:
          type: string
          description: JS to execute after the survey is complete. Only available if onanswer callback is enabled.

        onview_callback_code:
          type: string
          description: JS to execute after the survey is complete. Only available if onview callback is enabled.

        onclick_callback_code:
          type: string
          description: JS to execute after a link within a custom content question gets clicked. Only available if onclick callback is enabled.

        custom_content_link_click_enabled:
          type: string
          description: Whether or not custom content link clicking is enabled.
          enum: [ 't', 'f' ]

        inline_target_position:
          enum: [ 0, 1, 2, 3 ]
          type: number
          description: The position of the widget relative to its inline target. "0 = below, 1 = above, 2 = before, 3 = after"

        theme_css:
          type: string
          description: CSS from any applicable theme.

    DirectServedSurvey:
      type: object
      properties:
        survey:
          $ref: '#/components/schemas/Survey'
        questions_and_possible_answers:
          $ref: '#/components/schemas/QuestionsAndPossibleAnswers'

        submission:
          $ref: '#/components/schemas/Submission'

        device:
          type: object
          properties:
            udid:
              $ref: '#/components/schemas/DeviceUdid'
            client_key:
              $ref: '#/components/schemas/ClientKey'

        device_data:
          $ref: '#/components/schemas/DeviceData'

    ServedSurvey:
      type: object
      properties:
        survey:
          $ref: '#/components/schemas/Survey'
        submission:
          $ref: '#/components/schemas/Submission'
        device:
          type: object
          properties:
            udid:
              $ref: '#/components/schemas/DeviceUdid'
        device_data:
          $ref: '#/components/schemas/DeviceData'

    ThankYou:
      type: object
      properties:
        thank_you:
          type: string
          example: "Thank you for taking this survey!"

  parameters:
    Callback:
      in: query
      name: callback
      description: Conditionally required. If device_type != 'native_mobile' OR 'email'. Response will be wrapped in callback code. For example, passing "console.debug" will result in "console.debug('{}')".
      schema:
        type: string
        example: "console.debug"
      required: false

    ContextData:
      in: query
      name: custom_data
      description: Also known as "Context Data". Used to specify context in which the survey appeared. See https://docs.pulseinsights.com/implementing-pulse-insights-dev/implementing-on-web-and-mobile-web/ingesting-contextual-data-for-targeting-and-analysis#context-data for more details.
      schema:
        type: string
      required: false

    DeviceType:
      in: query
      name: device_type
      schema:
        type: string
        enum: [
          'desktop',
          'mobile',
          'tablet',
          'native_mobile',
          'email'
        ]
      description: The type of device that's requesting the survey/poll. Use 'desktop' if unsure.
      required: true

    ClientKey:
      in: query
      name: client_key
      schema:
        $ref: '#/components/schemas/ClientKey'
      required: false

    submission_udid:
      in: path
      name: submission_udid
      schema:
        $ref: '#/components/schemas/SubmissionUdid'
      required: true

    identifier:
      in: query
      name: identifier
      required: true
      description: The account's unique ID.
      schema:
        type: string
        example: "PI-1234567890"

    preview_mode:
      in: query
      name: preview_mode
      required: false
      description: If 'true' then nothing will be recorded in the database.
      schema:
        type: string
        example: 'true'

    VisitCount:
      in: query
      name: visit_count
      description: The number of times the user has visited the site. Used to target surveys.
      schema:
        type: number
      required: false

    PageviewCount:
      in: query
      name: pageview_count
      description: The number of times the user has visited the page. Used to target surveys.
      schema:
        type: number
      required: false

paths:
  /surveys/{survey_id}:
    get:
      description: Returns a specific survey with the provided ID.
      parameters:
        - in: path
          name: survey_id
          description: The survey's unique identifier.
          schema:
            type: number
          required: true
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/DeviceType'
        - $ref: '#/components/parameters/Callback'
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/preview_mode'
        - $ref: '#/components/parameters/VisitCount'
        - $ref: '#/components/parameters/PageviewCount'
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: true
        - in: query
          name: url
          description: The URL from which the submission was made. If not provided HTTP_REFERER will be used as a fallback.
          schema:
            type: string
          required: false
      responses:
        '200':
          description: Successful response. Will return empty object if no eligible surveys are found. Otherwise the return type is based on the "device_type" parameter. (native_mobile, email, all others).
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/EmptyObject"
                  - $ref: "#/components/schemas/ServedSurvey"

  /surveys/{event_name}:
    get:
      description: Retrieves a survey by its event name.
      parameters:
        - in: path
          name: event_name
          description: The name of the event identifying the survey.
          schema:
            type: string
            pattern: '/[-a-zA-Z0-9]+/'
          required: true
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/DeviceType'
        - $ref: '#/components/parameters/Callback'
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/preview_mode'
        - $ref: '#/components/parameters/VisitCount'
        - $ref: '#/components/parameters/PageviewCount'
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: true
        - in: query
          name: url
          description: The URL from which the submission was made. If not provided HTTP_REFERER will be used as a fallback.
          schema:
            type: string
          required: false
      responses:
        '200':
          description: Successful response. Will return empty object if no eligible surveys are found. Otherwise the return type is based on the "device_type" parameter. (native_mobile, email, all others).
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/EmptyObject"
                  - $ref: "#/components/schemas/ServedSurvey"
        '404':
          description: Error response.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  example: ["question_id == 0", "Error: can't find survey"]

  /q/{question_id}/a/{answer_id}:
    get:
      description: Submit an answer to a non free text question. Records the answer in the db unless preview_mode == 'true'. All parameters except (identifier question_id answer_id text redirect preview_mode) will be recorded as ContextData in the submission.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: text
          description: Text of survey response. Required if free text question.
          schema:
            type: string
          required: false
        - in: query
          name: redirect
          description: A URL to redirect to after submission.
          schema:
            type: string
          required: false
        - in: query
          name: url
          description: The URL from which the submission was made. If no redirect parameter is provided then this will be used as the redirect URL.
          schema:
            type: string
          required: false
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: false
        - $ref: '#/components/parameters/preview_mode'
        - in: path
          name: question_id
          description: The question's unique ID.
          schema:
            type: string
          required: true
        - in: path
          name: answer_id
          description: The possible answer's unique ID.
          schema:
            type: string
          required: true
      responses:
        '404':
          description: Error response.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  example: ["question_id == 0", "Error: can't find survey"]
        '302':
          description: Successful response. Returned if "redirect" parameter is provided.
          headers:
            Location:
              schema:
                type: string
              description: The "redirect" parameter provided.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  enum: [""]
        '200':
          description: Successful response.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  enum: ["Thank you!"]

  /q/{question_id}:
    get:
      description: Submit an answer to a free text question. Records the answer in the db unless preview_mode == 'true'. All parameters except (identifier question_id text redirect preview_mode) will be record  as ContextData in the submission.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: text
          description: Text of survey response. Required if free text question.
          schema:
            type: string
          required: false
        - in: query
          name: redirect
          description: A URL to redirect to after submission.
          schema:
            type: string
          required: false
        - in: query
          name: url
          description: The URL from which the submission was made. If no redirect parameter is provided then this will be used as the redirect URL.
          schema:
            type: string
          required: false
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: false
        - $ref: '#/components/parameters/preview_mode'
        - in: path
          name: question_id
          description: The question's unique ID.
          schema:
            type: string
          required: true
      responses:
        '404':
          description: Error response.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  example: ["is_free_text.nil?", "question_id == 0", "Error: can't find survey"]
        '302':
          description: Successful response. Returned if "redirect" parameter is provided.
          headers:
            Location:
              schema:
                type: string
              description: The "redirect" parameter provided.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  enum: [""]
        '200':
          description: Successful response.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  enum: ["Thank you!"]

  /surveys/{survey_id}/questions:
    get:
      description: Retrieve a survey's questions and possible answers.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - in: path
          name: survey_id
          description: The survey's unique ID.
          schema:
            type: string
          required: true
      responses:
        '200':
          description: Successful response. Will return empty object if no eligible surveys are found.
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/EmptyObject"
                  - $ref: "#/components/schemas/QuestionsAndPossibleAnswers"
        '400':
          $ref: '#/components/responses/Error'

  /direct_serve:
    get:
      description: Returns the first eligible survey along with its questions and possible answers. One of client_key and udid is required.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/ClientKey'
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: true
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/preview_mode'
      responses:
        '200':
          description: Successful response. Will return empty object if no eligible surveys are found. Otherwise the return type is based on the "device_type" parameter. (native_mobile, email, all others).
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/EmptyObject"
                  - $ref: "#/components/schemas/DirectServedSurvey"
        '400':
          $ref: '#/components/responses/Error'

  /serve:
    get:
      description: Serves an eligible survey.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/DeviceType'
        - $ref: '#/components/parameters/Callback'
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: true
        - in: query
          name: preview_mode
          required: false
          description: If 'true' then it will return surveys in DRAFT status or with frequency caps enabled. (These are not returned otherwise).
          schema:
            type: string
            example: 'true'
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/VisitCount'
        - $ref: '#/components/parameters/ClientKey'
        - $ref: '#/components/parameters/PageviewCount'

        - in: query
          name: install_days
          description: Native-Mobile only. The number of days the app has been installed for.
          schema:
            type: number
            example: 1
        - in: query
          name: launch_times
          description: Native-Mobile only. The number of times the app has been launched.
          schema:
            type: number
            example: 7
        - in: query
          name: view_name
          description: Native-Mobile only. The view used to access the survey.
          schema:
            type: string
            example: domain.com
        - in: query
          name: mobile_type
          description: Native-Mobile only. The type of mobile device.
          schema:
            type: string
            enum: [ 'ios', 'android' ]
      responses:
        '200':
          description: Successful response. Will return empty object if no eligible surveys are found. Otherwise the return type is based on the "device_type" parameter. (native_mobile, email, all others).
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/EmptyObject"
                  - $ref: "#/components/schemas/ServedSurvey"
        '400':
          $ref: '#/components/responses/Error'

  /surveys/{survey_id}/poll:
    get:
      description: Returns poll results for a survey question. Only works if the survey is configured as poll.
      parameters:
        - in: path
          name: survey_id
          description: The survey's unique ID.
          schema:
            type: string
          required: true
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/Callback'
        - in: query
          name: device_udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: false
          description: The device's unique ID. Conditionally required. If device_type != 'native_mobile' OR 'email'.
        - $ref: '#/components/parameters/DeviceType'
        - in: query
          name: url
          description: The URL where the event occurred. Conditionally required. Required if device_type = native_mobile.
          schema:
            type: string
          required: false
        - in: query
          name: question_id
          description: The question's unique ID.
          schema:
            type: number
          required: true
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/preview_mode'
        - $ref: '#/components/parameters/VisitCount'
        - $ref: '#/components/parameters/PageviewCount'
      responses:
        '400':
          $ref: '#/components/responses/Error'
        '403':
          description: Forbidden. Poll is not enabled for this survey.
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string
                  example: ["Error: Poll not enabled for this survey"]
        '200':
          description: Successful response.
          content:
            application/javascript:
              schema:
                type: object
                properties:
                  survey:
                    $ref: '#/components/schemas/Survey'
                  question:
                    type: object
                    properties:
                      id:
                        type: number
                        description: The question's unique identifier.
                      question_type:
                        $ref: '#/components/schemas/QuestionType'
                      content:
                        type: string
                        description: The question content.
                      question_locale_group_id:
                        type: number
                        description: The unique identifier of the group (if any) that the question belongs to.
                  results:
                    $ref: '#/components/schemas/PollResults'

  /submissions/{submission_udid}/all_answers:
    get:
      description: Submits all answers for a survey (all at once survey). Records the answers in the database UNLESS preview_mode is 'true'.
      parameters:
        - $ref: '#/components/parameters/submission_udid'
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: answers
          required: true
          description: The answers.
          schema:
            type: array
            items:
              type: object
              properties:
                question_id:
                  type: string
                  description: The question's unique ID.

                question_type:
                  $ref: '#/components/schemas/QuestionTypeLabel'

                answer:
                  type: string
                  description: The possible answer's unique ID. In the case of a multiple choice question, provide all IDs in a single comma-delimited string.
        - $ref: '#/components/parameters/ClientKey'
        - $ref: '#/components/parameters/ContextData'
        - $ref: '#/components/parameters/preview_mode'
        - in: query
          name: pdf_results
          required: false
          description: Get the results as a PDF file.
          schema:
            type: boolean
      responses:
        '200':
          description: Successful response.
          content:
            application/javascript:
              schema:
                $ref: "#/components/schemas/EmptyObject"
            application/pdf:
              schema:
                type: string
                format: binary
        '400':
          $ref: '#/components/responses/Error'

  /submissions/{submission_udid}/answer:
    get:
      description: Submits an answer to a survey question. Records the answer in the database UNLESS preview_mode is 'true'.
      parameters:
        - $ref: '#/components/parameters/submission_udid'
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: question_id
          required: true
          description: The question ID.
          schema:
            type: string

        - in: query
          name: answer_id
          required: false
          description: Required by single choice questions, slider questions, and NPS questions.
          schema:
            type: string
        - in: query
          name: text_answer
          required: false
          description: Required if question is a free text question.
          schema:
            type: string
        - in: query
          name: next_question_id
          required: false
          description: Required if question is a custom content question.
          schema:
            type: string
        - in: query
          name: check_boxes
          required: false
          description: A comma-delimited string of possible answer IDs. Used by multiple choice questions.
          schema:
            type: string
            example: '1,23,42'
        - $ref: '#/components/parameters/preview_mode'
      responses:
        '200':
          description: Successful response. If survey has only one question and "show results instead" is enabled, then returns an object of poll results. Otherwise '{}'.
          content:
            application/javascript:
              schema:
                type: string
        '400':
          $ref: '#/components/responses/Error'

  /submissions/{submission_udid}/close:
    get:
      description: Marks a survey as being closed by the survey taker.
      parameters:
        - $ref: '#/components/parameters/submission_udid'
        - $ref: '#/components/parameters/identifier'
      responses:
        '200':
          $ref: '#/components/responses/EmptyObject'
        '400':
          $ref: '#/components/responses/Error'

  /submissions/{submission_udid}/viewed_at:
    get:
      description: Marks a viewed impression.
      parameters:
        - $ref: '#/components/parameters/submission_udid'
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: viewed_at
          required: true
          description: The time the user saw the survey.
          schema:
            type: string
            format: date-time
            example: "2023-05-31 11:12:07.304719 -0700"
      responses:
        '200':
          $ref: '#/components/responses/EmptyObject'
        '400':
          $ref: '#/components/responses/Error'

  /devices/{deviceUdid}/set_data:
    get:
      description: Sets a device's data.
      parameters:
        - in: path
          name: deviceUdid
          required: true
          schema:
            $ref: '#/components/schemas/DeviceUdid'
        - $ref: '#/components/parameters/identifier'
      responses:
        '200':
          $ref: '#/components/responses/EmptyObject'
        '400':
          $ref: '#/components/responses/Error'

  /results:
    get:
      description: Get results of survey. Or just a thank_you message.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/submission_udid'
        - in: query
          name: accept
          description: "If provided a value of 'application/json', response will have JSON data rather than HTML"
          schema:
            type: string
          required: false
      responses:
        '200':
          description: Successful response. HTML with JS which will download and present the survey results.
          content:
            'text/html; charset=utf-8':
              schema:
                type: string
        '400':
          $ref: '#/components/responses/Error'

  /present_results:
    get:
      description: If the survey has polling enabled then return the results of the survey, otherwise return a thank_you message.
      parameters:
        - $ref: '#/components/parameters/identifier'
        - $ref: '#/components/parameters/submission_udid'
      responses:
        '200':
          description: Successful response.
          content:
            application/javascript:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ThankYou'
                  - $ref: '#/components/schemas/PollResults'
                type: object
                example: '{"thank_you": "Thank you for taking this survey!"}'
        '400':
          $ref: '#/components/responses/Error'

  /track_event:
    get:
      description: Record the occurrence of an event.
      parameters:
        - in: query
          name: event_name
          description: A descriptive name for the event.
          schema:
            type: string
          required: true
        - in: query
          name: event_properties
          description: An object representing the properties to record.
          schema:
            type: object
            example: { test: 1 }
          required: true
        - $ref: '#/components/parameters/identifier'
        - in: query
          name: udid
          schema:
            $ref: '#/components/schemas/DeviceUdid'
          required: true
        - in: query
          name: url
          description: The URL where the event occurred.
          schema:
            type: string
          required: true
      responses:
        '200':
          $ref: '#/components/responses/EmptyObject'
        '400':
          $ref: '#/components/responses/Error'

  /custom_content_link_click:
    get:
      description: Registers a click for a particular link in a custom content question. Increments the click count of the specified link by one.
      parameters:
        - $ref: '#/components/parameters/ClientKey'
        - $ref: '#/components/parameters/ContextData'
        - in: query
          name: submission_udid
          schema:
            $ref: '#/components/schemas/SubmissionUdid'
          required: true
        - in: query
          name: question_id
          description: The custom content question's unique ID.
          schema:
            type: number
          required: true
        - in: query
          name: link_identifier
          description: The UUID of the link that would be included in the "data-pi-link-id" attribute.
          schema:
            type: string
          required: true
      responses:
        '200':
          $ref: '#/components/responses/EmptyObject'
        '400':
          $ref: '#/components/responses/Error'
