Skip to main content

Create Question API

Details POST/api/v1/questions
Authentication Required

This endpoint currently requires JWT Authentication.

Authorization: Bearer <token>

Note: Support for Owner API Key (Hybrid Auth) is planned for future updates.

Request to create a new question with automatic validation based on question type.

The API validates the question structure and correct answer format according to the specified question type. Each type has specific requirements for correct_answer format and options array.


Question Types & Validation Rules

1. MultipleChoice

Single correct answer from multiple options.

Requirements:

  • options: Required, at least 1 option
  • correct_answer: Single value (label or value from options), no commas allowed

Options Format:

{
"options": [
{"label": "A", "value": "Paris"},
{"label": "B", "value": "London"},
{"label": "C", "value": "Berlin"}
],
"correct_answer": "A"
}

Validation:

  • "A" or "Paris" (matches option label or value)
  • "A,B" (no commas allowed)
  • "D" (not in options)
  • Case-insensitive matching supported

2. MultipleSelect

Multiple correct answers from options.

Requirements:

  • options: Required, at least 1 option
  • correct_answer: Comma-separated values (labels or values from options)

Options Format:

{
"options": [
{"label": "A", "value": "Red"},
{"label": "B", "value": "Blue"},
{"label": "C", "value": "Green"}
],
"correct_answer": "A,B"
}

Validation:

  • "A" (single answer)
  • "A,B" or "Red,Blue" (multiple answers)
  • "A,B,C" (all answers)
  • "A," (empty value after comma)
  • "A,,B" (consecutive commas)
  • Case-insensitive matching supported

3. TrueFalse

Binary true/false question.

Requirements:

  • options: Optional. If provided, must be exactly 2 options with values "true" and "false"
  • correct_answer: Must be "true" or "false" (case-insensitive)

Options Format (Optional):

{
"options": [
{"label": "True", "value": "true"},
{"label": "False", "value": "false"}
],
"correct_answer": "true"
}

Validation:

  • "true" or "false" (case-insensitive)
  • "True", "FALSE", " true " (whitespace trimmed)
  • "yes", "no", "1", "0" (only true/false allowed)
  • If options provided, must have exactly 2 with values "true" and "false"

4. Ordering

User must arrange items in correct sequence.

Requirements:

  • options: Required, at least 2 options
  • correct_answer: Comma-separated sequence of labels only

Important: The evaluator validates label sequence only, not option values. Options define available items, correct answer defines the order using labels.

Options Format:

{
"options": [
{"label": "A", "value": "First step"},
{"label": "B", "value": "Second step"},
{"label": "C", "value": "Third step"}
],
"correct_answer": "A,B,C"
}

Explanation: User must arrange items in order A→B→C. The values are just for display.

Validation:

  • "A,B,C" (using labels in correct order)
  • "A,B" (partial ordering - subset of items)
  • "a,b,c" (case-insensitive labels)
  • "A" (need at least 2 items)
  • "A,D" (D not in options)
  • "First step,Second step" (values not allowed, use labels only)
  • Case-insensitive matching supported for labels

5. MatchingPairs

User pairs items together using labels.

Requirements:

  • options: Required, at least 2 options with unique labels
  • correct_answer: Comma-separated pairs in format "label:label" (e.g., "A:B,C:D")

Important: The evaluator validates label pairs only, not option values. Options define available items, correct answer defines which labels should be paired.

Options Format:

{
"options": [
{"label": "A", "value": "France"},
{"label": "B", "value": "Paris"},
{"label": "C", "value": "Germany"},
{"label": "D", "value": "Berlin"}
],
"correct_answer": "A:B,C:D"
}

Explanation: User must pair A with B (France→Paris) and C with D (Germany→Berlin). The actual values are just for display.

Validation:

  • "A:B,C:D" (pairs A with B, C with D)
  • "a:b,c:d" (case-insensitive)
  • ✅ All labels in pairs (A,B,C,D) must exist in options
  • "A:E" (E not in options)
  • "A:A" or "C:C" (cannot pair a label with itself)
  • "A:B,A:B" (duplicate pairs not allowed)
  • "A:B,B:A" (reverse duplicate - same pair, different order)
  • "A:" or ":B" (empty label in pair)
  • "A:B:C" (exactly one colon per pair)
  • Each pair must be unique and labels cannot be paired with themselves
  • Option values are ignored for validation

6. FillBlank

Fill-in-the-blank with support for multiple blanks and alternative answers.

Requirements:

  • options: Optional (can be empty array or contain word choices for frontend display)
  • correct_answer: Use <> to separate multiple blanks, use | to separate alternative answers within a blank

Important: Options are not validated against the correct answer. If you provide options, they are purely for frontend use (e.g., word bank, dropdown choices). The evaluator only validates user's answer against the correct_answer field.

Format:

  • Single blank: "answer"
  • Single blank with alternatives: "answer1|answer2|answer3"
  • Multiple blanks: "blank1<>blank2<>blank3"
  • Multiple blanks with alternatives: "apple|fruit<>water|H2O<>blue|navy"

Example with Word Bank:

{
"options": [
{"label": "1", "value": "Paris"},
{"label": "2", "value": "water"},
{"label": "3", "value": "blue"},
{"label": "4", "value": "red"}
],
"correct_answer": "Paris|paris<>water|H2O|aqua<>blue"
}

Explanation:

  • Options provide word choices for frontend (word bank, drag-and-drop, etc.)
  • Evaluation only checks user answer against correct_answer
  • Blank 1: Accepts "Paris" or "paris"
  • Blank 2: Accepts "water", "H2O", or "aqua"
  • Blank 3: Accepts only "blue"
  • Note: "red" is a distractor, user can still type "H2O" even if not in options

Validation:

  • "answer" (single blank)
  • "apple|fruit" (alternatives)
  • "apple<>water" (multiple blanks)
  • "apple|fruit<>water|H2O<>blue" (combined)
  • "|apple" (leading pipe)
  • "apple|" (trailing pipe)
  • "apple||fruit" (consecutive pipes)
  • "apple| |fruit" (empty alternative)
  • "apple<><>water" (empty blank)
  • Each alternative must have content
  • Options array is not validated against correct_answer

7. ShortAnswer

Short text answer expecting exact match with user's expected answer.

Requirements:

  • options: Not required (can be empty array)
  • correct_answer: Any non-empty text (this is what user answer must exactly match)

Example:

{
"options": [],
"correct_answer": "Paris"
}

Validation:

  • ✅ Any non-empty text
  • ❌ Empty string or whitespace only

Evaluation Behavior:

  • User answer must exactly match the correct_answer
  • Matching is case-insensitive with whitespace trimming
  • Example: If correct_answer is "Paris", user can answer "paris", "PARIS", " Paris " (all correct)
  • But "Paris, France" would be incorrect if correct_answer is just "Paris"

8. Essay

Long-form text answer requiring manual grading by instructor.

Requirements:

  • options: Not required (can be empty array)
  • correct_answer: Reference answer or grading rubric (non-empty, for instructor use only)

Example:

{
"options": [],
"correct_answer": "Grading rubric: Must discuss climate impact (30%), provide examples (30%), conclusion (20%), grammar (20%)"
}

Validation:

  • ✅ Any non-empty text
  • ❌ Empty string or whitespace only

Evaluation Behavior:

  • Essay answers are NOT automatically evaluated
  • Evaluator returns 0.0 score automatically
  • The correct_answer field is for instructor reference only (grading rubric, sample answer, criteria)
  • Instructor must manually review and grade essay responses
  • Use the explanation field or correct_answer to store grading criteria

General Validation Rules

All Question Types

  • question_title: Required, minimum 1 character
  • question_text: Required, minimum 1 character
  • category: Required, minimum 1 character
  • correct_answer: Required, non-empty (specific format per type)
  • points: Optional, defaults to system value if not provided
  • difficulty_level: Optional (easy/medium/hard)
  • explanation: Optional, shown after answer submission
  • tags: Optional JSON value for categorization

Options Array

  • Each option must have both label and value
  • Labels typically use single letters (A, B, C, D) for UI display
  • Values contain the actual content shown to users
  • Required for: MultipleChoice, MultipleSelect, Ordering, MatchingPairs
  • Optional for: TrueFalse, FillBlank (word bank/choices for frontend, not validated)
  • Not used for: ShortAnswer, Essay

Example Requests

Multiple Choice Example

{
"question_title": "Capital of France",
"question_text": "What is the capital city of France?",
"question_type": "MultipleChoice",
"correct_answer": "A",
"category": "Geography",
"options": [
{"label": "A", "value": "Paris"},
{"label": "B", "value": "London"},
{"label": "C", "value": "Berlin"},
{"label": "D", "value": "Madrid"}
],
"points": 10,
"difficulty_level": "easy",
"explanation": "Paris is the capital and largest city of France."
}

Matching Pairs Example

{
"question_title": "Match Countries with Capitals",
"question_text": "Match each country with its capital city",
"question_type": "MatchingPairs",
"correct_answer": "A:B,C:D,E:F",
"category": "Geography",
"options": [
{"label": "A", "value": "France"},
{"label": "B", "value": "Paris"},
{"label": "C", "value": "Germany"},
{"label": "D", "value": "Berlin"},
{"label": "E", "value": "Italy"},
{"label": "F", "value": "Rome"}
],
"points": 15,
"difficulty_level": "medium"
}

Fill Blank Example

{
"question_title": "Complete the Sentences",
"question_text": "Fill in the blanks: The capital of France is ___. Water is made of ___. The sky is ___.",
"question_type": "FillBlank",
"correct_answer": "Paris|paris<>H2O|water<>blue",
"category": "General Knowledge",
"options": [],
"points": 15,
"difficulty_level": "medium"
}

Validation Error Messages

The API returns specific error messages to help debug validation issues:

ErrorMeaning
EmptyCorrectAnswercorrect_answer is empty or whitespace only
MissingOptionsQuestion type requires options but array is empty
InvalidCorrectAnswerAnswer format doesn't match type requirements
InvalidTrueFalseOptionsTrueFalse must have 0 or exactly 2 options
Specific format errorsDetailed messages for pipes, blanks, pairs, etc.

Tips

  1. Case Sensitivity: Most validations are case-insensitive for user convenience
  2. Whitespace: Leading/trailing whitespace is automatically trimmed
  3. Label vs Value: You can use either option labels or values in correct_answer (except MatchingPairs and Ordering which use labels only)
  4. Testing: Use the validation endpoint before creating questions to verify format
  5. Alternatives: Use FillBlank with alternatives (pipe |) for flexible answers
  6. Partial Ordering: Ordering questions can accept subset of items (useful for "arrange first 3 steps")