Challenges Endpoints¶
CTFd Version: 3.7.1
Last Updated: 8/6/2024
Endpoints¶
GET /challengesPOST /challengesPOST /challenges/attemptGET /challenges/typesGET /challenges/{challenge_id}PATCH /challenges/{challenge_id}DELETE /challenges/{challenge_id}GET /challenges/{challenge_id}/filesGET /challenges/{challenge_id}/flagsGET /challenges/{challenge_id}/hintsGET /challenges/{challenge_id}/requirementsGET /challenges/{challenge_id}/solvesGET /challenges/{challenge_id}/tagsGET /challenges/{challenge_id}/topics
GET /challenges¶
Info
This endpoint only returns challenges that are visible to the user by default. To get all challenges, set the view query parameter to "admin".
Warning
The data returned by this endpoint only contains a part of each challenge's details. To get the full details of a challenge, use the GET /challenges/{challenge_id} endpoint.
Endpoint to get challenges in bulk. Can be filtered by name, max_attempts, value, category, type and state.
Query Parameters¶
| Name | Type | Description |
|---|---|---|
name |
string |
The name of the challenge to get challenges for |
max_attempts |
int |
The maximum number of attempts for the challenge to get challenges for |
value |
int |
The value of the challenge to get challenges for |
category |
string |
The category of the challenge to get challenges for |
type |
string |
The type of the challenge to get challenges for |
state |
string |
The state of the challenge to get challenges for. Possible values are "visible", "hidden", and "locked" |
q |
string |
A search query to match against the given field. If this is specified, field must also be specified |
field |
string |
The field to search against, can be either name, description, category, type or state. If this is specified, q must also be specified |
view |
string |
The view of the challenges to output. If set to "admin", it will show all challenges including hidden and locked challenges. |
Response¶
-
200 OK- The challenges were successfully retrievedlist[ChallengePreview]{ "success": true, "data": [ { "id": 1, "type": "string", "name": "string", "value": 1, "solves": 1, "solved_by_me": true, "category": "string", "tags": [ "string" ], "template": "string", "script": "string" } ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
category |
string |
The category of the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
template |
string |
The template of the challenge. Used internally by the frontend |
script |
string |
The script of the challenge. Used internally by the frontend |
POST /challenges¶
This endpoint is only accessible to admins.
Endpoint to create a new challenge. Accepts either form data or JSON data.
JSON / Multipart Form Parameters¶
| Name | Type | Description |
|---|---|---|
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
Literal["standard"] |
The type of the challenge. Has to be "standard" for standard challenges |
| Name | Type | Description |
|---|---|---|
name |
string |
The name of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
Literal["dynamic"] |
The type of the challenge. Has to be "dynamic" for dynamic challenges |
Response¶
-
200 OK- The hint was created successfully{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "standard", "type_data": { "id": "standard", "name": "standard", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } } } }{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "initial": 1, "decay": 1, "minimum": 1, "function": "string", "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "dynamic", "type_data": { "id": "dynamic", "name": "dynamic", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } } } } -
400 Bad Request- An error occurred processing the provided or stored dataapplication/json{ "success": false, "errors": [ "string" ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
POST /challenges/attempt¶
Endpoint to send a challenge attempt.
JSON / Multipart Form Parameters¶
| Name | Type | Description |
|---|---|---|
challenge_id |
int |
The ID of the challenge to attempt |
submission |
string |
The submission for the challenge |
Response¶
Refer to ChallengeAttemptResult for possible responses
Warning
Even when the response code is 200 OK, the success field might be False if the attempt was not successful. Additionally, the success field does not mean that the attempt was correct. The only way to tell that the attempt is correct is when the status field is "correct".
200 OK- The attempt was successful-
{ "success": true, // (1)! "data": { "status": "string", "message": "string" } }- This may not always be
True.
- This may not always be
-
Return Values¶
| Name | Type | Description |
|---|---|---|
status |
string |
The status of the attempt |
message |
string |
The message from the attempt |
Refer to ChallengeAttemptResult for possible responses.
GET /challenges/types¶
This endpoint is only accessible to admins.
Endpoint to get the available challenge types.
Response¶
200 OK- The challenge types were successfully retrievedlist[ChallengeType]{ "success": true, "data": [ { "id": "string", "name": "string", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" }, "create": "string" } ] }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
string |
The ID of the challenge type |
name |
string |
The name of the challenge type |
templates |
dict[str, str] |
A dictionary of templates for creating, updating, and viewing challenges of this type |
scripts |
dict[str, str] |
A dictionary of scripts for creating, updating, and viewing challenges of this type |
create |
string |
The tempate for creating challenges of this type |
GET /challenges/{challenge_id}¶
Endpoint to get a challenge by ID.
Response¶
-
200 OK- The challenge was successfully retrieved{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "standard", "type_data": { "id": "standard", "name": "standard", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } }, "solves": 1, "solved_by_me": true, "attempts": 1, "files": [ "string" ], "tags": [ "string" ], "hints": [{ }], "view": "string" } }{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "initial": 1, "decay": 1, "minimum": 1, "function": "string", "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "dynamic", "type_data": { "id": "dynamic", "name": "dynamic", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } }, "solves": 1, "solved_by_me": true, "attempts": 1, "files": [ "string" ], "tags": [ "string" ], "hints": [{ }], "view": "string" } } -
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
-
500 Internal Server Error- The underlying challenge type is not installedapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
attempts |
int |
The number of attempts for the challenge |
files |
list[str] |
A list of files associated with the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
hints |
list[ LockedChallengeHint|UnlockedChallengeHint] |
A list of hints associated with the challenge |
As of CTFd 3.7.0, the function field is not returned by the API.
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
attempts |
int |
The number of attempts for the challenge |
files |
list[str] |
A list of files associated with the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
hints |
list[ LockedChallengeHint|UnlockedChallengeHint] |
A list of hints associated with the challenge |
PATCH /challenges/{challenge_id}¶
This endpoint is only accessible to admins.
Endpoint to update a challenge by ID.
JSON Parameters¶
Warning
The "locked" challenge state is not documented. Setting challenges to "locked" is not recommended.
| Name | Type | Description |
|---|---|---|
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
| Name | Type | Description |
|---|---|---|
name |
string |
The name of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
Response¶
-
200 OK- The challenge was successfully retrieved{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "standard", "type_data": { "id": "standard", "name": "standard", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } } } }{ "success": true, "data": { "id": 1, "name": "string", "value": 1, "initial": 1, "decay": 1, "minimum": 1, "function": "string", "description": "string", "connection_info": "string", "next_id": 1, "category": "string", "state": "string", "max_attempts": 1, "type": "dynamic", "type_data": { "id": "dynamic", "name": "dynamic", "templates": { "create": "string", "update": "string", "view": "string" }, "scripts": { "create": "string", "update": "string", "view": "string" } } } } -
400 Bad Request- An error occurred processing the provided or stored dataapplication/json{ "success": false, "errors": [ "string" ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
DELETE /challenges/{challenge_id}¶
This endpoint is only accessible to admins.
Endpoint to delete a challenge by ID.
Response¶
-
200 OK- The challenge was successfully deletedapplication/json{ "success": true }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
None
GET /challenges/{challenge_id}/files¶
This endpoint is only accessible to admins.
Endpoint to get the files associated with a challenge by ID.
Response¶
-
200 OK- The files were successfully retrievedlist[ChallengeFileResponse]{ "success": true, "data": [ { "id": 1, "type": "challenge", "location": "string" } ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the file |
type |
string |
The type of the file, can only be "challenge" |
location |
string |
The location of the file |
GET /challenges/{challenge_id}/flags¶
This endpoint is only accessible to admins.
Endpoint to get the flags associated with a challenge by ID.
Response¶
-
200 OK- The flags were successfully retrievedlist[Flag]{ "success": true, "data": [ { "id": 1, "challenge_id": 1, "type": "string", "content": "string", "data": "string" } ] }
-
400 Bad Request- An error occurred processing the provided or stored dataapplication/json{ "success": false, "errors": [ "string" ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the flag |
challenge_id |
int |
The ID of the challenge the flag is for |
type |
string |
The type of the flag, can be either "static" or "regex" |
content |
string |
The content of the flag |
data |
string |
The data of the flag, seems to only be used for the flag's case-insensitivity, can be either "case_insensitive" or "" |
GET /challenges/{challenge_id}/hints¶
This endpoint is only accessible to admins.
Endpoint to get the hints associated with a challenge by ID.
Response¶
-
200 OK- The hints were successfully retrievedlist[Hint]{ "success": true, "data": [ { "id": 1, "type": "string", "challenge": 1, "challenge_id": 1, "content": "string", "html": "string", "cost": 1, "requirements": { "prerequisites": [ 1 ] } } ] }
-
400 Bad Request- An error occurred processing the provided or stored dataapplication/json{ "success": false, "errors": [ "string" ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the hint |
type |
string |
The type of the hint, seems to always be "standard" |
challenge |
int |
The ID of the challenge the hint is for (I'm not sure why this field exists) |
challenge_id |
int |
The ID of the challenge the hint is for |
content |
string |
The content of the hint |
html |
string |
The HTML content of the hint |
cost |
int |
The cost of the hint |
requirements |
dict |
The hint's requirements. This dictionary has a single item, prerequisites, which is a list of hint IDs required to unlock before this one. (Optional) |
GET /challenges/{challenge_id}/requirements¶
This endpoint is only accessible to admins.
Endpoint to get the requirements associated with a challenge by ID.
Response¶
-
200 OK- The requirements were successfully retrievedChallengeRequirements{ "success": true, "data": { "prerequisites": [ 1 ], "anonymize": false } }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
prerequisites |
list[int] |
A list of prerequisite challenge IDs |
anonymize |
bool |
Whether or not to anonymize the challenge |
GET /challenges/{challenge_id}/solves¶
Endpoint to get the solves associated with a challenge by ID.
Query Parameters¶
| Name | Type | Description |
| preview | bool | If the CTF is currently frozen, the user is an admin, and this is set to True, the response will only contain the solves prior to the freeze time. |
Response¶
-
200 OK- The solves were successfully retrievedlist[ChallengeSolvesResponse]{ "success": true, "data": [ { "account_id": 1, "name": "string", "date": "string", "account_url": "string" } ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
account_id |
int |
The ID of the account that solved the challenge |
name |
string |
The name of the account that solved the challenge |
date |
string |
The date the challenge was solved |
account_url |
string |
The URL of the account that solved the challenge |
GET /challenges/{challenge_id}/tags¶
This endpoint is only accessible to admins.
Endpoint to get the tags associated with a challenge by ID.
Response¶
-
200 OK- The tags were successfully retrievedlist[Tag]{ "success": true, "data": [ { "id": 1, "challenge_id": 1, "value": "string" } ] }`
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the tag |
challenge_id |
int |
The ID of the challenge |
value |
string |
The value of the tag |
GET /challenges/{challenge_id}/topics¶
This endpoint is only accessible to admins.
Endpoint to get the topics associated with a challenge by ID.
Response¶
-
200 OK- The topics were successfully retrievedlist[ChallengeTopicResponse]{ "success": true, "data": [ { "id": 1, "challenge_id": 1, "topic_id": 1, "value": "string" } ] }
-
403 Forbidden- You are not allowed to access this endpointapplication/json{ "message": "string" }
-
404 Not Found- The challenge was not foundapplication/json{ "message": "string" }
Return Values¶
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge-topic association |
challenge_id |
int |
The ID of the challenge |
topic_id |
int |
The ID of the topic |
value |
string |
The value of the topic |
Models¶
ChallengeModelDynamicChallengeModelChallengePreviewModelHiddenChallengeModelPartialChallengeModelPartialDynamicChallengeModelLockedChallengeHintModelUnlockedChallengeHintModelChallengeAttemptResultModelChallengeTypeModelChallengeFileResponseModelChallengeRequirementsModelChallengeSolvesResponseModelChallengeTopicResponseModel
Challenge Model¶
Represents a challenge returned by the GET /challenges/{challenge_id} endpoint.
{
"id": 1,
"name": "string",
"value": 1,
"description": "string",
"connection_info": "string",
"next_id": 1,
"category": "string",
"state": "string",
"max_attempts": 1,
"type": "standard",
"type_data": {
"id": "standard",
"name": "standard",
"templates": {
"create": "string",
"update": "string",
"view": "string"
},
"scripts": {
"create": "string",
"update": "string",
"view": "string"
}
},
"solves": 1,
"solved_by_me": true,
"attempts": 1,
"files": [
"string"
],
"tags": [
"string"
],
"hints": [{ }],
"view": "string"
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
attempts |
int |
The number of attempts the current user has made on the challenge |
files |
list[str] |
A list of files associated with the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
hints |
list[ LockedChallengeHint|UnlockedChallengeHint] |
A list of hints associated with the challenge |
view |
string |
The view of the challenge. Used internally by the frontend |
DynamicChallenge Model¶
Represents a dynamic challenge returned by the GET /challenges/{challenge_id} endpoint.
{
"id": 1,
"name": "string",
"value": 1, // (1)!
"initial": 1,
"decay": 1,
"minimum": 1,
"function": "string",
"description": "string",
"connection_info": "string",
"next_id": 1,
"category": "string",
"state": "string",
"max_attempts": 1,
"type": "dynamic",
"type_data": {
"id": "dynamic",
"name": "dynamic",
"templates": {
"create": "string",
"update": "string",
"view": "string"
},
"scripts": {
"create": "string",
"update": "string",
"view": "string"
}
},
"solves": 1,
"solved_by_me": true,
"attempts": 1,
"files": [
"string"
],
"tags": [
"string"
],
"hints": [{ }],
"view": "string"
}
- The
valuefield is read-only and represents the current value of the challenge. This value is calculated based on theinitial,decay, andminimumfields.
As of CTFd versions 3.7.0 and below do not return the function field. This is fixed in 3.7.1
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge. This is read-only for dynamic challenges |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
Literal["dynamic"] |
The type of the challenge. Has to be "dynamic" for dynamic challenges |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
attempts |
int |
The number of attempts the current user has made on the challenge |
files |
list[str] |
A list of files associated with the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
hints |
list[ LockedChallengeHint|UnlockedChallengeHint] |
A list of hints associated with the challenge |
view |
string |
The view of the challenge. Used internally by the frontend |
ChallengePreview Model¶
Represents a preview of a challenge. This model is returned by GET /challenges.
{
"id": 1,
"type": "string",
"name": "string",
"value": 1,
"solves": 1,
"solved_by_me": true,
"category": "string",
"tags": [
"string"
],
"template": "string",
"script": "string"
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
solves |
int |
The number of solves for the challenge |
solved_by_me |
bool |
Whether or not the current user has solved the challenge |
category |
string |
The category of the challenge |
tags |
list[str] |
A list of tags associated with the challenge |
template |
string |
The template of the challenge. Used internally by the frontend |
script |
string |
The script of the challenge. Used internally by the frontend |
HiddenChallenge Model¶
Represents a challenge with details hidden from the user. This is used for challenges with requirements not yet fulfilled by the user.
Warning
This model is a hard-coded response and should not be confused with a Challenge that has state set to "hidden".
{
"id": 1,
"type": "hidden",
"name": "???",
"value": 0,
"solves": null,
"solved_by_me": false,
"category": "???",
"tags": [],
"template": "",
"script": ""
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
type |
string |
The type of the challenge. Will always be "hidden" |
name |
string |
The name of the challenge. Will always be "???" |
value |
int |
The value of the challenge. Will always be 0 |
solves |
int |
The number of solves for the challenge. Will always be None |
solved_by_me |
bool |
Whether or not the current user has solved the challenge. Will always be False |
category |
string |
The category of the challenge. Will always be "???" |
tags |
list[str] |
A list of tags associated with the challenge. Will always be [] |
template |
string |
The template of the challenge. Will always be "" |
script |
string |
The script of the challenge. Will always be "" |
PartialChallenge Model¶
Represents a partial challenge returned by the POST /challenges and PATCH /challenges/{challenge_id} endpoint.
{
"id": 1,
"name": "string",
"value": 1,
"description": "string",
"connection_info": "string",
"next_id": 1,
"category": "string",
"state": "string",
"max_attempts": 1,
"type": "standard",
"type_data": {
"id": "standard",
"name": "standard",
"templates": {
"create": "string",
"update": "string",
"view": "string"
},
"scripts": {
"create": "string",
"update": "string",
"view": "string"
}
}
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
PartialDynamicChallenge Model¶
Represents a partial dynamic challenge returned by the POST /challenges and PATCH /challenges/{challenge_id} endpoint.
{
"id": 1,
"name": "string",
"value": 1,
"initial": 1,
"decay": 1,
"minimum": 1,
"function": "string",
"description": "string",
"connection_info": "string",
"next_id": 1,
"category": "string",
"state": "string",
"max_attempts": 1,
"type": "dynamic",
"type_data": {
"id": "dynamic",
"name": "dynamic",
"templates": {
"create": "string",
"update": "string",
"view": "string"
},
"scripts": {
"create": "string",
"update": "string",
"view": "string"
}
}
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge |
name |
string |
The name of the challenge |
value |
int |
The value of the challenge |
initial |
int |
The initial value of the challenge |
decay |
int |
The decay rate of the challenge |
minimum |
int |
The minimum value of the challenge |
function |
string |
The function used to calculate the value of the challenge. Possible values are "logarithmic" and "linear" |
description |
string |
The description of the challenge |
connection_info |
string |
The connection information of the challenge |
next_id |
int |
The ID of the next challenge |
category |
string |
The category of the challenge |
state |
string |
The state of the challenge. Possible values are "visible", "hidden", and "locked" |
max_attempts |
int |
The maximum number of attempts for the challenge |
type |
string |
The type of the challenge. Possible values are "standard" and "dynamic" |
type_data |
dict[str, Any] |
The data associated with the challenge type. Used internally by the frontend |
ChallengeRequirements Model¶
Represents the requirements before a challenge can be accessed by a user.
{
"prerequisites": [
1
],
"anonymize": false
}
| Name | Type | Description |
|---|---|---|
prerequisites |
list[int] |
A list of challenge IDs that must be solved before this challenge can be accessed |
anonymize |
bool |
Whether or not to anonymize the challenge instead of hiding it if the prerequisites are not met. If not specified, defaults to False |
LockedChallengeHint Model¶
Represents a hint that is locked for the current user.
{
"id": 1,
"cost": 1
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the hint |
cost |
int |
The cost of the hint |
UnlockedChallengeHint Model¶
Represents a hint that is unlocked for the current user.
{
"id": 1,
"cost": 1,
"content": "string"
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the hint |
cost |
int |
The cost of the hint |
content |
string |
The content of the hint |
ChallengeAttemptResult Model¶
Represents the response from sending a challenge attempt.
{
"status": "string",
"message": "string" // (1)!
}
- The message sometimes might be
null
| Name | Type | Description |
|---|---|---|
status |
string |
The status of the attempt |
message |
string |
The message from the attempt |
Challenge Attempt Statuses
| Status | Description | Status Code |
|---|---|---|
correct |
The attempt was correct | 200 |
incorrect |
The attempt was incorrect or you have 0 tries left for this challenge | 200 / 403 |
authentication_required |
The user must log in to send an attempt | 403 |
paused |
The CTF is paused | 403 |
ratelimited |
The user is submitting attempts too quickly | 429 |
already_solved |
The challenge has already been solved by the user or the user's team | 200 |
ChallengeType Model¶
Represents a challenge type.
{
"id": "string",
"name": "string",
"templates": {
"create": "string",
"update": "string",
"view": "string"
},
"scripts": {
"create": "string",
"update": "string",
"view": "string"
},
"create": "string"
}
| Name | Type | Description |
|---|---|---|
id |
string |
The ID of the challenge type |
name |
string |
The name of the challenge type |
templates |
dict[str, str] |
A dictionary of templates for creating, updating, and viewing challenges of this type |
scripts |
dict[str, str] |
A dictionary of scripts for creating, updating, and viewing challenges of this type |
create |
string |
The tempate for creating challenges of this type |
ChallengeFileResponse Model¶
Represents a file associated with a challenge.
{
"id": 1,
"type": "challenge",
"location": "string"
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the file |
type |
Literal["challenge"] |
The type of the file. Will always be "challenge" |
location |
string |
The location of the file |
ChallengeSolvesResponse Model¶
Represents a solve for a challenge
{
"account_id": 1,
"name": "string",
"date": "string",
"account_url": "string"
}
| Name | Type | Description |
|---|---|---|
account_id |
int |
The ID of the account that solved the challenge |
name |
string |
The name of the account that solved the challenge |
date |
string |
The date the challenge was solved |
account_url |
string |
The URL of the account that solved the challenge |
ChallengeTopicResponse Model¶
Represents a topic associated with a challenge.
{
"id": 1,
"challenge_id": 1,
"topic_id": 1,
"value": "string"
}
| Name | Type | Description |
|---|---|---|
id |
int |
The ID of the challenge-topic association |
challenge_id |
int |
The ID of the challenge |
topic_id |
int |
The ID of the topic |
value |
string |
The value of the topic |