Responses

Reference for rCTF responses, common errors, and shared API objects.

Edit this page View Markdown

The @rctf/types package defines each response’s kind, HTTP status, message, and optional data. Individual endpoint pages list their relevant responses. This page collects the shared definitions.

Response format

Most responses contain kind, message, and optional data fields:

{
"kind": "goodUserSelfData",
"message": "The user's own data was successfully retrieved.",
"data": {}
}

Responses with no additional data omit data:

{
"kind": "goodToken",
"message": "The authorization token is valid."
}

Unknown API routes usually return 404 badEndpoint. Unexpected server errors return 500 errorInternal.

Common errors

Response Data Meaning
400 badJson No data The request body was not valid JSON.
400 badBody { reason: string } Validation did not pass for body, query, path parameters, or form data.
401 badToken No data The auth token was missing or could not be used.
403 badPerms No data The authenticated team does not have the permission bits for this route.
404 badEndpoint No data The route is not available, or the provider behind the route is not configured.
401 badNotStarted No data The CTF has not started yet for this request.
401 badEnded No data The CTF has ended for this action.
403 badCaptcha No data V2 captcha validation did not pass.
401 badRecaptchaCode No data V1 captcha validation did not pass.
429 badRateLimit { timeLeft: number } This rate limit needs more time before another request.
500 errorInternal No data The server hit an unexpected error.

Auth and account errors

Response Data Meaning
400 badEmail No data The email did not pass validation.
400 badName No data The team name did not pass validation.
409 badKnownEmail No data Another account already uses this email.
409 badKnownName No data Another account already uses this team name.
409 badKnownCtftimeId No data Another account already uses this CTFtime ID.
404 badUnknownEmail No data No account is associated with this email.
404 badUnknownUser No data No user exists for that ID.
401 badTokenVerification No data The verify, team, or CTFtime auth token could not be verified.
401 badCtftimeToken No data The CTFtime auth token could not be used.
401 badCtftimeCode No data The CTFtime OAuth code could not be used.
404 badCtftimeNoExists No data The current user does not have a linked CTFtime team.
404 badEmailNoExists No data The current user does not have an email address.
403 badEmailChangeDivision No data The new email would move the account outside its current division rules.
403 badDivisionNotAllowed No data The account is not allowed to use the requested division.
403 badCompetitionNotAllowed No data Registration rules do not allow this account.
400 badRegistrationsDisabled No data Registrations are currently disabled.
409 badTooManyMembers No data The team is already at maxMembers.
409 badZeroAuth No data The change would remove the final auth method from the account.
403 badUserPrivileged No data The target user has admin permissions, so this route does not modify it.

Challenge and integration errors

Response Data Meaning
404 badChallenge No data The challenge was not found or is not available to this route.
400 badFlag No data The submitted flag was not accepted.
409 badAlreadySolvedChallenge No data The team has already solved this challenge.
404 badUnknownSolveV2 No data The solve row was not found.
400 badDataUri No data The V1 upload data URI could not be read.
500 badFilesUpload No data The upload provider could not finish the upload.
400 badAvatarFile No data The avatar file was not accepted as an image.
400 badAvatarFileSize { maxSize: number } The avatar is larger than maxAvatarSize.
400 badModerationNotPassed No data Avatar moderation did not approve the image.
400 badInstancerConfig { error: string } The instancer provider did not accept the challenge config.
400 badInstancerError { message: string } The instancer could not create, read, extend, or stop the instance.
400 badInstancerState { error: string } The admin bot route needs a running instance, but one was not available.
400 badAdminBotConfig { error: string } The admin bot provider did not accept the challenge source.
404 badUnknownVerification No data The pending user verification was not found.
401 badSignature No data The dynamic-scoring webhook signature, timestamp, or challenge target was rejected. The endpoint deliberately doesn’t distinguish causes.
400 badExternalAuthRequest No data An external-auth call was rejected. The same response is used for unknown client, wrong secret, wrong/expired/reused code, and mismatched redirect URI so the endpoint can’t be probed.

Success response data

Response Data
200 goodRegister { authToken: string }
200 goodRegisterV2 { authToken: string, teamToken: string }
200 goodLogin { authToken: string }
200 goodVerify { authToken: string }
200 goodVerifyInfo { kind: "register" | "team" | "update", email: string | null, name?: string }
200 goodToken No data.
200 goodVerifySent No data.
200 goodEmailSet No data.
200 goodEmailRemoved No data.
200 goodCtftimeAuthSet No data.
200 goodCtftimeRemoved No data.
200 goodCtftimeToken { ctftimeToken: string, ctftimeName: string, ctftimeId: string }
200 goodChallenges 200 goodChallengesV2 Challenge array. Fields depend on API version.
200 goodChallengeSolves 200 goodChallengeSolvesV2 Solve list. Fields depend on API version.
200 goodFlag No data.
200 goodLeaderboard 200 goodLeaderboardV2 { total: number, leaderboard: LeaderboardEntry[] }. Entry fields depend on API version.
200 goodLeaderboardWithGraph { total: number, leaderboard: LeaderboardEntryV2[], graph: LeaderboardGraphEntry[] }
200 goodLeaderboardGraph { graph: LeaderboardGraphEntry[] }
200 goodLeaderboardChallengesV2 { challenges: Record<string, LeaderboardChallenge> }
200 goodUserData 200 goodUserDataV2 Public user profile. Fields depend on API version.
200 goodUserSelfData 200 goodUserSelfDataV2 Authenticated user’s own profile. Fields depend on API version.
200 goodUserUpdate 200 goodUserUpdateV2 { user: UserUpdateResult }
200 goodAvatarUpdated { url: string | null }
200 goodMemberData Team member array.
200 goodMemberCreate Team member object.
200 goodMemberDelete No data.
200 goodAdminChallenges 200 goodAdminChallengesV2 Admin challenge array. Fields depend on API version.
200 goodAdminChallenge 200 goodAdminChallengeV2 Admin challenge object. Fields depend on API version.
200 goodChallengeUpdate 200 goodChallengeUpdateV2 Updated admin challenge object.
200 goodChallengeDelete No data.
200 goodChallengeSolveDeleteV2 No data.
200 goodFilesUpload 200 goodFilesUploadV2 Uploaded file array. Fields depend on API version.
200 goodUploadsQuery 200 goodUploadsQueryV2 Upload query result array. Fields depend on API version.
200 goodAdminUsersV2 { total: number, users: AdminUserListItem[] }
200 goodAdminUserV2 Admin user detail with solves.
200 goodAdminUserUpdateV2 No data.
200 goodAdminUserDeleteV2 No data.
200 goodCreateUserTokenV2 { token: string }
200 goodAdminUserVerificationsV2 { verifications: PendingUserVerification[] }
200 goodAdminUserVerificationCompleteV2 { userId: string }
200 goodAdminUserVerificationResendV2 { id: string }
200 goodAdminSubmissions { total: number, submissions: AdminSubmission[] }
200 goodAdminSettings { overrides: AdminSettings, defaults: AdminSettings }
200 goodAdminSettingsUpdate { overrides: AdminSettings, defaults: AdminSettings }
200 goodClientConfig 200 goodClientConfigV2 Client config object. Fields depend on API version.
200 goodCtftimeLeaderboard { standings: { pos: number, team: string, score: number }[] }
200 goodInstanceStatus { status: InstanceStatus, timeLeftMilliseconds: number | null, endpoints: Endpoint[] | null }
200 goodInstancerSchema { schema: Record<string, unknown>, defaults: Record<string, unknown> }
200 goodAdminBotConfig { sourceCode: string, fileExtension: string }
200 goodAdminBotStatus { enabled: boolean, configLanguage: string }
200 goodAdminBotJobSubmitted { jobId: string }
200 goodAdminBotJobStatus { job: AdminBotJobStatusResponse | null }
200 goodAdminBotJobHistory { jobs: AdminBotJobHistoryItem[] }
200 goodAdminBotJobLogs { logs: string | null }
200 goodAdminBotJobPull { job: PulledAdminBotJob | null }
200 goodAdminBotChallengeSource { sourceCode: string, configRevision: string }
200 goodAdminBotJobUpdate { ok: boolean }
200 goodAdminBotQueueDepth { depth: number }
200 goodDynamicScores { inserted: number, updated: number, deleted: number }
200 goodExternalAuthClient { id: string, name: string, redirectUri: string }
200 goodExternalAuthAuthorize { redirectTo: string }
200 goodExternalAuthToken { accessToken: string, tokenType: "bearer" }
200 goodAdminExternalAuthClients { id, name, redirectUri, createdAt, createdBy }[]
200 goodAdminExternalAuthClientCreate { id, name, redirectUri, createdAt, createdBy, secret } (secret shown once)
200 goodAdminExternalAuthClientDelete No data.

Shared objects

ChallengeFileV2

Field Type
name string
url string
size number | null

Endpoint

Field Type
kind "tcp" | "tcp-ssl" | "http" | "https"
host string
port number
title string | undefined

InstancerConfig

Field Type
challengeIntegrationId string
config Record<string, unknown>
expose Expose[]
timeoutMilliseconds number
extendable boolean | undefined

Expose

Field Type
kind "tcp" | "tcp-ssl" | "http" | "https"
hostPrefix string
containerName string
containerPort number
shouldDisplay boolean | undefined
title string | undefined

AdminBotConfig

Field Type
code string
inputs Record<string, RegexRule>
revision string
timeoutMilliseconds number
requireInstancerInstancesRunning boolean | undefined

RegexRule

Field Type
pattern string
flags string | undefined

Enum values

Enum Values
InstanceStatus stopped, running, starting, stopping, errored
AdminBotJobStatus queued, running, completed, failed
AdminTeamSortBy createdAt, team, email, division, score, solves, status
SortOrder asc, desc
AdminTeamStatus active, banned, admin
SubmissionKind flag, admin_bot
SubmissionSortBy createdAt, challenge, team, ip, kind, result
SubmissionResult correct, incorrect, already_solved, queued, active_job, invalid_input, bad_instancer_state
SubmissionTeamStatus banned, not_banned
ProtectedAction register, recover, setEmail, instancerStart, instancerExtend, avatarUpload, adminBotSubmit

Type to search.