Skip to main content

Create Quiz Request Api

Create a new quiz with specified settings and access controls.

Field Details POST/api/v1/quizzes

title (required)

The quiz title/name. Must be at least 1 character long.

Example: "Introduction to Rust Programming"

description (optional)

A detailed description of the quiz content and purpose.

Example: "Test your knowledge of Rust fundamentals including ownership, borrowing, and lifetimes."

categories (optional)

Quiz category string. If omitted, defaults to "general".

Constraints: 1-255 characters, cannot be null.

tags (optional)

Tags for the quiz.

Type: array of strings

Constraints: maximum 50 items, cannot be null.

metadata (optional)

Free-form metadata for the quiz.

Type: flat JSON object

Constraints: maximum 50 keys; values must be either a string or an array of strings; no nested objects; no null values.

available_from (conditional)

Start date/time when the quiz becomes available. Required when availability is scheduled.

Format: ISO 8601 datetime (e.g., "2025-11-14T10:00:00Z")

available_until (conditional)

End date/time when the quiz becomes unavailable. Required when availability is scheduled.

Format: ISO 8601 datetime (e.g., "2025-11-14T18:00:00Z")

Validation: Must be after available_from

time_limit_seconds (required)

Time limit for completing the quiz in seconds. 60 seconds is minimum time limit

Examples:

  • 3600 = 1 hour
  • 1800 = 30 minutes
  • 60 = minimum time limit

⚠️ Important - Deadline Mutation System:

When using submission_mode: hard_limit, the actual deadline for an attempt is dynamically calculated at attempt creation time, not fixed to this value.

How it works:

  • This field sets the maximum attempt duration
  • The actual deadline = min(available_until, started_at + time_limit_seconds)
  • The effective time limit can be shorter if the quiz availability window closes before the full duration

Example:

  • Quiz: available_until = 2025-01-23 18:00, time_limit_seconds = 7200 (2 hours)
  • Participant starts at: 17:30
  • Configured time limit: 2 hours (7200 seconds)
  • Actual deadline: 18:00 (only 30 minutes available)
  • Effective time limit: 1800 seconds (30 minutes) ⚠️ Mutated!

API consumers should be aware that participants may receive less time than time_limit_seconds if they start near the quiz's available_until deadline.

status (required)

Publication status of the quiz. See QuizStatus enum for details.

Values: draft, published, archived

Default: draft

access_type (required)

Access control type. See QuizAccessType enum for details.

Values: shared, private, public

Note: When set to shared, an access code is automatically generated.

availability (required)

Time-based availability setting. See QuizAvailability enum for details.

Values: always, scheduled

Note: When set to scheduled, both available_from and available_until are required.

shuffle_questions (required)

Whether to randomize question order for each attempt.

Values: true or false

Use Cases:

  • true: Reduces cheating in exams
  • false: Maintains logical question flow

max_attempts (required)

Maximum number of attempts allowed per participant. Must be at least 1.

Examples:

  • 1 = Single attempt only
  • 3 = Up to 3 attempts
  • 999 = Effectively unlimited

submission_mode (required)

Controls how the quiz enforces submission limits and availability windows.

Values: soft_limit, hard_limit

Default: soft_limit

Behavior:

  • soft_limit: Flexible enforcement

    • Participants can submit answers even after time limits expire
    • Can be combined with any availability setting
    • Use for practice quizzes or low-stakes assessments
  • hard_limit: Strict enforcement

    • Quiz access is strictly controlled by time limits and availability windows
    • Cannot be combined with availability: always (validation error)
    • Can only be used with availability: scheduled
    • Use for timed exams or time-sensitive assessments

Validation Rules:

  • soft_limit + always = Valid
  • soft_limit + scheduled = Valid
  • hard_limit + scheduled = Valid
  • hard_limit + always = Invalid (returns validation error)

Use Cases:

  • soft_limit: Practice quizzes, self-paced learning, flexible deadlines
  • hard_limit: Timed exams, competitive assessments, strict deadlines

How HardLimit Deadline Calculation Works:

When a participant starts a quiz attempt with hard_limit submission mode, the system mutates the deadline dynamically using dual time constraints:

deadline = min(available_until, started_at + time_limit_seconds)

⚠️ Deadline Mutation: The configured time_limit_seconds is the maximum duration, but the actual time limit is mutated at attempt creation time. This means participants may receive less time than the configured limit if they start the quiz near its available_until deadline.

The quiz will be auto-submitted at whichever comes first:

  1. The quiz's available_until timestamp (end of quiz availability window)
  2. The attempt's started_at + time_limit_seconds (personal time limit)

API Consumer Notice: When retrieving attempt data, the time_limit_seconds field in the response will reflect the mutated/adjusted value, not the original configured value. For example, if the quiz has time_limit_seconds: 7200 (2 hours) but only 30 minutes remain until available_until, the API will return time_limit_seconds: 1800 (30 minutes) for that attempt.

Why HardLimit Requires Scheduled Availability:

HardLimit needs available_until to calculate the quiz window deadline. With availability: always, there is no available_until value, making it impossible to enforce the hard deadline. This is why the validation rule exists:

  • hard_limit + always = Invalid
  • hard_limit + scheduled = Valid (has available_until)

Example Scenarios:

Scenario 1: Attempt Time Limit Expires First

  • Quiz availability: 2025-01-23 09:00 to 2025-01-23 18:00 (9 hours)
  • Time limit: 3600 seconds (1 hour)
  • Participant starts at: 2025-01-23 10:30
  • Calculated deadline: 2025-01-23 11:30 (started_at + 1 hour) ✓
  • Auto-submit at: 11:30 (1 hour personal time limit)

Scenario 2: Quiz Window Expires First

  • Quiz availability: 2025-01-23 17:00 to 2025-01-23 18:00 (1 hour)
  • Time limit: 7200 seconds (2 hours)
  • Participant starts at: 2025-01-23 17:30
  • Calculated deadline: 2025-01-23 18:00 (available_until) ✓
  • Auto-submit at: 18:00 (quiz window closes, not the full 2 hours)

Scenario 3: Both Constraints Align

  • Quiz availability: 2025-01-23 14:00 to 2025-01-23 15:00 (1 hour)
  • Time limit: 3600 seconds (1 hour)
  • Participant starts at: 2025-01-23 14:00 (exactly when quiz opens)
  • Calculated deadline: 2025-01-23 15:00 (both constraints equal) ✓
  • Auto-submit at: 15:00 (quiz window and time limit expire simultaneously)

Auto-Submission Scheduling:

When an attempt is created with hard_limit, the system automatically schedules a background job to submit the attempt at the calculated deadline. This ensures participants cannot exceed the time constraints, even if they don't manually submit.


Updating a Quiz — Protected Fields

When updating a quiz via PUT /api/v1/quizzes/{id}, most fields can be changed freely. However, the following fields are protected while participants are actively taking the quiz:

  • time_limit_seconds
  • max_attempts
  • submission_mode
  • client_only

If any active (unsubmitted) attempts exist, updating these fields will return a 409 Conflict error with code G-001. The same applies to deleting a quiz.

See Managing Active Attempts for how to handle this and use the force-submit endpoint.