Users

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

Edit this page View Markdown

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. Every profile update consumes from a per user rate limit bucket, regardless of which fields are present.

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

Edit this page View Markdown
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*string
Team ID.

Response fields

namestring
Team display name.
ctftimeIdstring | null | undefined
Linked CTFtime team ID, when present.
divisionstring
Division the team competes in.
scorenumber
Total team score.
globalPlacenumber | null
Overall rank, or null when unranked.
divisionPlacenumber | null
Rank within the division, or null when unranked.
solves[].categorystring
Challenge category.
solves[].namestring
Challenge name.
solves[].pointsnumber | null
Challenge point value, or null when unavailable.
solves[].awardedPointsnumber | null
Points awarded to the team for this solve, or null.
solves[].solvesnumber | null
Total solve count for the challenge, or null.
solves[].idstring
Challenge ID.
solves[].createdAtnumber
Solve time as a Unix timestamp in milliseconds.
solves[].bloodIndexnumber | null
Zero-based solve order (0 = first blood), or null.
dynamicScores[].idstring
Dynamic challenge ID.
dynamicScores[].pointsnumber
The team’s current points for this challenge.
dynamicScores[].pointDeltanumber
The team’s point change from the latest scoring tick.
avatarUrlstring | null
Team avatar URL, or null when unset.
countryCodestring | null
ISO 3166-1 alpha-2 country code, or null when unset.
statusTextstring | null
Free-form team status badge, or null when unset.

GET Own profile

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

Edit this page View Markdown
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
Team ID.
namestring
Team display name.
emailstring | null
Account email address, or null when unset.
ctftimeIdstring | null | undefined
Linked CTFtime team ID, when present.
divisionstring
Division the team competes in.
scorenumber
Total team score.
globalPlacenumber | null
Overall rank, or null when unranked.
divisionPlacenumber | null
Rank within the division, or null when unranked.
solves[].categorystring
Challenge category.
solves[].namestring
Challenge name.
solves[].pointsnumber | null
Challenge point value, or null when unavailable.
solves[].awardedPointsnumber | null
Points awarded to the team for this solve, or null.
solves[].solvesnumber | null
Total solve count for the challenge, or null.
solves[].idstring
Challenge ID.
solves[].createdAtnumber
Solve time as a Unix timestamp in milliseconds.
solves[].bloodIndexnumber | null
Zero-based solve order (0 = first blood), or null.
dynamicScores[].idstring
Dynamic challenge ID.
dynamicScores[].pointsnumber
The team’s current points for this challenge.
dynamicScores[].pointDeltanumber
The team’s point change from the latest scoring tick.
teamTokenstring
Token used to invite teammates to the team.
allowedDivisionsstring[]
Divisions the team is allowed to switch to.
permsnumber | null
Permission bitmask, or null for a standard user.
bannedboolean
Whether the team is banned from the competition.
avatarUrlstring | null
Team avatar URL, or null when unset.
countryCodestring | null
ISO 3166-1 alpha-2 country code, or null when unset.
statusTextstring | null
Free-form team status badge, or null when unset.

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

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

V2 can update the authenticated team’s name, division, country or region code, and status text. V1 supports only the name and division. Changes refresh the team’s cached profile and leaderboard entry.

Every request uses the same profile rate-limit bucket, regardless of the fields it changes. A new division must be allowed for the team’s current email address.

Division changes stop when the competition ends because they affect the final standings. Other fields remain editable. V2 returns badDivisionChangeEnded, while V1 returns badBody.

Request body

namestring
2-64 printable ASCII characters.
divisionstring
Division to switch the team to.
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"
ISO 3166-1 alpha-2 country code, or null to clear.
statusTextstring
Free-form status badge (max 60 chars), or null to clear.

Response fields

user.namestring
Team display name.
user.emailstring | null
Account email address, or null when unset.
user.divisionstring
Division the team competes in.
user.avatarUrlstring | null
Team avatar URL, or null when unset.
user.countryCodestring | null
ISO 3166-1 alpha-2 country code, or null when unset.
user.statusTextstring | null
Free-form team status badge, or null when unset.

PATCH Update avatar

PATCH /api/v2/users/me/avatar

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

Send an image in the avatar field of a multipart/form-data body to set or replace the team avatar. Omit the field to remove the current avatar.

rCTF enforces maxAvatarSize, resizes the image to 256 by 256 pixels, converts it to WebP, and checks it with the moderation provider when configured. After the upload provider stores the new image, rCTF deletes the previous one.

Request body

avatarcustom
Avatar image file (multipart form-data).
captchaCodestring
Checked only when captcha protects this route.

Response fields

urlstring | null
New avatar URL, or null when cleared.

PUT Set email auth

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

Edit this page View Markdown
Auth
Required
Gate
None
Permissions
No extra permissions
Captcha
setEmail
Rate limit
Email change bucket. Burst 3 and refill window 900000 ms per user.

This route sets or changes the authenticated team’s email. With an email provider configured, rCTF sends a verification message and returns 200 goodVerifySent. Otherwise, it applies the change immediately and returns 200 goodEmailSet.

The address must be unused and must still allow the team’s current division under the division ACLs. V1 and V2 share the same rate-limit bucket, and requests count against it before any verification email is sent.

Request body

email*string
Email address. Normalized to lowercase and trimmed.
captchaCodestring
Checked only when captcha protects this route.

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

Edit this page View Markdown
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

Edit this page View Markdown
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*string
CTFtime OAuth token to link to the account.

Response

A successful request returns 200 goodCtftimeAuthSet with no data.

DELETE Remove CTFtime auth

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

Edit this page View Markdown
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

Edit this page View Markdown
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
Membership ID.
useridstring
User ID of the team member.
emailstring
Member email address.

POST Add a team member

POST /api/v1/users/me/members

Edit this page View Markdown
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*string
Email address. Normalized to lowercase and trimmed.

Response fields

idstring
Membership ID.
useridstring
User ID of the team member.
emailstring
Member email address.

DELETE Remove a team member

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

Edit this page View Markdown
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*string
Membership ID.

Response

A successful request returns 200 goodMemberDelete with no data.

Type to search.