openapi: 3.0.4
info:
  title: Survey API
  description: |-
    Welcome to the Voxtelesys Survey REST API. If at any point you have questions or would like more information please reach out to support.
  version: v1
servers:
  - url: https://surveyapi.voxtelesys.net/api/v1
paths:
  /survey:
    post:
      tags:
        - Survey
      security:
        - OAuth2: ['surveyapi:survey:manage']
      summary: Create a survey
      description: Endpoint for creating a new survey instance.
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateSurveyBody"
      responses:
        "200":
          description: Success.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Survey"
        "400":
          description: Invalid request body or parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Template or template version not found.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /survey/{id}/response:
    patch:
      tags:
        - Survey
      security:
        - OAuth2: ['surveyapi:survey:manage']
      summary: Add responses to a survey
      description: Endpoint for adding or updating responses on a pending survey.
      parameters:
        - name: id
          in: path
          description: ID of the survey
          required: true
          schema:
            type: string
          example: 550e8400-e29b-41d4-a716-446655440000
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateSurveyResponseBody"
      responses:
        "200":
          description: Success.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Survey"
        "400":
          description: Invalid request body or parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Survey not found.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: Survey is not in a pending state.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /survey/{id}:
    put:
      tags:
        - Survey
      security:
        - OAuth2: ['surveyapi:survey:manage']
      summary: Update survey status
      description: Endpoint for finalizing a survey by updating its status to `completed` or `failed`.
      parameters:
        - name: id
          in: path
          description: ID of the survey
          required: true
          schema:
            type: string
          example: 550e8400-e29b-41d4-a716-446655440000
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateSurveyBody"
      responses:
        "200":
          description: Success.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Survey"
        "400":
          description: Invalid request body or parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Survey not found.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: Survey is not in a pending state.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://authapi.voxtelesys.net/api/v1/oauth/token
          scopes:
            surveyapi:survey:manage: Create, update, and delete surveys
            surveyapi:survey:view: View surveys
  schemas:
    Survey:
      type: object
      readOnly: true
      properties:
        id:
          type: string
          format: uuid
          description: Unique survey identifier.
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        account_id:
          type: integer
          description: Voxtelesys account ID.
          example: 190000
          readOnly: true
        service_trunk_group_id:
          type: integer
          description: Voxtelesys service trunk group ID.
          example: 70000
          readOnly: true
        type:
          type: string
          description: Survey type.
          enum: [web, generic]
          example: web
          readOnly: true
        template_version_guid:
          type: string
          description: GUID of the template version used (web surveys only).
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
          readOnly: true
        status:
          type: string
          description: Current survey status.
          enum: [pending, expired, failed, completed]
          example: pending
          readOnly: true
        tag:
          type: string
          description: Custom string included in callback events.
          example: my-survey-tag
        bulk_tag:
          type: string
          description: Custom string for grouping surveys in callback events.
          example: my-bulk-tag
        region:
          type: string
          description: Region where the survey was created.
          example: pit
          readOnly: true
        status_callback:
          type: object
          description: Configuration for receiving HTTP callbacks when the survey status or responses change.
          properties:
            url:
              type: string
              format: uri
              description: The absolute URL to send callbacks to.
              example: https://example.com/survey-callback
            method:
              type: string
              enum: [GET, POST]
              description: HTTP method used when sending the callback.
              example: POST
        parameters:
          type: object
          description: Key-value pairs used for template parameter interpolation.
          example: { "name": "John", "appointment_time": "3:00 PM" }
        url:
          type: string
          format: uri
          description: URL for the survey (web surveys only).
          example: https://survey.voxtelesys.net/surveys/550e8400-e29b-41d4-a716-446655440000?v=b2c3d4e5-f6a7-8901-bcde-f12345678901
          readOnly: true
        locale:
          type: string
          description: Locale for the survey. Defaults to `en`.
          enum:
            [
              en,
              de,
              fr,
              es,
              it,
              nl,
              pt,
              ru,
              zh-cn,
              zh-tw,
              ja,
              ko,
              ar,
              tr,
              pl,
              sv,
              fi,
              da,
              no,
              el,
              hu,
              cs,
              ro,
              he,
              id,
              vi,
              hi,
            ]
          default: en
          example: en
        expire_at:
          type: string
          format: date-time
          description: ISO 8601 datetime when the survey expires. Defaults to 30 days from creation; maximum 90 days.
          example: "2026-04-24T00:00:00.000Z"
        failure_reason:
          type: string
          description: Reason for failure (only present when status is `failed`).
          example: User did not complete the survey.
          readOnly: true
        finished_at:
          type: string
          format: date-time
          description: ISO 8601 datetime when the survey reached a final status.
          example: "2026-03-25T15:30:00.000Z"
          readOnly: true
        response:
          type: array
          description: Responses collected on the survey.
          readOnly: true
          items:
            $ref: "#/components/schemas/SurveyResponseItem"
        error:
          type: object
          readOnly: true
          properties:
            code:
              type: integer
              description: The error code.
              example: 4102
            description:
              type: string
              description: The error description.
              example: user-defined error
    ErrorResponse:
      type: object
      readOnly: true
      properties:
        message:
          type: string
          description: Human-readable description of the error.
          example: Survey not found.
        error_id:
          type: string
          description: Unique identifier for the error instance.
          example: 550e8400-e29b-41d4-a716-446655440000
    SurveyResponseItem:
      type: object
      properties:
        key:
          type: string
          description: Response key (question identifier).
          example: satisfaction
        value:
          description: Response value.
          example: 5
        answered_at:
          type: string
          format: date-time
          description: ISO 8601 datetime when the response was first recorded.
          example: "2026-03-25T14:00:00.000Z"
          readOnly: true
        updated_at:
          type: string
          format: date-time
          description: ISO 8601 datetime when the response was last updated.
          example: "2026-03-25T14:00:00.000Z"
          readOnly: true
    CreateSurveyBody:
      type: object
      properties:
        template_guid:
          type: string
          description: GUID of the survey template. Uses the default template version if no `template_version_guid` is provided.
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        template_version_guid:
          type: string
          description: GUID of a specific template version. Providing this creates a web survey with a shareable URL.
          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
        status_callback:
          type: object
          description: Configuration for receiving HTTP callbacks when the survey status or responses change.
          required:
            - url
            - method
          properties:
            url:
              type: string
              format: uri
              description: The absolute URL to send callbacks to.
              example: https://example.com/survey-callback
            method:
              type: string
              enum: [GET, POST]
              description: HTTP method used when sending the callback.
              example: POST
        tag:
          type: string
          description: Custom string included in callback events (max 255 characters).
          example: my-survey-tag
        bulk_tag:
          type: string
          description: Custom string for grouping surveys in callback events (max 255 characters).
          example: my-bulk-tag
        parameters:
          type: object
          description: Key-value pairs for template parameter interpolation.
          example: { "name": "John", "appointment_time": "3:00 PM" }
        expire_at:
          type: string
          format: date-time
          description: ISO 8601 datetime when the survey should expire. Must be in the future and no more than 90 days from now. Defaults to 30 days from creation.
          example: "2026-04-24T00:00:00.000Z"
        locale:
          type: string
          description: Locale for the survey. Defaults to `en`.
          enum:
            [
              en,
              de,
              fr,
              es,
              it,
              nl,
              pt,
              ru,
              zh-cn,
              zh-tw,
              ja,
              ko,
              ar,
              tr,
              pl,
              sv,
              fi,
              da,
              no,
              el,
              hu,
              cs,
              ro,
              he,
              id,
              vi,
              hi,
            ]
          default: en
          example: en
    UpdateSurveyResponseBody:
      type: object
      required:
        - response
      properties:
        response:
          type: array
          description: Array of response items to add or update on the survey. Each key must be unique within the request.
          minItems: 1
          items:
            type: object
            required:
              - key
              - value
            properties:
              key:
                description: Response key (question identifier).
                example: satisfaction
              value:
                description: Response value. Accepts string, number, boolean, null, or array of primitives.
                example: 5
    UpdateSurveyBody:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          enum: [completed, failed, stopped]
          description: Final status for the survey.
          example: completed
        failure_reason:
          type: string
          description: Reason for failure (used when status is `failed`, max 1024 characters).
          example: User did not complete the survey.
