Skip to main content

Documentation 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.

FlagForge supports two types of badges: system badges earned automatically by hitting solve milestones, and custom badges assigned manually by admins. The badges API lets you retrieve profile badges as embeddable images and — for admins — manage badge templates and assignments.

GET /api/badge/[username]/svg

Generate and return a player’s profile badge as an SVG image. No authentication is required. The badge displays the player’s name, level, rank, score, solved challenge count, and avatar. Badge color is determined by the player’s total score.

Path parameters

username
string
required
The player’s display name. Hyphens are treated as spaces during the lookup.

Response

Returns an image/svg+xml response. The image is cached for 5 minutes (Cache-Control: public, max-age=300).

Badge color thresholds

ScoreColor
3000+Yellow (#EAB308) — Flag Conqueror
2000 – 2999Red (#DC2626) — Forger
1500 – 1999Orange (#EA580C) — Cipher Hunter
1000 – 1499Purple (#7C3AED) — Hacker
500 – 999Green (#059669) — Codebreaker
200 – 499Blue (#2563EB) — Scout
0 – 199Gray (#6B7280) — Newbie

Example

curl "https://flagforgectf.com/api/badge/alice/svg" \
  --output alice-badge.svg
You can embed the badge directly in a GitHub README or any HTML page:
<img src="https://flagforgectf.com/api/badge/alice/svg" alt="alice's FlagForge badge" />

GET /api/badge/[username]/png

Identical to the SVG endpoint but returns a image/svg+xml response rendered as a PNG-compatible SVG. Use this endpoint in contexts where SVG embedding is not supported.

Path parameters

username
string
required
The player’s display name.

Example

curl "https://flagforgectf.com/api/badge/alice/png" \
  --output alice-badge.png

POST /api/admin/assign-badge

Assign a badge to a user. Requires the Admin role. The badge is recorded as an AssignedBadge document and added to the user’s customBadges array so it appears on their profile immediately.
This endpoint requires an Admin session. Non-admin requests return 401 Unauthorized or 403 Forbidden.

Request body

The endpoint accepts two formats. You can send the badge fields directly at the top level, or nest them under a badge object. Direct format:
userId
string
required
The MongoDB _id of the user receiving the badge.
badgeId
string
required
A string identifier for the badge. For template badges, this is typically the badge name.
badgeType
string
default:"template"
Badge type: template for a predefined badge, or custom for a badge image uploaded via the badge images endpoint.
assignedBy
string
default:"system"
The name or email of the admin performing the assignment.
reason
string
Optional reason for the assignment, stored on the badge record.
Nested format (used by the admin UI):
userId
string
required
The MongoDB _id of the user receiving the badge.
badge
object
required
Badge details nested under a badge key.

Response fields

Success (201 Created):
success
boolean
true
message
string
Confirmation message, e.g. "Badge \"CTF Champion\" assigned successfully".
assignmentId
string
MongoDB _id of the new AssignedBadge document.
badge
object
Summary of the assigned badge: id, name, and type.

Error responses

StatusCondition
400 Bad RequestMissing or invalid userId or badgeId.
401 UnauthorizedNot signed in.
403 ForbiddenSigned in but not an Admin.
409 ConflictThe badge is already assigned to this user.

Example

curl -X POST "https://flagforgectf.com/api/admin/assign-badge" \
  -H "Content-Type: application/json" \
  -H "Cookie: next-auth.session-token=<admin-session>" \
  -d '{
    "userId": "665a1f2e3c4b5d6e7f8a9b0c",
    "badgeId": "CTF Champion",
    "assignedBy": "admin@example.com",
    "reason": "Winner of Spring 2024 event"
  }'
{
  "success": true,
  "message": "Badge \"CTF Champion\" assigned successfully",
  "assignmentId": "6660abc123def456789abc12",
  "badge": {
    "id": "CTF Champion",
    "name": "CTF Champion",
    "type": "template"
  }
}

GET /api/admin/assign-badge

List badge assignments. Requires the Admin role. Returns all active assignments, or those for a specific user when userId is provided.

Query parameters

userId
string
Filter assignments to a specific user by their MongoDB _id. Omit to return all active assignments.

Response fields

success
boolean
true on success.
assignments
object[]
Array of active badge assignment records.
count
number
Total number of assignments returned.

Example

curl "https://flagforgectf.com/api/admin/assign-badge?userId=665a1f2e3c4b5d6e7f8a9b0c" \
  -H "Cookie: next-auth.session-token=<admin-session>"
{
  "success": true,
  "assignments": [
    {
      "_id": "6660abc123def456789abc12",
      "userId": "665a1f2e3c4b5d6e7f8a9b0c",
      "badgeId": "CTF Champion",
      "badgeName": "CTF Champion",
      "badgeDescription": "Winner of the Spring 2024 event",
      "badgeIcon": "trophy",
      "badgeColor": "#EAB308",
      "assignedBy": "admin@example.com",
      "reason": "Winner of Spring 2024 event",
      "isActive": true,
      "assignedAt": "2024-05-01T12:00:00.000Z"
    }
  ],
  "count": 1
}

DELETE /api/admin/assign-badge

Remove a badge assignment. The assignment is soft-deleted (marked isActive: false) and the badge is removed from the user’s customBadges array. Requires the Admin role.

Query parameters

id
string
The _id of the AssignedBadge document to remove.
userId
string
The user’s _id. Required when id is not provided.
badgeId
string
The badge identifier. Required when id is not provided.
Provide either id alone, or both userId and badgeId together. The request returns 400 Bad Request if neither combination is supplied.

Example

curl -X DELETE \
  "https://flagforgectf.com/api/admin/assign-badge?id=6660abc123def456789abc12" \
  -H "Cookie: next-auth.session-token=<admin-session>"
{
  "success": true,
  "message": "Badge assignment removed successfully"
}

Build docs developers (and LLMs) love