Skip to main content

Age, country and who may play

No gameplay token is issued to a player Crowded Kingdoms may not admit. Every mint and every refresh checks the player, whichever way the token is asked for (mintAppToken, refreshAppToken, hosted sign-in, or an organization signing in one of its own players), in this order:

  1. Country: TERRITORY_NOT_SUPPORTED where Crowded Kingdoms does not offer its services.
  2. Age: AGE_REQUIRED when the player's age is not known, AGE_REQUIREMENT_NOT_MET when the player is younger than the app allows where they are.
  3. Documents: LEGAL_ACCEPTANCE_REQUIRED until the player has accepted the platform's documents and the app's own (Legal documents).

A sign-up checks the country and the age before the account exists.

What is switched on
  • Since 2026-11-04, when Crowded Kingdoms opened to players 13 and over: the youngest player is 13; a browser sign-up gives a birth date and a country; an organization gives an age and a country for each player it signs in; developers are adults.
  • Game API v2.60.0: the checks above; the birth date and country at sign-up and in recordPlayerAge; a managed player's ageYears and country; an app's minPlayerAge; and the country list, enforced for every player, adults included.
  • Game API v2.61.0 and v2.61.1: age refusals that name no age, and the lock after one; the erasure of an account that declares an age under 13; countries checked by region, and a managed player's region; Crowded Kingdoms staff past the country check.

What changed on 2026-11-04​

BeforeSince
Youngest player1813, or older where the app or the player's country asks
How a Crowded Kingdoms account's age is knownthe age-of-majority attestation, or a birth datethe birth date; the attestation is ignored
A birth date at a browser sign-upoptionalrequired
A managed player's ageYears and countryoptional: with no age, the player counted as 18 or older, as the organization warrantedrequired
Countries Crowded Kingdoms does not serverefusedrefused

An account that attested its age before 2026-11-04 keeps the bracket 18_plus and is not asked again.

Ages are kept as brackets​

A player's age is one of five brackets: unknown (not given yet), under_13, 13_15, 16_17 and 18_plus. Of a birth date only the year and month are kept, and the age is counted from the last day of that month, so it is never overstated; the bracket moves on that day. A player reads their own:

query { me { ageBracket country } }

Both are private: null to anyone but the player. Your app's server code reads a player's bracket, never their age, with players.get.

Signing up​

register takes three more fields in registerUserInput:

FieldWhat
birthDateYYYY-MM-DD, or YYYY-MM
countrywhere the player lives, ISO 3166-1 alpha-2, such as US; sent with birthDate
parentalConfirmationtrue when a player under 18 confirms that a parent or guardian agreed; required under 18, ignored at 18 and over
mutation SignUp($input: RegisterUserInput!) {
register(registerUserInput: $input) { token user { userId } }
}
# variables: { "input": { "email": "...", "password": "...", "acceptLegal": true,
# "birthDate": "1994-04", "country": "US" } }

attestAgeOfMajority is ignored since 2026-11-04. Before any account exists, the sign-up is refused:

  • TERRITORY_NOT_SUPPORTED for a place Crowded Kingdoms does not serve: the country the player gave, or the country or region their connection comes from;
  • AGE_REQUIREMENT_NOT_MET under 13, or under the country's minimum. It names no age, and the same client is then refused AGE_REQUIREMENT_NOT_MET here and at recordPlayerAge, whatever it sends (the retry lock);
  • BAD_REQUEST for a date that is not a real date in the past, a country without a birth date or a birth date without one, or a player under 18 without parentalConfirmation: true.

A browser sign-up without a birth date is refused AGE_REQUIRED. A request with no Origin header (a native client, a tool) may leave the three fields out and give them with recordPlayerAge before its first mint.

An account with no age: recordPlayerAge​

An account whose ageBracket is unknown gives its birth date, country and (under 18) the parent's agreement once, with its session token:

mutation {
recordPlayerAge(input: { birthDate: "1994-04-17", country: "US" }) { ageBracket country }
}

A player under 18 sends parentalConfirmation: true as well. The answer cannot be changed by asking again, so record what the player entered, never a test value, on an account that will play.

  • An account that already has an age is refused CONFLICT, an attested one included: the age is not changed here. A Crowded Kingdoms operator corrects a wrong one.
  • A place Crowded Kingdoms does not serve is refused TERRITORY_NOT_SUPPORTED, except for Crowded Kingdoms staff.
  • Under 13 is refused AGE_REQUIREMENT_NOT_MET, and the account is deleted and erased, as deleteMyAccount does (Game API v2.61.0): Crowded Kingdoms keeps no personal information about the child. The same client is then locked out, as after a sign-up.
  • Whether the player may play a given app (its minimum age, the country's) is decided at the mint, not here.

The age screen​

Any screen that asks a player's age for Crowded Kingdoms follows these rules: a sign-up form, a launcher, an in-game prompt, or the screen of a server that signs its own players in.

  • Ask for the date of birth and the country. A month and a year is enough. Pick neither for the player, and suggest no answer.

  • Show no age. Not the youngest age allowed, and not the player's age.

  • Show the parental line only to a player whose date makes them 13 to 17, worded with no age. With it the player confirms that a parent or guardian agreed to the terms for them; send it as parentalConfirmation: true.

  • A refusal names no age. Tell the player they cannot sign up or play, without a reason, an age or a way to try again. AGE_REQUIREMENT_NOT_MET carries no extensions and its message names no age (Game API v2.61.0), so there is nothing in it to show.

  • Do not offer an immediate retry after an age refusal: no way back to the date to change it. Crowded Kingdoms stops one as well, whatever is sent next (Game API v2.61.1):

    • at sign-up and recordPlayerAge, a client that sends an x-ck-device-id header (an opaque random id it keeps, 16 to 128 letters, digits, - or _) is refused for 24 hours by that device, wherever it connects from; one that sends none is refused for an hour by its address and user agent, which schools, households and carriers share;
    • the same Minecraft account, for 24 hours;
    • the same managed player (your organization and its externalId), for 24 hours, in any of the organization's apps.

    That stops an immediate retry; it is not a barrier, so your screen keeps its own lockout. Send x-ck-device-id from a native client to get the day-long lock.

Minimum ages​

The youngest player an app admits is the highest of three:

  • the platform's: 13 (18 before 2026-11-04);
  • the app's, minPlayerAge, from 13 to 18, which only ever raises the platform's;
  • the country's, from territoryPolicies.
mutation AdultsOnly($appId: BigInt!) {
updateApp(appId: $appId, input: { minPlayerAge: 18 }) { minPlayerAge effectiveMinPlayerAge }
}

App.effectiveMinPlayerAge is the higher of the app's and the platform's. minPlayerAge: null returns the app to the platform's minimum. A raised minimum applies at each player's next mint or refresh: a younger player is refused AGE_REQUIREMENT_NOT_MET. An app whose minimum is 18 admits no minor, and needs no safety log: set it to keep a game for adults.

Countries​

query { territoryPolicies { countryCode regionCode status minAge } }

territoryPolicies is public, so a sign-up form can say so before an account exists. It lists the countries Crowded Kingdoms does not serve (status: "blocked") and those whose minimum age is above 13, then the regions it lists (regionCode, ISO 3166-2). A country it does not list is open at the platform's minimum. Read it rather than keeping a copy: the list changes, and every server applies a change within a minute, refusing a player already signed in there at their next refresh.

  • A Crowded Kingdoms account is checked on the country the player gave, and the country and region their connection comes from; any one blocked refuses. Hosted sign-in checks the player's browser when Studio issues the code, and not again when your game exchanges it.
  • Countries checked by region (Game API v2.61.0): a country with a region listed is checked by region. A connection from it whose region cannot be told is refused; Crowded Kingdoms asks a second location database before it does. The country a player gives is checked by country only, since sign-up asks no region.
  • A managed player is checked on the country, and where needed the region, its organization gives.
  • For everyone, from Game API v2.60.0, not only for players under 18. Crowded Kingdoms staff pass the country check at the mint and at recordPlayerAge (Game API v2.61.0), and are checked at sign-up like anyone, since an account's staff role is not known before it exists. The age checks apply to them as to everyone.
  • The refusal carries extensions.country, and extensions.region when a region decided it (null otherwise).

The Player Terms say where Crowded Kingdoms offers its services (section 1.7) and the minimum age by country (section 1.8); territoryPolicies is what the API enforces.

Players your organization signs in​

A managed player has no Crowded Kingdoms sign-up, so your organization gives its age and country at every sign-in: ageYears (whole years) and country (ISO 3166-1 alpha-2) on mintManagedPlayerToken, or as the ageYears and country claims of a signed assertion. In a country checked by region, it gives region too (ISO 3166-2, such as UA-30), which is checked at each sign-in and not stored (Game API v2.61.0).

  • Under 13, or under the app's or the country's minimum, the player is refused AGE_REQUIREMENT_NOT_MET before it is created or signed in, and the same player (your organization and its externalId) is refused again for 24 hours, in any of your organization's apps, whatever age you send. A player that already exists and is now said to be under 13 is deleted, as deleteManagedPlayer does.
  • A place Crowded Kingdoms does not serve, or a missing region where one is needed, is refused TERRITORY_NOT_SUPPORTED.
  • The bracket and the country are stored on the player. A refresh, which carries no age, is refused once the stored bracket is wholly below the app's minimum.
  • Both are required: no age is AGE_REQUIRED, no country BAD_REQUEST. (Before 2026-11-04 both were optional, and a player with no age counted as 18 or older.)
  • A player under 18 gets the minors' defaults: voice and video off until a parent consents, then contacts only, and no direct messages. The app must keep its safety log on (SAFETY_LOG_REQUIRED otherwise), and your organization must have appointed a moderator (SAFETY_MODERATOR_REQUIRED otherwise).

If your server asks players their age, the age screen applies to it. See Org-managed players.

Developers​

Creating an organization and administering one or its apps need the developer documents (Legal documents), which only adults may accept: an account with no age is refused AGE_REQUIRED (recordPlayerAge first), and one under 18 AGE_REQUIREMENT_NOT_MET. A player of 13 to 17 plays, and does not build on Crowded Kingdoms.

In the SDKs​

CrowdyJS 18.25.0CrowdyCPP 0.76.0CrowdyPy 0.24.0
Sign-up with the ageauth.register({ …, birthDate, country, parentalConfirmation })auth().registerUser(RegisterUserInput)auth.register(…, birth_date=, country=, parental_confirmation=)
An account with no ageauth.recordPlayerAge({ birthDate, country, parentalConfirmation })auth().recordPlayerAge(PlayerAgeInput)auth.record_player_age(birth_date=, country=, parental_confirmation=)
The bracket and countryusers.me()users().me()users.me()
The country and region list (regionCode)platform.territoryPolicies()platform().territoryPolicies()platform.territory_policies()
The refusalsterritoryNotSupportedOf, ageRequiredOf, ageRequirementNotMetOf, safetyLogRequiredOf, safetyModeratorRequiredOfgraphql::territoryNotSupportedOf and the same namesterritory_not_supported_of and the same names, in crowdypy.errors

The age readers surface no age. None of the SDKs wraps mintManagedPlayerToken, which runs on your organization's server; CrowdyJS and CrowdyPy type the assertion's claims (ManagedPlayerAssertionClaims: ageYears, country, region).

Refusals​

extensions.codeHTTPWhenWhat to do
TERRITORY_NOT_SUPPORTED403The player's place, the country they gave or their connection's country or region (extensions.country, extensions.region), is one Crowded Kingdoms does not serve; or, in a country checked by region, the region cannot be told or a managed player was sent without one.Tell the player Crowded Kingdoms is not available where they are. Do not retry.
AGE_REQUIRED403The player's age is not known: an account with no age, a browser sign-up without birthDate, or a managed player signed in without ageYears.Ask the age (the age screen), then recordPlayerAge, or sign the managed player in with ageYears and country.
AGE_REQUIREMENT_NOT_MET403The player is younger than the app allows where they are, or under 13; or a developer under 18; or the same device, client, Minecraft account or managed player was refused so recently (the retry lock). No extensions.Tell the player they cannot play this, without a reason, an age or a way to try again. Do not retry with another date or age.
LEGAL_ACCEPTANCE_REQUIRED403Documents are missing (extensions.missingDocuments).Legal documents.
SAFETY_LOG_REQUIRED403A player under 18, in an app whose safety log is off: at the mint, and since Game API v2.61.1 when Studio's hosted sign-in issues the code.The app's admins turn it on (the safety log). Tell the player the game cannot admit them yet.
SAFETY_MODERATOR_REQUIRED403A player under 18, in an app whose organization has no appointed moderator (Game API v2.61.0; at the hosted sign-in's code too since v2.61.1).The organization gives a member a role that grants moderate_safety (Moderators). Tell the player the game cannot admit them yet, naming no age.
CONFLICT409recordPlayerAge on an account that has an age.Read me { ageBracket }; do not ask again.
BAD_REQUEST400A malformed date or country, one without the other, or a player under 18 without parentalConfirmation.Fix the input.

All codes are on Error codes.