---
updatedAt: 2026-08-14T20:32:53.000Z
agentTools:
  projectIndex: https://docs.voiceform.com/llms.txt
---

# Create a question

Feature gates:
- `matrix` requires plan feature `matrix_question`
- `file-upload` requires plan feature `file_upload`
- other non-basic types require `all_question_types`

`properties` and `multiple_choice_items` are validated per `type` (unknown property keys are stripped).
Create applies product defaults when omitted (e.g. voice record times, 5-star rating, 3×4 matrix).
Choice types (`multiple-choice`, `dropdown`, `checkbox`) require at least one `multiple_choice_items[].value`.
See schema components `QuestionProperties*`, `MatrixColumn`, and `MultipleChoiceItem`.


# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Voiceform Public API",
    "version": "1.0.0",
    "description": "Public REST API for Voiceform surveys, questions, actions, folders, webhooks, and results.\n\n**Authentication:** Sanctum personal access token with the `public-api-call` ability.\nThe caller's plan must include the `api_access` feature. Requests without a valid token\nor without `api_access` are rejected.\n\n**Feature gates** (plan-dependent; missing features return `{ error: { code, message, details } }`):\n- `api_access` — required for all endpoints (middleware)\n- `matrix_question` — required to create `matrix` questions\n- `file_upload` — required to create `file-upload` questions\n- `all_question_types` — when false, only basic question types are allowed\n- `dynamic_loops` — required for action type `loop`\n- `condition_scripts` — required when an action condition uses `script: true`\n\nSync this file to ReadMe manually if needed (no automated publish from this repo).\n"
  },
  "servers": [
    {
      "url": "https://app.voiceform.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Questions"
    }
  ],
  "paths": {
    "/surveys/{survey_id}/questions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SurveyId"
        }
      ],
      "post": {
        "tags": [
          "Questions"
        ],
        "operationId": "createQuestion",
        "summary": "Create a question",
        "description": "Feature gates:\n- `matrix` requires plan feature `matrix_question`\n- `file-upload` requires plan feature `file_upload`\n- other non-basic types require `all_question_types`\n\n`properties` and `multiple_choice_items` are validated per `type` (unknown property keys are stripped).\nCreate applies product defaults when omitted (e.g. voice record times, 5-star rating, 3×4 matrix).\nChoice types (`multiple-choice`, `dropdown`, `checkbox`) require at least one `multiple_choice_items[].value`.\nSee schema components `QuestionProperties*`, `MatrixColumn`, and `MultipleChoiceItem`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuestionCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created question",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Question"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Sanctum PAT",
        "description": "Personal access token created with ability `public-api-call`.\nPlan feature `api_access` is required.\n"
      }
    },
    "parameters": {
      "SurveyId": {
        "name": "survey_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "responses": {
      "Error": {
        "description": "API error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "details"
            ],
            "properties": {
              "code": {
                "type": "string",
                "examples": [
                  "forbidden",
                  "survey_not_found",
                  "matrix_question",
                  "file_upload",
                  "dynamic_loops",
                  "condition_scripts",
                  "api_access"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        }
      },
      "Question": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "survey_id": {
            "type": "string",
            "format": "uuid"
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "audio_url": {
            "type": "string",
            "nullable": true
          },
          "views_count": {
            "type": "integer"
          },
          "starts_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "is_optional": {
            "type": "boolean"
          },
          "type": {
            "$ref": "#/components/schemas/QuestionType"
          },
          "properties": {
            "description": "Type-specific configuration (see QuestionProperties* schemas)",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/QuestionProperties"
              }
            ]
          },
          "multiple_choice_items": {
            "type": "array",
            "nullable": true,
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/MultipleChoiceItem"
                },
                {
                  "$ref": "#/components/schemas/RatingItem"
                }
              ]
            }
          },
          "order": {
            "type": "integer"
          },
          "enable_text_input": {
            "type": "boolean",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "variable_name": {
            "type": "string",
            "nullable": true
          },
          "hash": {
            "type": "string",
            "nullable": true
          },
          "ai_probing": {
            "type": "boolean",
            "description": "True when properties.enable_probing is set"
          }
        }
      },
      "QuestionType": {
        "type": "string",
        "enum": [
          "voice-response",
          "voice-question",
          "date-picker",
          "name",
          "email",
          "phone-number",
          "dropdown",
          "yesno",
          "rating",
          "checkbox",
          "custom-field",
          "multiple-choice",
          "net-promoter-score",
          "description-slide",
          "input-check-slide",
          "numeric-input",
          "file-upload",
          "matrix"
        ],
        "description": "`matrix` requires feature `matrix_question`.\n`file-upload` requires feature `file_upload`.\n"
      },
      "MultipleChoiceItem": {
        "type": "object",
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "type": "string",
            "description": "Option label/value (must be unique within the question)"
          },
          "exclusive": {
            "type": "boolean",
            "description": "Checkbox only — selecting this clears other options"
          }
        }
      },
      "RatingItem": {
        "type": "object",
        "required": [
          "icon",
          "order"
        ],
        "properties": {
          "icon": {
            "type": "string",
            "enum": [
              "star",
              "heart",
              "user",
              "number"
            ]
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10
          }
        }
      },
      "MatrixRow": {
        "type": "object",
        "required": [
          "id",
          "title"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable row id (e.g. row_<hex>)"
          },
          "title": {
            "type": "string"
          },
          "translation": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "MatrixColumnOption": {
        "type": "object",
        "required": [
          "id",
          "value"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "MatrixColumn": {
        "type": "object",
        "required": [
          "id",
          "title",
          "type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable column id (e.g. column_<hex>)"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "radio",
              "checkbox",
              "text",
              "numeric",
              "dropdown"
            ],
            "description": "Cell input type. Radio/checkbox use `group_name` for exclusive groups.\nDropdown requires `properties.options`. Numeric may set min/max/prefix/suffix.\n"
          },
          "optional": {
            "type": "boolean",
            "description": "Whether the cell/group is optional"
          },
          "group_name": {
            "type": "string",
            "nullable": true,
            "pattern": "^[a-zA-Z_]\\w*$",
            "description": "Shared name for radio/checkbox column groups"
          },
          "width": {
            "type": "integer",
            "nullable": true
          },
          "translation": {
            "type": "string",
            "nullable": true
          },
          "properties": {
            "type": "object",
            "description": "Type-dependent column config",
            "properties": {
              "field_placeholder": {
                "type": "string",
                "nullable": true
              },
              "min_number": {
                "type": "number",
                "nullable": true
              },
              "max_number": {
                "type": "number",
                "nullable": true
              },
              "allow_decimal_numbers": {
                "type": "boolean"
              },
              "prefix": {
                "type": "string",
                "nullable": true
              },
              "suffix": {
                "type": "string",
                "nullable": true
              },
              "options": {
                "type": "array",
                "description": "Required for dropdown columns",
                "items": {
                  "$ref": "#/components/schemas/MatrixColumnOption"
                }
              }
            }
          }
        }
      },
      "QuestionProperties": {
        "type": "object",
        "description": "Union of allowed keys across question types. Only keys valid for the question's `type`\nare kept; others are stripped. Prefer the type-specific shapes below.\n",
        "additionalProperties": false,
        "properties": {
          "continue_button_label": {
            "type": "string",
            "nullable": true
          },
          "maxRecordTime": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3600,
            "description": "voice-* — max recording seconds (default 150)"
          },
          "minRecordTime": {
            "type": "integer",
            "minimum": 0,
            "maximum": 3600,
            "description": "voice-* — min recording seconds (default 0)"
          },
          "min_variable": {
            "type": "string",
            "nullable": true
          },
          "max_variable": {
            "type": "string",
            "nullable": true
          },
          "minNumberOfCharacters": {
            "type": "integer",
            "nullable": true
          },
          "prevent_recording_deletion": {
            "type": "boolean"
          },
          "start_recording_on_page_load": {
            "type": "boolean"
          },
          "audio_attachment_play_on_mount": {
            "type": "boolean"
          },
          "enable_probing": {
            "type": "boolean"
          },
          "goal": {
            "type": "string",
            "nullable": true
          },
          "max_probes": {
            "type": "integer",
            "nullable": true
          },
          "vocabulary": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "custom_labels": {
            "type": "object",
            "properties": {
              "hit_record": {
                "type": "string",
                "nullable": true
              },
              "record_more": {
                "type": "string",
                "nullable": true
              },
              "text_input_label": {
                "type": "string",
                "nullable": true
              },
              "text_input_placeholder": {
                "type": "string",
                "nullable": true
              },
              "hint_text": {
                "type": "string",
                "nullable": true
              },
              "or_divider": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "yes_label": {
            "type": "string",
            "nullable": true,
            "description": "yesno"
          },
          "no_label": {
            "type": "string",
            "nullable": true,
            "description": "yesno"
          },
          "range_option": {
            "type": "string",
            "nullable": true,
            "enum": [
              "until_now",
              "from_now",
              "custom"
            ],
            "description": "date-picker"
          },
          "min_date": {
            "type": "string",
            "nullable": true,
            "format": "date",
            "description": "date-picker YYYY-MM-DD"
          },
          "max_date": {
            "type": "string",
            "nullable": true,
            "format": "date"
          },
          "starting_active_state": {
            "type": "string",
            "nullable": true,
            "enum": [
              "MONTH",
              "YEAR"
            ]
          },
          "text_input_look": {
            "type": "boolean"
          },
          "min_number": {
            "type": "number",
            "nullable": true,
            "description": "numeric-input"
          },
          "max_number": {
            "type": "number",
            "nullable": true
          },
          "allow_decimal_numbers": {
            "type": "boolean"
          },
          "field_placeholder": {
            "type": "string",
            "nullable": true
          },
          "prefix": {
            "type": "string",
            "nullable": true
          },
          "suffix": {
            "type": "string",
            "nullable": true
          },
          "randomize_options": {
            "type": "boolean",
            "description": "multiple-choice / dropdown / checkbox"
          },
          "excluded_from_randomization": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "add_none_of_the_above": {
            "type": "boolean",
            "description": "checkbox"
          },
          "min_choices_number": {
            "type": "integer",
            "nullable": true
          },
          "max_choices_number": {
            "type": "integer",
            "nullable": true
          },
          "local_files": {
            "type": "boolean",
            "description": "file-upload"
          },
          "camera": {
            "type": "boolean"
          },
          "screencast": {
            "type": "boolean"
          },
          "auto_proceed": {
            "type": "boolean"
          },
          "file_types": {
            "type": "string",
            "enum": [
              "all",
              "images",
              "videos",
              "documents",
              "custom"
            ]
          },
          "file_types_patterns": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "Required when file_types is custom (MIME/ext patterns)"
          },
          "min_number_of_files": {
            "type": "integer",
            "nullable": true,
            "minimum": 1
          },
          "max_number_of_files": {
            "type": "integer",
            "nullable": true,
            "minimum": 1
          },
          "table_title": {
            "type": "string",
            "nullable": true,
            "description": "matrix"
          },
          "row_headers_width": {
            "type": "integer",
            "nullable": true
          },
          "rows": {
            "type": "array",
            "description": "matrix — required (defaults to 3 rows on create if omitted)",
            "items": {
              "$ref": "#/components/schemas/MatrixRow"
            }
          },
          "columns": {
            "type": "array",
            "description": "matrix — required (defaults to 4 radio columns on create if omitted)",
            "items": {
              "$ref": "#/components/schemas/MatrixColumn"
            }
          },
          "randomize_rows": {
            "type": "boolean"
          },
          "matrix_validation_message": {
            "type": "boolean"
          },
          "row_source_variable": {
            "type": "string",
            "nullable": true
          },
          "repeat_headers": {
            "type": "boolean"
          },
          "rows_per_header_repeat": {
            "type": "integer",
            "nullable": true,
            "minimum": 1
          }
        }
      },
      "QuestionCreate": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "$ref": "#/components/schemas/QuestionType"
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "properties": {
            "allOf": [
              {
                "$ref": "#/components/schemas/QuestionProperties"
              }
            ],
            "nullable": true
          },
          "multiple_choice_items": {
            "type": "array",
            "nullable": true,
            "description": "Required (≥1) for multiple-choice, dropdown, and checkbox.\nRating uses RatingItem objects (defaults to 5 stars).\nMust be empty/omitted for voice, matrix, file-upload, yesno, etc.\n",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/MultipleChoiceItem"
                },
                {
                  "$ref": "#/components/schemas/RatingItem"
                }
              ]
            }
          },
          "is_optional": {
            "type": "boolean"
          },
          "order": {
            "type": "integer"
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "example": {
          "type": "matrix",
          "text": "Rate each feature",
          "properties": {
            "table_title": "Features",
            "rows": [
              {
                "id": "row_ease",
                "title": "Ease of use"
              },
              {
                "id": "row_speed",
                "title": "Speed"
              }
            ],
            "columns": [
              {
                "id": "col_1",
                "title": "Poor",
                "type": "radio",
                "optional": false,
                "group_name": "rating"
              },
              {
                "id": "col_5",
                "title": "Excellent",
                "type": "radio",
                "optional": false,
                "group_name": "rating"
              }
            ]
          }
        }
      }
    }
  }
}
```