Example 1
📥 JSON import

Spelling bee — import a pre-built JSON file

The fastest way to get a spelling bee into QuizBuilder is to import a JSON test bundle. Each word gets one block: an audio context (uploaded separately) and a short-text question auto-scored against the correct spelling.

1

Prepare the JSON file

A QuizBuilder test export is a single JSON object. The blocks array holds groups of questions. For a spelling bee each block has one word, one optional audio context, and one short_text question.

{
  "title": "Grade 4 Spelling Bee",
  "description": "Listen and spell each word correctly.",
  "question_count_mode": "all",
  "show_correct_answers": true,
  "blocks": [
    {
      "title": "Word 1",
      "context_json": null,   // audio uploaded after import
      "questions": [
        {
          "type": "short_text",
          "points": 1,
          "review_required": false,
          "prompt_json": {
            "type": "doc",
            "content": [{ "type": "paragraph",
              "content": [{ "type": "text", "text": "Type the word you hear." }] }]
          },
          "correct_answer": "necessary",
          "options_json": null
        }
      ]
    },
    {
      "title": "Word 2",
      "context_json": null,
      "questions": [
        {
          "type": "short_text",
          "points": 1,
          "review_required": false,
          "prompt_json": {
            "type": "doc",
            "content": [{ "type": "paragraph",
              "content": [{ "type": "text", "text": "Type the word you hear." }] }]
          },
          "correct_answer": "receive",
          "options_json": null
        }
      ]
    }
  ]
}
💡 Set review_required: false on short_text questions to enable instant auto-scoring. QuizBuilder compares the answer case-insensitively and trims whitespace.
2

Import the file in the admin panel

Go to Tests → Import, select your JSON file, and click Import. QuizBuilder creates the test with all blocks and questions. The test is saved as a draft — no takers can access it yet.

3

Upload audio for each block

Open the test editor. For each block, click the Upload audio / video link in the block context area and select the corresponding MP3 file. The file is uploaded and stored server-side.

The context area will change to show a media badge (♪ audio/mpeg) with Replace and Remove buttons — confirming the audio is attached.

4

Publish and share

Set the test status to Published, choose your access mode (open link, access codes, or registered users), and copy the shareable URL. Takers hear the audio, type the word, and see their score immediately on submission.

📎 You can also import a ZIP bundle that includes the JSON and all media files together — no manual upload step needed. Use Tests → Export (ZIP) on any existing test to see the bundle format.

Example 2
📊 CSV import

Any quiz — import from a spreadsheet

If you already have questions in a spreadsheet (Excel, Google Sheets, Numbers), you can export as CSV and import directly into QuizBuilder. One test is created automatically, with questions grouped by the optional block column.

1

Prepare your spreadsheet

Your CSV must have a header row with these columns. All except type and prompt are optional.

type         # multiple_choice | multiple_select | true_false | short_text | long_text
prompt       # question text (plain text)
options      # choices separated by | for mc/ms, e.g.  Paris|London|Berlin
correct_answer # single value for mc/tf, comma-list for ms, plain text for short_text
points       # integer, default 1
tags         # comma-separated tags (optional)
block        # block/group title to organize questions (optional)
2

Example CSV — geography quiz

type,prompt,options,correct_answer,points,tags,block
multiple_choice,What is the capital of France?,Paris|London|Berlin|Madrid,Paris,2,geography,Europe
multiple_choice,Which country is the largest by area?,Russia|Canada|USA|China,Russia,2,geography,World
true_false,The Amazon river is in Africa.,,false,1,geography,Americas
multiple_select,"Which are continents? (select all)","Africa|Europe|Pacific|Antarctica","Africa,Europe,Antarctica",3,geography,World
short_text,Spell the name of the capital of Japan.,,Tokyo,1,spelling,Asia
💡 correct_answer rules by type:
multiple_choice / true_false: the exact option value, e.g. Paris or false
multiple_select: comma-separated values, e.g. Africa,Europe,Antarctica
short_text: the expected text (auto-scored, case-insensitive)
long_text: leave blank — always goes to manual review
3

Import the file

In the admin panel, go to Tests and click the ↑ CSV button in the top-right corner.

Select your .csv file. QuizBuilder creates a new unpublished test named after the filename, with all questions grouped into blocks matching the block column.

After import: review the test, edit any question that needs adjusting, then click Publish to make it live.

💡 The file must be saved as UTF-8. In Excel: File → Save As → CSV UTF-8 (Comma delimited). In Google Sheets: File → Download → Comma-separated values (.csv).

Example 3
🐍 Python script

Spelling bee — bulk create with seed_audio.py

The examples/seed_audio.py script automates the full pipeline: it creates a test, adds a block per word, generates or loads an MP3 for each word, uploads it, and wires the audio to the block — all via the QuizBuilder REST API. No manual clicking required.

1

Install dependencies

# Inside the QuizBuilder/examples/ directory
pip install requests gtts

requests calls the QuizBuilder API. gtts (Google Text-to-Speech) generates MP3 files on the fly when no local audio is available. If you have your own MP3s, gtts is optional.

2

Run with auto-generated speech (gTTS)

The simplest invocation — just provide your QuizBuilder URL, admin credentials, and a word list. The script calls Google TTS for each word and uploads the result.

python seed_audio.py \
  --url   http://localhost:8000 \
  --email admin@example.com \
  --password your_password \
  --title "Grade 5 Spelling Bee" \
  --words necessary receive separate beautiful \
          conscience occurrence rhythm
⚠️ gTTS requires an internet connection and uses Google's servers to synthesise speech. For offline or production use, supply your own MP3 files instead (see step 3).
3

Run with local MP3 files (offline, recommended)

Place your MP3 files in a folder. Each file must be named exactly as the word with an .mp3 extension (e.g. necessary.mp3). Pass the folder with --local-audio:

# Folder structure:
# spelling_bee_audio/
#   necessary.mp3
#   receive.mp3
#   separate.mp3
#   ...

python seed_audio.py \
  --url   http://localhost:8000 \
  --email admin@example.com \
  --password your_password \
  --title "Grade 5 Spelling Bee" \
  --local-audio ./spelling_bee_audio \
  --words necessary receive separate beautiful \
          conscience occurrence rhythm

When --local-audio is set the script checks the folder first. If the file exists it's used directly; if not, it falls back to gTTS. This lets you use professional recordings for some words and synthesised speech for the rest.

4

What the script creates

For each word the script:

1. Creates a block titled with the word number (e.g. "Word 1").

2. Uploads the MP3 to /api/v1/media/ and gets back a media_file_id.

3. Sets the block's context_json to an audio node referencing that file ID.

4. Adds a short_text question with correct_answer set to the word.

When done, the test is ready to publish — open it in the admin panel, review, and set to Published.


Example 4
🤖 AI-assisted

Let an AI build the test for you

Any capable AI (Claude, ChatGPT, Gemini) can generate a complete QuizBuilder-compatible JSON file from a description. You describe the test; the AI produces the JSON; you import it. This works for spelling bees, multiple-choice exams, reading comprehension — anything QuizBuilder supports.

1

Give the AI the format specification

The AI needs to know the exact JSON structure QuizBuilder expects. Paste the following context at the top of your prompt:

System context — paste this to the AI first

You are generating test data for the QuizBuilder self-hosted assessment platform. Output a single valid JSON object matching this schema exactly:

{
  "title": "string",
  "description": "string | null",
  "question_count_mode": "all" | "draw",
  "draw_count": "integer | null",
  "time_limit_minutes": "integer | null",
  "show_correct_answers": true | false,
  "blocks": [
    {
      "title": "string",
      "context_json": null,
      "questions": [
        {
          "type": "multiple_choice | multiple_select | true_false |
                   short_text | long_text | file_upload",
          "points": integer,
          "review_required": true | false,
          "prompt_json": {
            // Tiptap doc node — plain paragraph is fine
            "type": "doc",
            "content": [{ "type": "paragraph",
              "content": [{ "type": "text", "text": "question text here" }] }]
          },
          "correct_answer": "string | null",
          "options_json": null
        }
      ]
    }
  ]
}

Rules:

  • For multiple_choice: set options_json to ["Option A", "Option B", ...] and correct_answer to the exact text of the correct option.
  • For multiple_select: set options_json to a list and correct_answer to a JSON array, e.g. ["A", "C"].
  • For true_false: set correct_answer to "true" or "false".
  • For short_text with auto-scoring: set review_required: false and correct_answer to the expected string.
  • For long_text or file_upload: set review_required: true and correct_answer: null.
  • Always set context_json: null — media must be added manually after import.
  • Output only the JSON. No markdown fences, no explanation.
2

Write your test request

After the format context, describe the test you want. Be specific about:

• The subject and grade level

• Number of questions (and blocks if mixed types)

• Question types and scoring method

• Time limit, passing score, whether to show answers

Example prompt — spelling bee

Create a QuizBuilder JSON test called "Grade 4 Spelling Bee — Spring 2026" with 20 words. Use short_text questions with review_required: false. Each block should be titled "Word 1", "Word 2", etc. The question prompt in every block should be: "Listen and type the word you hear." Use common Grade 4 English spelling words. Show correct answers after submission. No time limit.

Example prompt — mixed exam

Create a QuizBuilder JSON test called "Biology 101 — Chapter 3 Quiz". 20 questions. Mix: 10 multiple choice (4 options each), 5 true/false, 5 short_text auto-scored. Each block should have one question. Topic: cell biology (organelles, mitosis, photosynthesis). 1 point per question. Show correct answers. Time limit: 30 minutes.

3

Validate and import

Save the AI's output as a .json file. Before importing, do a quick sanity check:

• Confirm the JSON is valid (paste into jsonlint.com or use python -m json.tool file.json)

• Spot-check a few correct_answer values against the question options

• Verify review_required matches the question type intent

Then go to Tests → Import and upload the file. The test loads instantly.

4

Add audio after import (for AI-generated spelling bees)

The AI cannot upload media files, so context_json will be null for all blocks. After import you have two options:

Option A — manual upload: open each block in the test editor and use the "↑ Upload audio / video" link to attach an MP3.

Option B — run seed_audio.py: export the AI-generated test as JSON, pass the word list to seed_audio.py --local-audio, and let the script handle all uploads automatically (see Example 2 above).

💡 The most powerful workflow combines both approaches: ask the AI to generate the full question set (words, distractors, metadata), then run seed_audio.py with your professional recordings to attach audio in bulk — no clicking required.

Quick reference — question type cheat sheet for AI prompts

// Multiple choice — 4 options, auto-scored
{
  "type": "multiple_choice", "points": 1, "review_required": false,
  "options_json": ["Mitochondria", "Ribosome", "Nucleus", "Golgi"],
  "correct_answer": "Mitochondria"
}

// Multiple select — pick all correct, auto-scored
{
  "type": "multiple_select", "points": 2, "review_required": false,
  "options_json": ["A", "B", "C", "D"],
  "correct_answer": ["A", "C"]
}

// True / false — auto-scored
{
  "type": "true_false", "points": 1, "review_required": false,
  "options_json": null, "correct_answer": "true"
}

// Short text — auto-scored (exact match, case-insensitive)
{
  "type": "short_text", "points": 1, "review_required": false,
  "options_json": null, "correct_answer": "necessary"
}

// Essay — manual review required
{
  "type": "long_text", "points": 10, "review_required": true,
  "options_json": null, "correct_answer": null
}

Example 5
📋 Copy & paste

Full agent context — give this to any AI

Copy the block below and paste it as the first message to any AI (Claude, ChatGPT, Gemini). It contains everything the AI needs: the complete JSON format, every question type with correct encoding, all the rules, and ready-to-use examples. Then just describe the test you want in plain English.

How to use

  1. Copy the entire block below.
  2. Paste it as your first message to the AI (or as the system prompt).
  3. Follow up in the same chat with your test request, e.g. "Create a 20-word Grade 4 spelling bee" or "Make a 15-question biology multiple choice quiz".
  4. Save the AI's output as mytest.json.
  5. Import it in QuizBuilder: Tests → Import → select the file.
You are a test builder for QuizBuilder, a self-hosted assessment platform.
Your only job is to output a single valid JSON object that can be imported directly into QuizBuilder.
Output ONLY the JSON — no markdown fences, no explanation, no extra text.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TOP-LEVEL STRUCTURE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{
  "title": "string — test name",
  "description": "string or null",
  "question_count_mode": "all",          // always "all" unless told to use random draw
  "draw_count": null,                     // integer only when question_count_mode is "draw"
  "time_limit_minutes": null,             // integer (e.g. 30) or null for untimed
  "show_correct_answers": true,           // true = show answers after submission
  "blocks": [ ...array of blocks... ]
}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BLOCK STRUCTURE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Each block is a group of questions (usually one question per block).
Always set context_json to null — audio is added manually after import.

{
  "title": "string — block label, e.g. 'Word 1' or 'Question 1'",
  "context_json": null,
  "questions": [ ...array of questions... ]
}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
QUESTION STRUCTURE — COMMON FIELDS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Every question has these fields:

{
  "type": "...",              // see types below
  "points": 1,                // integer, default 1
  "review_required": false,   // true only for long_text and file_upload
  "prompt_json": {            // the question text — always this exact wrapper
    "type": "doc",
    "content": [{
      "type": "paragraph",
      "content": [{ "type": "text", "text": "YOUR QUESTION TEXT HERE" }]
    }]
  },
  "correct_answer": "...",   // see encoding per type below
  "options_json": null        // see encoding per type below
}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
QUESTION TYPES — FULL REFERENCE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. MULTIPLE CHOICE  (one correct answer, auto-scored)
   "type": "multiple_choice"
   "review_required": false
   "options_json": ["Option A", "Option B", "Option C", "Option D"]
   "correct_answer": "Option B"   ← must be the exact text of the correct option

   Example:
   {
     "type": "multiple_choice", "points": 1, "review_required": false,
     "prompt_json": { "type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"What is the capital of France?"}]}] },
     "options_json": ["London", "Paris", "Berlin", "Madrid"],
     "correct_answer": "Paris"
   }

──────────────────────────────────────────

2. MULTIPLE SELECT  (one or more correct answers, all-or-nothing scoring)
   "type": "multiple_select"
   "review_required": false
   "options_json": ["A", "B", "C", "D"]
   "correct_answer": ["A", "C"]   ← a JSON array listing the correct option texts

   Example:
   {
     "type": "multiple_select", "points": 2, "review_required": false,
     "prompt_json": { "type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Which are mammals? Select all that apply."}]}] },
     "options_json": ["Dolphin", "Shark", "Bat", "Salmon"],
     "correct_answer": ["Dolphin", "Bat"]
   }

──────────────────────────────────────────

3. TRUE / FALSE  (auto-scored)
   "type": "true_false"
   "review_required": false
   "options_json": null
   "correct_answer": "true"   ← must be the string "true" or "false"

   Example:
   {
     "type": "true_false", "points": 1, "review_required": false,
     "prompt_json": { "type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"The Earth orbits the Sun."}]}] },
     "options_json": null,
     "correct_answer": "true"
   }

──────────────────────────────────────────

4. SHORT TEXT — AUTO-SCORED  (exact match, case-insensitive)
   Use for spelling bees, fill-in-the-blank, single-word answers.
   "type": "short_text"
   "review_required": false
   "options_json": null
   "correct_answer": "expected word"

   Example:
   {
     "type": "short_text", "points": 1, "review_required": false,
     "prompt_json": { "type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Type the word you hear."}]}] },
     "options_json": null,
     "correct_answer": "necessary"
   }

──────────────────────────────────────────

5. LONG TEXT / ESSAY  (manual review, no auto-scoring)
   "type": "long_text"
   "review_required": true
   "options_json": null
   "correct_answer": null

   Example:
   {
     "type": "long_text", "points": 10, "review_required": true,
     "prompt_json": { "type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Explain the causes of World War I in your own words."}]}] },
     "options_json": null,
     "correct_answer": null
   }

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RULES — READ CAREFULLY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

- Output ONLY the JSON object. No markdown, no comments inside the JSON.
- Every question MUST have prompt_json using the doc/paragraph/text wrapper shown above.
- Never omit any field — use null for optional fields you don't need.
- For multiple_choice: correct_answer must be the exact string from options_json.
- For multiple_select: correct_answer must be a JSON array: ["A", "B"]
- For true_false: correct_answer is always the string "true" or "false", never a boolean.
- For short_text auto-scoring: review_required must be false and correct_answer must be a string.
- For long_text: review_required must be true and correct_answer must be null.
- context_json is always null — never generate media references.
- Validate that every correct_answer for multiple_choice exactly matches one entry in options_json.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
COMPLETE MINIMAL EXAMPLE (2-block test)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{
  "title": "Sample Quiz",
  "description": null,
  "question_count_mode": "all",
  "draw_count": null,
  "time_limit_minutes": null,
  "show_correct_answers": true,
  "blocks": [
    {
      "title": "Question 1",
      "context_json": null,
      "questions": [{
        "type": "multiple_choice",
        "points": 1,
        "review_required": false,
        "prompt_json": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"What is 2 + 2?"}]}]},
        "options_json": ["3", "4", "5", "6"],
        "correct_answer": "4"
      }]
    },
    {
      "title": "Question 2",
      "context_json": null,
      "questions": [{
        "type": "true_false",
        "points": 1,
        "review_required": false,
        "prompt_json": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"The sky is blue."}]}]},
        "options_json": null,
        "correct_answer": "true"
      }]
    }
  ]
}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NOW DESCRIBE THE TEST YOU WANT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 The last line "NOW DESCRIBE THE TEST YOU WANT" is a cue — after pasting, just type your request in the same message or the next one. Example: "Create a 20-word Grade 5 spelling bee. One short_text question per block titled Word 1, Word 2, etc. No time limit."