The challenges API gives you programmatic access to every CTF problem on the platform. You can browse challenges with pagination and category filtering, retrieve a single challenge by its ID, and — if your account has theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/flagForgeCTF/flagForge/llms.txt
Use this file to discover all available pages before exploring further.
Admin role — create new challenges. The flag field is never returned by any read endpoint, keeping challenge answers safe.
GET /api/problems
List challenges. No authentication is required. Results are sorted newest-first and paginated.Query parameters
The page number to retrieve. Starts at
1.Number of challenges per page. Maximum value is
1000. Pass a large value (e.g. 1000) to retrieve all challenges in a single request.Filter by challenge category. Pass
All or omit this parameter to return challenges from all categories. Pass a specific category name (e.g. Web, Crypto) to filter results.Response fields
Array of challenge objects. The
flag field is excluded from all objects in this array.The authenticated user’s current total score. Returns
0 when the request is made without a session.Array of
UserQuestion records representing challenges the authenticated user has already solved. Returns an empty array when the request is made without a session.Pagination metadata for the current result set.
Example
GET /api/problems/[id]
Retrieve a single challenge by its MongoDB ID. No authentication is required, but the response includes user-specific fields (isDone, usedHints) when a valid session cookie is present.
Path parameters
The MongoDB
_id of the challenge.Response fields
The challenge object. The
flag and hints fields are stripped from this object — use the hint count in hintCount and the hints endpoint for hint text.Number of hints available for this challenge. Only hints with non-empty text are counted.
true if the authenticated user has already solved this challenge. Always false when the request is unauthenticated.true if the challenge’s expiryDate is in the past.Milliseconds remaining until
expiryDate. null if there is no expiry date.ISO 8601 expiry date, or
null if the challenge does not expire.Array of hint indices the authenticated user has already unlocked. Empty array when unauthenticated.
Error responses
| Status | Condition |
|---|---|
404 Not Found | No challenge exists with the given id. |
410 Gone | The challenge existed but has expired. |
Example
POST /api/problems
Create a new challenge. Requires theAdmin role.
The endpoint accepts two content types depending on whether the challenge has a file attachment:
application/json— for link-based challenges where the resource lives at an external URL.multipart/form-data— for file-based challenges where you upload a challenge file directly.
Request fields (JSON or form-data)
Display title of the challenge.
Full challenge description shown to participants.
Challenge category, for example
Web, Crypto, or Pwn.Point value awarded to the first solver (before any hint penalties).
The correct flag string. This value is stored securely and never returned by the API.
URL to the external challenge resource. Used for link-type challenges.
Optional supplementary links for participants (e.g. reference materials).
JSON-encoded array of hint objects. Each hint object should include
text, content, description, and pointsDeduction fields.Set to
true to give the challenge an expiry date.Duration of the time limit in
timeLimitUnit units.One of
hours, days, or weeks.An explicit expiry date in ISO 8601 format. Overrides the
timeLimit / timeLimitUnit calculation when provided.The file to upload. Only accepted when
Content-Type is multipart/form-data. Allowed types: ZIP, PDF, TXT, PNG, JPG. Maximum size: 50 MB.Response fields
true on success.Human-readable confirmation message, for example
"Your question has been created".Examples
Create a link-based challenge (JSON):GET /api/categories
Return all challenge categories currently in use on the platform. No authentication is required.Response fields
Sorted list of distinct category names. Always includes
"All" as the first entry.Example
Categories are derived dynamically from the challenges in the database. A category only appears after at least one challenge has been created with that category label.