CTFFactory Docs

Post-Event Report

After a CTF event concludes, CTFFactory compiles a structured post-event report that captures participant performance, challenge solve rates, scoring distribution, and operational metrics. This report is the primary tool for retrospective analysis and for demonstrating the value of the event to stakeholders.

Accessing the Report

The post-event report becomes available within a few minutes of the event end time.

  • In the UI: navigate to the event and click Report in the top navigation.
  • Via API: retrieve the full report as a structured JSON document through the REST API.
GET /api/v1/events/{event_id}/report
Authorization: Bearer {api_key}

The response is a single JSON object containing all report sections described below.

[!NOTE] The report endpoint is available for all events, including those that ended early or were cancelled. Incomplete events produce a partial report reflecting the data collected up to termination.

Report Structure

The full JSON report contains the following top-level keys:

{
  "event": { ... },
  "summary": { ... },
  "participants": [ ... ],
  "challenges": [ ... ],
  "timeline": [ ... ],
  "difficulty_retrospective": { ... }
}

event β€” Event Metadata

Basic event information: name, ID, start and end timestamps, scoring mode, total registered participants, and deployment region.

summary β€” Aggregate Statistics

High-level numbers for quick reporting:

Field Description
total_participants Number of registered participants (or teams in team mode)
active_participants Participants who made at least one solve attempt
total_solves Sum of all correct flag submissions across all challenges
overall_solve_rate total_solves / (active_participants Γ— challenge_count)
median_score Median participant score at event end
top_score Highest individual or team score
duration_seconds Actual event duration

participants β€” Per-Participant Statistics

An array of objects, one per participant or team, sorted by final rank:

{
  "rank": 1,
  "name": "team_name",
  "score": 2450,
  "solves": 12,
  "first_blood_count": 3,
  "last_solve_at": "2025-06-15T18:42:00Z",
  "solve_history": [
    { "challenge_id": "web-001", "solved_at": "...", "points_awarded": 200 }
  ]
}

challenges β€” Per-Challenge Statistics

An array of objects, one per challenge, that captures how each challenge performed:

Field Description
challenge_id Internal challenge identifier
title Challenge title
category Technical category
difficulty Configured difficulty level
points Final point value (at event end for dynamic scoring)
solve_count Number of participants who solved it
solve_rate solve_count / active_participants
first_blood Participant name and timestamp of first solve
median_solve_time_seconds Median time from event start to solve across all solvers
incorrect_attempts Total incorrect flag submissions
attempt_to_solve_ratio incorrect_attempts / solve_count β€” a proxy for challenge friction

timeline β€” Event Timeline

A chronological log of significant events: first participant joined, first solve, scoreboard freeze (if applied), challenge releases (if challenges were released progressively), and event end.

difficulty_retrospective β€” Calibration Analysis

[!TIP] The difficulty retrospective is the most actionable section for organizers improving future events.

This section compares the configured difficulty of each challenge against its observed difficulty (derived from solve rate and median solve time). Mismatches indicate calibration drift between the AI-generated difficulty label and actual player behavior.

{
  "web-001": {
    "configured_difficulty": "medium",
    "observed_difficulty": "easy",
    "solve_rate": 0.87,
    "median_solve_time_seconds": 420,
    "calibration_verdict": "easier_than_labeled"
  }
}

Possible calibration verdicts:

Verdict Meaning
well_calibrated Solve rate and time match the expected range for the difficulty label
easier_than_labeled Challenge was solved by significantly more participants or faster than expected
harder_than_labeled Challenge was solved by significantly fewer participants or slower than expected
unsolved No participant solved the challenge during the event

Use the difficulty retrospective to adjust point values for re-used challenges, refine your generation prompts, or select different challenge specs in future events.

Exporting the Report

From the UI, the report can be exported as:

  • JSON β€” the full machine-readable document
  • CSV β€” participant rankings and per-challenge solve counts in tabular form
  • PDF β€” a formatted summary suitable for sharing with stakeholders

The JSON export is identical to the API response and can be ingested by external BI tools, LMS platforms, or custom dashboards.

[!WARNING] Post-event reports contain participant names, email addresses (for workspace members), and solve timestamps. Handle exported reports in accordance with your organization's data retention and privacy policies.

Webhook Delivery

If your workspace has a webhook configured for the event.report.ready event type, CTFFactory delivers the full JSON report to your endpoint automatically when the report is compiled. This eliminates the need to poll the API.

{
  "event_type": "event.report.ready",
  "event_id": "evt_abc123",
  "report_url": "https://api.ctffactory.io/v1/events/evt_abc123/report",
  "generated_at": "2025-06-15T19:05:00Z"
}

See the Webhooks documentation for payload signing and retry behavior.

πŸ‡¨πŸ‡¦ Data hosted in Canada Β· Β© 2026 ExamBoot Β· Terms Β· Privacy