rCTF Docs

Users

API reference for public profiles, self profiles, profile updates, avatars, email auth, CTFtime auth, and team members.

User routes cover public team profiles and authenticated account settings. V2 includes avatar, country, and status fields. V1 is still used for team members and CTFtime account links.

Public profile routes are available after the CTF starts. Admin tokens with challsRead can read public profiles before that gate opens because profile responses include solve data.

When both V1 and V2 exist for the same action, V2 is usually the best fit for new clients. The V1 account management routes remain useful where there is no V2 route.

Profile data#

Public profiles include the team name, division, score, rank fields, CTFtime ID when linked, and visible solves. V2 also includes avatar URL, country or region code, status text, and bloodIndex on solve rows.

The own profile routes include private account fields as well, such as the team ID, email address, team token, allowed divisions, and admin permission bitmask when present.

Account updates#

Profile updates can change the team name and division. V2 can also update country or region code and status text. Name updates use a per user rate limit bucket.

Email auth may involve a verification email, depending on provider configuration. CTFtime auth and team member management are available through V1 routes.

GET Public profile

GET /api/[v2,v1]/users/:id

Auth
Public
Gate
Started (bypass challsRead)
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route returns the public profile for one team. Public profiles are available after the CTF starts, and admin tokens with challsRead can read through that gate.

For new clients, V2 is usually the best fit. It includes avatar URL, country or region code, status text, and bloodIndex on solve rows. V1 remains available for older clients.

Path parameters

id requiredstring
Unique identifier.

Response fields

namestring
Display name.
ctftimeIdstring | null | undefined
Returned ctftime id value.
divisionstring
Division name or filter.
scorenumber
Current score.
globalPlacenumber | null
Global leaderboard rank.
divisionPlacenumber | null
Division leaderboard rank.
solves[].categorystring
Returned solves category value.
solves[].namestring
Display name.
solves[].pointsnumber | null
Point value.
solves[].awardedPointsnumber | null
Returned solves awarded points value.
solves[].solvesnumber | null
Returned solves solves value.
solves[].idstring
Unique identifier.
solves[].createdAtnumber
Creation timestamp.
solves[].bloodIndexnumber | null
Returned solves blood index value.
dynamicScores[].idstring
Unique identifier.
dynamicScores[].pointsnumber
Point value.
dynamicScores[].pointDeltanumber
Returned dynamic scores point delta value.
avatarUrlstring | null
Avatar image URL.
countryCodestring | null
Country or region code.
statusTextstring | null
Team status text.

Response fields

namestring
Display name.
ctftimeIdstring | null | undefined
Returned ctftime id value.
divisionstring
Division name or filter.
scorenumber
Current score.
globalPlacenumber | null
Global leaderboard rank.
divisionPlacenumber | null
Division leaderboard rank.
solves[].categorystring
Returned solves category value.
solves[].namestring
Display name.
solves[].pointsnumber | null
Point value.
solves[].awardedPointsnumber | null
Returned solves awarded points value.
solves[].solvesnumber | null
Returned solves solves value.
solves[].idstring
Unique identifier.
solves[].createdAtnumber
Creation timestamp.
dynamicScores[].idstring
Unique identifier.
dynamicScores[].pointsnumber
Point value.
dynamicScores[].pointDeltanumber
Returned dynamic scores point delta value.

GET Own profile

GET /api/[v2,v1]/users/me

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route returns the authenticated team’s profile, including private account fields. It is useful for account settings, profile screens, and client side session state.

V2 includes the same public profile additions as public profile. V1 returns the older profile fields and remains available for clients that already use it.

Response fields

idstring
Unique identifier.
namestring
Display name.
emailstring | null
Email address.
ctftimeIdstring | null | undefined
Returned ctftime id value.
divisionstring
Division name or filter.
scorenumber
Current score.
globalPlacenumber | null
Global leaderboard rank.
divisionPlacenumber | null
Division leaderboard rank.
solves[].categorystring
Returned solves category value.
solves[].namestring
Display name.
solves[].pointsnumber | null
Point value.
solves[].awardedPointsnumber | null
Returned solves awarded points value.
solves[].solvesnumber | null
Returned solves solves value.
solves[].idstring
Unique identifier.
solves[].createdAtnumber
Creation timestamp.
solves[].bloodIndexnumber | null
Returned solves blood index value.
dynamicScores[].idstring
Unique identifier.
dynamicScores[].pointsnumber
Point value.
dynamicScores[].pointDeltanumber
Returned dynamic scores point delta value.
teamTokenstring
Team token returned by the route.
allowedDivisionsstring[]
Returned allowed divisions value.
permsnumber | null
Returned perms value.
avatarUrlstring | null
Avatar image URL.
countryCodestring | null
Country or region code.
statusTextstring | null
Team status text.

Response fields

idstring
Unique identifier.
namestring
Display name.
emailstring | null
Email address.
ctftimeIdstring | null | undefined
Returned ctftime id value.
divisionstring
Division name or filter.
scorenumber
Current score.
globalPlacenumber | null
Global leaderboard rank.
divisionPlacenumber | null
Division leaderboard rank.
solves[].categorystring
Returned solves category value.
solves[].namestring
Display name.
solves[].pointsnumber | null
Point value.
solves[].awardedPointsnumber | null
Returned solves awarded points value.
solves[].solvesnumber | null
Returned solves solves value.
solves[].idstring
Unique identifier.
solves[].createdAtnumber
Creation timestamp.
dynamicScores[].idstring
Unique identifier.
dynamicScores[].pointsnumber
Point value.
dynamicScores[].pointDeltanumber
Returned dynamic scores point delta value.
teamTokenstring
Team token returned by the route.
allowedDivisionsstring[]
Returned allowed divisions value.
permsnumber | null
Returned perms value.

Treat teamToken as a credential. It can be used for account recovery and team scoped auth flows.

PATCH Update profile

PATCH /api/[v2,v1]/users/me

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
Profile name update bucket. Burst 3 and refill window 180000 ms per user.

This route updates profile fields for the authenticated team. Profile changes recalculate cached user data and trigger a leaderboard update.

V2 can update the name, division, country or region code, and status text. V1 can update the name and division.

Name updates use the shared profile name update bucket. Division updates are checked against the divisions allowed for the team’s current email address.

Request body

namestring
2-64 printable ASCII characters.
divisionstring
Division name or filter.
countryCode"AF" | "AX" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AI" | "AQ" | "AG" | "AR" | "AM" | "AW" | "AC" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BM" | "BT" | "BO" | "BA" | "BW" | "BV" | "BR" | "IO" | "VG" | "BN" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "IC" | "CV" | "BQ" | "KY" | "CF" | "EA" | "TD" | "CL" | "CN" | "CX" | "CP" | "CC" | "CO" | "KM" | "CK" | "CR" | "HR" | "CU" | "CW" | "CY" | "CZ" | "DK" | "DG" | "DJ" | "DM" | "DO" | "CD" | "EC" | "EG" | "SV" | "GQ" | "ER" | "EE" | "SZ" | "ET" | "EU" | "FK" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "TF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GI" | "GR" | "GL" | "GD" | "GP" | "GU" | "GT" | "GG" | "GN" | "GW" | "GY" | "HT" | "HM" | "HN" | "HK" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "CQ" | "IM" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LY" | "LI" | "LT" | "LU" | "MO" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MH" | "MQ" | "MR" | "MU" | "YT" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "MM" | "NA" | "NR" | "NP" | "NL" | "NC" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "MK" | "MP" | "NO" | "OM" | "PK" | "PW" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PN" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "SH" | "KN" | "LC" | "MF" | "PM" | "VC" | "WS" | "SM" | "ST" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SB" | "SO" | "ZA" | "GS" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SE" | "CH" | "SY" | "TW" | "TJ" | "TZ" | "TH" | "TL" | "TG" | "TK" | "TO" | "TT" | "TA" | "TN" | "TR" | "TM" | "TC" | "TV" | "UG" | "UA" | "AE" | "GB" | "UN" | "US" | "UM" | "VI" | "UY" | "UZ" | "VU" | "VA" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW"
Country or region code.
statusTextstring
Team status text.

Request body

namestring
2-64 printable ASCII characters.
divisionstring
Division name or filter.

Response fields

user.namestring
Display name.
user.emailstring | null
Email address.
user.divisionstring
Division name or filter.
user.avatarUrlstring | null
Avatar image URL.
user.countryCodestring | null
Country or region code.
user.statusTextstring | null
Team status text.

Response fields

user.namestring
Display name.
user.emailstring | null
Email address.
user.divisionstring
Division name or filter.

PATCH Update avatar

PATCH /api/v2/users/me/avatar

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
avatarUpload
Rate limit
Avatar upload bucket. Burst 2 and refill window 120000 ms per user.

This route uploads, replaces, or removes the team avatar. The request body uses multipart/form-data.

Include an image file as the avatar form field to upload or replace an avatar. Leaving out avatar removes the current avatar when one exists.

The route checks maxAvatarSize, resizes the image to 256 by 256 pixels, converts it to WebP, and can send it through the moderation provider. The active upload provider stores the new image. The previous avatar is deleted when it is replaced.

Request body

avatarcustom
Request body field for avatar.
captchaCodestring
Captcha challenge token.

Response fields

urlstring | null
Resource URL.

PUT Set email auth

PUT /api/[v2,v1]/users/me/auth/email

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
setEmail
Rate limit
No rate limit

This route sets or changes the email address for the authenticated team.

When email delivery is configured, the route sends a verification email and returns 200 goodVerifySent. When email delivery is not configured, the email is updated immediately and the route returns 200 goodEmailSet.

Duplicate emails are not accepted. Email changes also need to keep the team inside its division ACL.

Request body

email requiredstring
Email address. Normalized to lowercase and trimmed.
captchaCodestring
Captcha challenge token.

Request body

email requiredstring
Email address. Normalized to lowercase and trimmed.
recaptchaCodestring
reCAPTCHA challenge token.

Response#

Both success responses return no data. When the route returns 200 goodVerifySent, the verification token can be submitted to verify a token.

DELETE Remove email auth

DELETE /api/v1/users/me/auth/email

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route removes email auth from the authenticated team. It is available in V1.

If removing email auth would leave the team without either email auth or CTFtime auth, the route returns 409 badZeroAuth.

Response#

A successful request returns 200 goodEmailRemoved with no data.

PUT Set CTFtime auth

PUT /api/v1/users/me/auth/ctftime

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route links the authenticated team to a CTFtime team by using a CTFtime auth token. It is available in V1.

When CTFtime auth is not configured, the route returns 404 badEndpoint.

Request body

ctftimeToken requiredstring
CTFtime authentication token.

Response#

A successful request returns 200 goodCtftimeAuthSet with no data.

DELETE Remove CTFtime auth

DELETE /api/v1/users/me/auth/ctftime

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route removes CTFtime auth from the authenticated team. It is available in V1.

If removing CTFtime auth would leave the team without either email auth or CTFtime auth, the route returns 409 badZeroAuth.

Response#

A successful request returns 200 goodCtftimeRemoved with no data.

GET List team members

GET /api/v1/users/me/members

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route lists informational team member email rows under the authenticated team account. Team member rows do not create separate login identities.

It is available in V1. When userMembers is disabled, the route returns 404 badEndpoint.

Response fields

idstring
Unique identifier.
useridstring
Returned userid value.
emailstring
Email address.

POST Add a team member

POST /api/v1/users/me/members

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route adds an informational team member email row under the authenticated team account. Teams can have up to maxMembers member rows.

It is available in V1. When userMembers is disabled, the route returns 404 badEndpoint.

Request body

email requiredstring
Email address. Normalized to lowercase and trimmed.

Response fields

idstring
Unique identifier.
useridstring
Returned userid value.
emailstring
Email address.

DELETE Remove a team member

DELETE /api/v1/users/me/members/:id

Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
No captcha
Rate limit
No rate limit

This route removes a team member email row from the authenticated team account. It is available in V1.

Path parameters

id requiredstring
Unique identifier.

Response#

A successful request returns 200 goodMemberDelete with no data.

Esc

Start typing to search the docs.