Create Question API
This endpoint currently requires JWT Authentication.
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 optioncorrect_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 optioncorrect_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 optionscorrect_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 labelscorrect_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_answeris "Paris", user can answer "paris", "PARIS", " Paris " (all correct) - But "Paris, France" would be incorrect if
correct_answeris 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_answerfield 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 characterquestion_text: Required, minimum 1 charactercategory: Required, minimum 1 charactercorrect_answer: Required, non-empty (specific format per type)points: Optional, defaults to system value if not provideddifficulty_level: Optional (easy/medium/hard)explanation: Optional, shown after answer submissiontags: Optional JSON value for categorization
Options Array
- Each option must have both
labelandvalue - 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:
| Error | Meaning |
|---|---|
EmptyCorrectAnswer | correct_answer is empty or whitespace only |
MissingOptions | Question type requires options but array is empty |
InvalidCorrectAnswer | Answer format doesn't match type requirements |
InvalidTrueFalseOptions | TrueFalse must have 0 or exactly 2 options |
| Specific format errors | Detailed messages for pipes, blanks, pairs, etc. |
Tips
- Case Sensitivity: Most validations are case-insensitive for user convenience
- Whitespace: Leading/trailing whitespace is automatically trimmed
- Label vs Value: You can use either option labels or values in correct_answer (except MatchingPairs and Ordering which use labels only)
- Testing: Use the validation endpoint before creating questions to verify format
- Alternatives: Use FillBlank with alternatives (pipe
|) for flexible answers - Partial Ordering: Ordering questions can accept subset of items (useful for "arrange first 3 steps")