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

# Questions

> Create and manage interview questions including audio questions, survey questions, and AI text questions

## Overview

The Gather API supports three types of questions, each designed for different interview formats:

1. **Audio Questions** - Questions with text scripts that can be automatically converted to audio using text-to-speech (TTS) technology. These are used in **standard video interviews** where candidates record video responses to audio prompts.

2. **Survey Questions** - Multiple choice, yes/no, thumbs up/down, or free text questions used for **screening and questionnaires**. These can be added to interviews or used in standalone surveys. Perfect for pre-screening candidates or gathering structured feedback.

3. **AI Text Questions** - Text-based questions used in **AI-powered interviews** where candidates provide written responses that are evaluated by AI. Ideal for technical assessments and written evaluations.

## Audio Questions

Audio questions are the building blocks of standard video interviews. You can create questions with text scripts that can be automatically converted to audio using text-to-speech (TTS) technology.

### Create Audio Question

Create a new audio question with optional TTS audio generation.

**Endpoint:** `POST /qsi/gather/questions`

<ParamField name="title" type="string" required>
  Title of the question
</ParamField>

<ParamField name="description" type="string">
  Optional description of the question
</ParamField>

<ParamField name="userId" type="string">
  User ID who will be marked as the creator. If not provided, will be resolved from API credential.
</ParamField>

<ParamField name="audioURL" type="string">
  URL to a pre-recorded question audio file. Either provide `audioURL` OR use `questionScript` + `narratorId` for automatic TTS generation.
</ParamField>

<ParamField name="questionScript" type="string">
  Script text for the question. If provided with `narratorId`, audio will be generated automatically via TTS. Either provide `audioURL` OR use `questionScript` + `narratorId`.
</ParamField>

<ParamField name="narratorId" type="string">
  Narrator ID for AI-generated audio. **Required** if using `questionScript` for automatic TTS generation. Ignored if `audioURL` is provided.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://api.prod.qualifi.hr/qsi/gather/questions \
      -H "x-api-key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "title": "Tell me about yourself",
        "description": "A standard introductory question",
        "audioURL": "https://example.com/audio/question1.mp3",
        "narratorId": "narrator-uuid",
        "questionScript": "Tell me about yourself and your background."
      }'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch('https://api.prod.qualifi.hr/qsi/gather/questions', {
      method: 'POST',
      headers: {
        'x-api-key': apiKey,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Tell me about yourself',
        description: 'A standard introductory question',
        audioURL: 'https://example.com/audio/question1.mp3',
        narratorId: 'narrator-uuid',
        questionScript: 'Tell me about yourself and your background.'
      })
    });
    const question = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.prod.qualifi.hr/qsi/gather/questions',
        headers={
            'x-api-key': api_key,
            'Content-Type': 'application/json'
        },
        json={
            'title': 'Tell me about yourself',
            'description': 'A standard introductory question',
            'audioURL': 'https://example.com/audio/question1.mp3',
            'narratorId': 'narrator-uuid',
            'questionScript': 'Tell me about yourself and your background.'
        }
    )
    question = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Tell me about yourself",
    "description": "A standard introductory question",
    "audioURL": "https://example.com/audio/question1.mp3",
    "narratorId": "narrator-uuid",
    "questionScript": "Tell me about yourself and your background."
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "question": {
        "id": "question-uuid",
        "title": "Tell me about yourself",
        "audioURL": "https://example.com/audio/question1.mp3",
        "description": "A standard introductory question",
        "narratorId": "narrator-uuid",
        "questionScript": "Tell me about yourself and your background.",
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

<Callout type="info">
  The `userId` field is optional. If not provided, it will be resolved from your API credential. If you need to specify a different user as the creator, provide the `userId` field.
</Callout>

<Callout type="warning">
  **Audio Source**: You must provide either:

  * `audioURL` (pre-recorded audio), OR
  * `questionScript` + `narratorId` (for automatic TTS generation)

  Do not provide both `audioURL` and `questionScript` - if `audioURL` is provided, it will be used and `questionScript`/`narratorId` will be ignored.
</Callout>

### List Audio Questions

List all audio questions with pagination and filtering.

**Endpoint:** `GET /qsi/gather/questions`

<ParamField query="page" type="number">
  Page number (0-indexed, default: 0)
</ParamField>

<ParamField query="pageSize" type="number">
  Items per page (default: 50, max: 100)
</ParamField>

<ParamField query="archived" type="boolean">
  Filter by archived status (true, false, or omit for all)
</ParamField>

<ParamField query="search" type="string">
  Search term to filter by title/description
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://api.prod.qualifi.hr/qsi/gather/questions?page=0&pageSize=50&archived=false" \
      -H "x-api-key: ${API_KEY}"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const params = new URLSearchParams({
      page: '0',
      pageSize: '50',
      archived: 'false'
    });

    const response = await fetch(
      `https://api.prod.qualifi.hr/qsi/gather/questions?${params}`,
      {
        headers: {
          'x-api-key': apiKey
        }
      }
    );
    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    params = {
        'page': 0,
        'pageSize': 50,
        'archived': False
    }
    response = requests.get(
        'https://api.prod.qualifi.hr/qsi/gather/questions',
        headers={'x-api-key': api_key},
        params=params
    )
    data = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "questions": [
        {
          "id": "question-uuid",
          "title": "Tell me about yourself",
          "audioURL": "https://example.com/audio/question1.mp3",
          "description": "A standard introductory question",
          "narratorId": "narrator-uuid",
          "questionScript": "Tell me about yourself and your background.",
          "organizationId": "org-uuid",
          "teamId": "team-uuid",
          "createdById": "user-uuid",
          "createdAt": "2024-01-01T00:00:00Z",
          "updatedAt": "2024-01-01T00:00:00Z",
          "archivedAt": null
        }
      ],
      "pagination": {
        "total": 100,
        "page": 0,
        "pages": 2,
        "pageSize": 50
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Get Audio Question

Retrieve a specific audio question by ID.

**Endpoint:** `GET /qsi/gather/questions/{questionId}`

<ParamField path="questionId" type="string" required>
  UUID of the question to retrieve
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET https://api.prod.qualifi.hr/qsi/gather/questions/{questionId} \
      -H "x-api-key: ${API_KEY}"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.prod.qualifi.hr/qsi/gather/questions/${questionId}`,
      {
        headers: {
          'x-api-key': apiKey
        }
      }
    );
    const question = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        f'https://api.prod.qualifi.hr/qsi/gather/questions/{question_id}',
        headers={'x-api-key': api_key}
    )
    question = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "question": {
        "id": "question-uuid",
        "title": "Tell me about yourself",
        "audioURL": "https://example.com/audio/question1.mp3",
        "description": "A standard introductory question",
        "narratorId": "narrator-uuid",
        "questionScript": "Tell me about yourself and your background.",
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Update Audio Question

Update audio question properties. Only include fields you want to update.

**Endpoint:** `PATCH /qsi/gather/questions/{questionId}`

<ParamField path="questionId" type="string" required>
  UUID of the question to update
</ParamField>

<ParamField name="title" type="string">
  Updated title
</ParamField>

<ParamField name="description" type="string">
  Updated description
</ParamField>

<ParamField name="questionScript" type="string">
  Updated question script
</ParamField>

<ParamField name="audioURL" type="string">
  Updated audio URL
</ParamField>

<ParamField name="narratorId" type="string">
  Updated narrator ID
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Updated question title",
    "questionScript": "Updated script text"
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "question": {
        "id": "question-uuid",
        "title": "Updated question title",
        "questionScript": "Updated script text",
        "updatedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Archive Audio Question

Archive an audio question (soft delete).

**Endpoint:** `DELETE /qsi/gather/questions/{questionId}`

<ParamField path="questionId" type="string" required>
  UUID of the question to archive
</ParamField>

<ParamField query="userId" type="string">
  User ID for the archive action. If not provided, will be resolved from API credential.
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "question": {
        "id": "question-uuid",
        "archivedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

## Survey Questions

Survey questions are used for screening and questionnaires. They support multiple question types including multiple choice, yes/no, thumbs up/down, and free text.

### Survey Question Types

The following question types are supported:

* **`FREE_TEXT`** - Free text response with optional character limit. Use `maxCharacterLength` to set limits.
* **`YES_NO`** - Yes/No question with optional preferred option. Use `preferredOption` to mark the preferred answer.
* **`THUMBS_UP_DOWN`** - Thumbs up/down question. Requires `options` array with two options.
* **`MULTIPLE_CHOICE`** - Single answer multiple choice question. Requires `options` array.
* **`MULTIPLE_CHOICE_WEIGHTED`** - Multiple choice with weighted scoring. Requires `options` array with weights.
* **`MULTIPLE_CHOICE_MULTIPLE_ANSWER`** - Multiple choice allowing multiple selections. Requires `options` array. Use `selectAllForFullScore` to require all options for full score.

### Create Survey Question

Create a new survey question.

**Endpoint:** `POST /qsi/gather/survey-questions`

<ParamField name="type" type="string" required>
  Question type: `FREE_TEXT`, `YES_NO`, `THUMBS_UP_DOWN`, `MULTIPLE_CHOICE`, `MULTIPLE_CHOICE_WEIGHTED`, or `MULTIPLE_CHOICE_MULTIPLE_ANSWER`
</ParamField>

<ParamField name="title" type="string" required>
  Title of the question
</ParamField>

<ParamField name="userId" type="string">
  User ID who will be marked as the creator. If not provided, will be resolved from API credential.
</ParamField>

<ParamField name="includeScoring" type="boolean">
  Whether to include scoring for this question (default: false)
</ParamField>

<ParamField name="knockout" type="boolean">
  Whether this is a knockout question (default: false)
</ParamField>

<ParamField name="selectAllForFullScore" type="boolean">
  For `MULTIPLE_CHOICE_MULTIPLE_ANSWER` questions, whether all options must be selected for full score (default: false). Ignored for other question types.
</ParamField>

<ParamField name="maxCharacterLength" type="number">
  Maximum character length for `FREE_TEXT` questions. Ignored for other question types.
</ParamField>

<ParamField name="supportingVideoURL" type="string">
  URL to supporting video for the question. Optional for all question types.
</ParamField>

<ParamField name="preferredOption" type="boolean">
  For `YES_NO` questions only, the preferred option (true = yes, false = no). Ignored for other question types.
</ParamField>

<ParamField name="options" type="array">
  **Required** for `MULTIPLE_CHOICE`, `MULTIPLE_CHOICE_WEIGHTED`, `MULTIPLE_CHOICE_MULTIPLE_ANSWER`, and `THUMBS_UP_DOWN` question types. Array of options where each option should have:

  * `title` (string, required) - Option text
  * `preferred` (boolean, optional) - Whether this is a preferred option
  * `weight` (number, optional) - Weight for scoring (0-5)
  * `ordinal` (number, required) - Display order (1, 2, 3, etc.)

  Not used for `FREE_TEXT` or `YES_NO` question types.
</ParamField>

<Tabs>
  <Tab title="Free Text Question">
    ```json theme={null}
    {
      "type": "FREE_TEXT",
      "title": "Tell us about your experience",
      "includeScoring": true,
      "maxCharacterLength": 500
    }
    ```
  </Tab>

  <Tab title="Yes/No Question">
    ```json theme={null}
    {
      "type": "YES_NO",
      "title": "Do you have 5+ years of experience?",
      "includeScoring": true,
      "knockout": false,
      "preferredOption": true
    }
    ```
  </Tab>

  <Tab title="Multiple Choice Question">
    ```json theme={null}
    {
      "type": "MULTIPLE_CHOICE",
      "title": "What is your preferred work style?",
      "includeScoring": true,
      "knockout": false,
      "options": [
        {
          "title": "Remote",
          "preferred": true,
          "weight": 5,
          "ordinal": 1
        },
        {
          "title": "Hybrid",
          "weight": 3,
          "ordinal": 2
        },
        {
          "title": "On-site",
          "weight": 1,
          "ordinal": 3
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Thumbs Up/Down">
    ```json theme={null}
    {
      "type": "THUMBS_UP_DOWN",
      "title": "Would you recommend this candidate?",
      "includeScoring": true,
      "knockout": false,
      "options": [
        {
          "title": "Thumbs Up",
          "preferred": true,
          "weight": 5,
          "ordinal": 1
        },
        {
          "title": "Thumbs Down",
          "weight": 1,
          "ordinal": 2
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Weighted Multiple Choice">
    ```json theme={null}
    {
      "type": "MULTIPLE_CHOICE_WEIGHTED",
      "title": "Rate your experience level",
      "includeScoring": true,
      "options": [
        {
          "title": "Expert",
          "weight": 5,
          "ordinal": 1
        },
        {
          "title": "Advanced",
          "weight": 4,
          "ordinal": 2
        },
        {
          "title": "Intermediate",
          "weight": 3,
          "ordinal": 3
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Multiple Answer">
    ```json theme={null}
    {
      "type": "MULTIPLE_CHOICE_MULTIPLE_ANSWER",
      "title": "Select all that apply",
      "includeScoring": true,
      "selectAllForFullScore": true,
      "options": [
        {
          "title": "Option 1",
          "weight": 2,
          "ordinal": 1
        },
        {
          "title": "Option 2",
          "weight": 2,
          "ordinal": 2
        }
      ]
    }
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "MULTIPLE_CHOICE",
    "title": "What is your preferred work style?",
    "includeScoring": true,
    "options": [
      {
        "title": "Remote",
        "preferred": true,
        "weight": 5,
        "ordinal": 1
      },
      {
        "title": "Hybrid",
        "weight": 3,
        "ordinal": 2
      }
    ]
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "surveyQuestion": {
        "id": "survey-question-uuid",
        "type": "MULTIPLE_CHOICE",
        "title": "What is your preferred work style?",
        "includeScoring": true,
        "knockout": false,
        "selectAllForFullScore": false,
        "maxCharacterLength": null,
        "supportingVideoURL": null,
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### List Survey Questions

List survey questions with pagination and filtering.

**Endpoint:** `GET /qsi/gather/survey-questions`

<ParamField query="page" type="number">
  Page number (0-indexed, default: 0)
</ParamField>

<ParamField query="pageSize" type="number">
  Items per page (default: 50, max: 100)
</ParamField>

<ParamField query="search" type="string">
  Search term to filter by title (case-insensitive)
</ParamField>

<ParamField query="archived" type="boolean">
  Filter by archived status (true, false, or omit for all)
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://api.prod.qualifi.hr/qsi/gather/survey-questions?page=0&pageSize=50" \
      -H "x-api-key: ${API_KEY}"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const params = new URLSearchParams({
      page: '0',
      pageSize: '50'
    });

    const response = await fetch(
      `https://api.prod.qualifi.hr/qsi/gather/survey-questions?${params}`,
      {
        headers: {
          'x-api-key': apiKey
        }
      }
    );
    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    params = {
        'page': 0,
        'pageSize': 50
    }
    response = requests.get(
        'https://api.prod.qualifi.hr/qsi/gather/survey-questions',
        headers={'x-api-key': api_key},
        params=params
    )
    data = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "surveyQuestions": [
        {
          "id": "survey-question-uuid-1",
          "title": "Rate your experience",
          "type": "MULTIPLE_CHOICE",
          "organizationId": "org-uuid",
          "teamId": "team-uuid",
          "supportingVideoURL": null,
          "maxCharacterLength": null,
          "includeScoring": true,
          "selectAllForFullScore": false,
          "knockout": false,
          "includeInEvaluation": true,
          "createdById": "user-uuid",
          "createdAt": "2024-01-01T00:00:00Z",
          "updatedAt": "2024-01-01T00:00:00Z",
          "archivedAt": null
        },
        {
          "id": "survey-question-uuid-2",
          "title": "Tell us about yourself",
          "type": "FREE_TEXT",
          "organizationId": "org-uuid",
          "teamId": "team-uuid",
          "supportingVideoURL": null,
          "maxCharacterLength": 1000,
          "includeScoring": false,
          "selectAllForFullScore": false,
          "knockout": false,
          "includeInEvaluation": false,
          "createdById": "user-uuid",
          "createdAt": "2024-01-01T00:00:00Z",
          "updatedAt": "2024-01-01T00:00:00Z",
          "archivedAt": null
        }
      ],
      "pagination": {
        "total": 2,
        "page": 0,
        "pages": 1,
        "pageSize": 50
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Get Survey Question

Retrieve a specific survey question by ID.

**Endpoint:** `GET /qsi/gather/survey-questions/{surveyQuestionId}`

<ParamField path="surveyQuestionId" type="string" required>
  UUID of the survey question to retrieve
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "surveyQuestion": {
        "id": "survey-question-uuid",
        "type": "MULTIPLE_CHOICE",
        "title": "What is your preferred work style?",
        "includeScoring": true,
        "knockout": false,
        "selectAllForFullScore": false,
        "maxCharacterLength": null,
        "supportingVideoURL": null,
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Update Survey Question

Update survey question properties. Only include fields you want to update.

**Endpoint:** `PATCH /qsi/gather/survey-questions/{surveyQuestionId}`

<ParamField path="surveyQuestionId" type="string" required>
  UUID of the survey question to update
</ParamField>

<ParamField name="title" type="string">
  Updated title
</ParamField>

<ParamField name="type" type="string">
  Updated question type
</ParamField>

<ParamField name="includeScoring" type="boolean">
  Updated scoring setting
</ParamField>

<ParamField name="knockout" type="boolean">
  Updated knockout setting
</ParamField>

<ParamField name="selectAllForFullScore" type="boolean">
  Updated select all for full score setting
</ParamField>

<ParamField name="maxCharacterLength" type="number">
  Updated character limit
</ParamField>

<ParamField name="supportingVideoURL" type="string">
  Updated supporting video URL
</ParamField>

<ParamField name="preferredOption" type="boolean">
  Updated preferred option (for yes/no questions)
</ParamField>

<ParamField name="options" type="array">
  Updated options array. Include `id` for existing options to update, omit `id` for new options.
</ParamField>

<ParamField name="removedOptionIds" type="array">
  Array of option IDs to remove
</ParamField>

<ParamField name="userId" type="string">
  User ID for the update action. Required when updating multiple choice questions.
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Updated survey question title",
    "options": [
      {
        "id": "existing-option-uuid",
        "title": "Updated Option 1",
        "weight": 5,
        "ordinal": 1
      },
      {
        "title": "New Option",
        "weight": 3,
        "ordinal": 2
      }
    ],
    "removedOptionIds": ["old-option-uuid"]
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "surveyQuestion": {
        "id": "survey-question-uuid",
        "title": "Updated survey question title",
        "updatedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Archive Survey Question

Archive a survey question (soft delete).

**Endpoint:** `DELETE /qsi/gather/survey-questions/{surveyQuestionId}`

<ParamField path="surveyQuestionId" type="string" required>
  UUID of the survey question to archive
</ParamField>

<ParamField query="userId" type="string">
  User ID for the archive action. If not provided, will be resolved from API credential.
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "surveyQuestion": {
        "id": "survey-question-uuid",
        "archivedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

## AI Text Questions

AI text questions are used in AI-powered interviews where candidates provide written responses that are evaluated by AI.

### Create AI Text Question

Create a new AI text question.

**Endpoint:** `POST /qsi/gather/ai-text-questions`

<ParamField name="title" type="string" required>
  Title of the question
</ParamField>

<ParamField name="questionText" type="string" required>
  The question text that will be presented to candidates
</ParamField>

<ParamField name="description" type="string">
  Optional description of the question
</ParamField>

<ParamField name="userId" type="string">
  User ID who will be marked as the creator. If not provided, will be resolved from API credential.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://api.prod.qualifi.hr/qsi/gather/ai-text-questions \
      -H "x-api-key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "title": "Technical Assessment",
        "description": "A comprehensive technical question for candidates",
        "questionText": "Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs."
      }'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch('https://api.prod.qualifi.hr/qsi/gather/ai-text-questions', {
      method: 'POST',
      headers: {
        'x-api-key': apiKey,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title: 'Technical Assessment',
        description: 'A comprehensive technical question for candidates',
        questionText: 'Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs.'
      })
    });
    const question = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.post(
        'https://api.prod.qualifi.hr/qsi/gather/ai-text-questions',
        headers={
            'x-api-key': api_key,
            'Content-Type': 'application/json'
        },
        json={
            'title': 'Technical Assessment',
            'description': 'A comprehensive technical question for candidates',
            'questionText': 'Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs.'
        }
    )
    question = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Technical Assessment",
    "description": "A comprehensive technical question for candidates",
    "questionText": "Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs."
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestion": {
        "id": "ai-text-question-uuid",
        "title": "Technical Assessment",
        "description": "A comprehensive technical question for candidates",
        "questionText": "Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs.",
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### List AI Text Questions

List AI text questions with pagination and filtering.

**Endpoint:** `GET /qsi/gather/ai-text-questions`

<ParamField query="page" type="number">
  Page number (0-indexed, default: 0)
</ParamField>

<ParamField query="pageSize" type="number">
  Items per page (default: 50, max: 100)
</ParamField>

<ParamField query="search" type="string">
  Search term to filter by title
</ParamField>

<ParamField query="archived" type="boolean">
  Filter by archived status (true, false, or omit for all)
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://api.prod.qualifi.hr/qsi/gather/ai-text-questions?page=0&pageSize=50" \
      -H "x-api-key: ${API_KEY}"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const params = new URLSearchParams({
      page: '0',
      pageSize: '50'
    });

    const response = await fetch(
      `https://api.prod.qualifi.hr/qsi/gather/ai-text-questions?${params}`,
      {
        headers: {
          'x-api-key': apiKey
        }
      }
    );
    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    params = {
        'page': 0,
        'pageSize': 50
    }
    response = requests.get(
        'https://api.prod.qualifi.hr/qsi/gather/ai-text-questions',
        headers={'x-api-key': api_key},
        params=params
    )
    data = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestions": [
        {
          "id": "ai-text-question-uuid",
          "title": "Technical Assessment",
          "description": "A comprehensive technical question for candidates",
          "questionText": "Explain the difference between REST and GraphQL APIs.",
          "organizationId": "org-uuid",
          "teamId": "team-uuid",
          "createdById": "user-uuid",
          "createdAt": "2024-01-01T00:00:00Z",
          "updatedAt": "2024-01-01T00:00:00Z",
          "archivedAt": null
        }
      ],
      "pagination": {
        "total": 10,
        "page": 0,
        "pages": 1,
        "pageSize": 50
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Get AI Text Question

Retrieve a specific AI text question by ID.

**Endpoint:** `GET /qsi/gather/ai-text-questions/{aiTextQuestionId}`

<ParamField path="aiTextQuestionId" type="string" required>
  UUID of the AI text question to retrieve
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestion": {
        "id": "ai-text-question-uuid",
        "title": "Technical Assessment",
        "description": "A comprehensive technical question for candidates",
        "questionText": "Explain the difference between REST and GraphQL APIs, including their use cases and trade-offs.",
        "organizationId": "org-uuid",
        "teamId": "team-uuid",
        "createdById": "user-uuid",
        "createdAt": "2024-01-01T00:00:00Z",
        "updatedAt": "2024-01-01T00:00:00Z",
        "archivedAt": null
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Update AI Text Question

Update AI text question properties. Only include fields you want to update.

**Endpoint:** `PATCH /qsi/gather/ai-text-questions/{aiTextQuestionId}`

<ParamField path="aiTextQuestionId" type="string" required>
  UUID of the AI text question to update
</ParamField>

<ParamField name="title" type="string">
  Updated title
</ParamField>

<ParamField name="description" type="string">
  Updated description
</ParamField>

<ParamField name="questionText" type="string">
  Updated question text
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  {
    "title": "Updated Technical Assessment",
    "description": "Updated description",
    "questionText": "Updated question text with more details."
  }
  ```

  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestion": {
        "id": "ai-text-question-uuid",
        "title": "Updated Technical Assessment",
        "description": "Updated description",
        "questionText": "Updated question text with more details.",
        "updatedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Archive AI Text Question

Archive an AI text question (soft delete).

**Endpoint:** `DELETE /qsi/gather/ai-text-questions/{aiTextQuestionId}`

<ParamField path="aiTextQuestionId" type="string" required>
  UUID of the AI text question to archive
</ParamField>

<ParamField query="userId" type="string">
  User ID for the archive action. If not provided, will be resolved from API credential.
</ParamField>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestion": {
        "id": "ai-text-question-uuid",
        "archivedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

### Unarchive AI Text Question

Unarchive a previously archived AI text question.

**Endpoint:** `POST /qsi/gather/ai-text-questions/{aiTextQuestionId}/unarchive`

<ParamField path="aiTextQuestionId" type="string" required>
  UUID of the AI text question to unarchive
</ParamField>

<CodeGroup>
  ```json Request theme={null}
  {}
  ```

  ```json Response theme={null}
  {
    "data": {
      "aiTextQuestion": {
        "id": "ai-text-question-uuid",
        "archivedAt": null,
        "updatedAt": "2024-01-01T00:00:00Z"
      }
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

## Get Questions by Interview

Retrieve all questions (audio questions, survey questions, and AI text questions) associated with a specific interview, sorted by ordinal.

**Endpoint:** `GET /qsi/gather/questions/interview/{interviewId}`

<ParamField path="interviewId" type="string" required>
  UUID of the interview
</ParamField>

<ParamField query="teamId" type="string">
  Optional override for team ID. If not provided, will be resolved from your API credential (teamId or defaultTeamId). Required if using an organization-level API key without a defaultTeamId.
</ParamField>

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET https://api.prod.qualifi.hr/qsi/gather/questions/interview/{interviewId} \
      -H "x-api-key: ${API_KEY}"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch(
      `https://api.prod.qualifi.hr/qsi/gather/questions/interview/${interviewId}`,
      {
        headers: {
          'x-api-key': apiKey
        }
      }
    );
    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    response = requests.get(
        f'https://api.prod.qualifi.hr/qsi/gather/questions/interview/{interview_id}',
        headers={'x-api-key': api_key}
    )
    data = response.json()
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```json Response theme={null}
  {
    "data": {
      "questions": [
        {
          "id": "uuid",
          "title": "Question title",
          "audioURL": "https://...",
          "audioType": "question",
          "ordinal": 1,
          "transcription": "...",
          "organizationId": "uuid",
          "teamId": "uuid",
          "createdAt": "2024-01-01T00:00:00Z",
          "updatedAt": "2024-01-01T00:00:00Z"
        }
      ]
    },
    "meta": {
      "requestId": "uuid",
      "timestamp": "2024-01-01T00:00:00Z"
    }
  }
  ```
</CodeGroup>

<Callout type="info">
  Returns all question types (audio questions, survey questions, and AI text questions) associated with the interview. Questions are sorted by ordinal. Audio URLs are automatically converted to MP3 format. Survey questions and AI text questions will have `audioType: null` and `audioURL: null`.
</Callout>

## Audio Generation

Audio questions support text-to-speech (TTS) audio generation:

* **TTS Providers**: WellSaid or current TTS model
* **Async Processing**: Audio generation happens asynchronously
* **Webhook Notifications**: Use webhooks to be notified when audio generation completes
* **Pre-uploaded Audio**: Alternatively, provide your own `audioURL`

<Callout type="info">
  When `questionScript` is provided with `narratorId`, the question is created immediately, but `audioURL` may be `null` until generation completes. Check the `transcriptionStatus` field to monitor generation progress.
</Callout>

## Related Resources

<CardGroup cols={2}>
  <Card title="Interviews" icon="file-text" href="/api-reference/interviews">
    Learn how to use questions in interviews
  </Card>

  <Card title="Narrators" icon="user" href="/api-reference/narrators">
    Explore available narrators for TTS
  </Card>
</CardGroup>
