Skip to main content

Platform signal details

This page is the implementation-focused companion to Platform age signals. Use it when you need exact field shapes, endpoint behavior, and examples you can map directly into your client or server-side integration.

Choose the right signal shape

PlatformNative signal typeWhat to send to k-IDVerified for age requirements?Notes
Apple iOSNumeric age rangeageLow, ageHigh, optional declarationTypeYes, for verified declaration typesDon't send category
Google PlayNumeric age rangeageLow, ageHigh, optional declarationTypeYes, for verified declaration typesDon't send category
XboxCategorycategoryNok-ID resolves the category using the player's jurisdiction
Meta HorizonCategorycategoryNok-ID resolves the category using the player's jurisdiction
k-IDPrior verificationverificationId, plus optional category or rangeYes, if the verification is validdeclarationType is resolved server-side
tip

If a platform already gives you ageLow and ageHigh, send those values directly. Only use POST /age-gate/get-platform-age-range for category-based platforms.

Platform-specific integration guide

Apple iOS

How to obtain the signal: use the Age Range Service to get the player's age range and declaration type.

What to send to k-ID: name, ageLow, ageHigh, and optionally declarationType.

Verified declaration types: paymentChecked, governmentIDChecked, guardianPaymentChecked, guardianGovernmentIDChecked

{
"name": "apple-ios",
"ageLow": 18,
"ageHigh": 25,
"declarationType": "governmentIDChecked"
}

Google Play

How to obtain the signal: use the Play Age Signals API to get the player's age range and userStatus.

What to send to k-ID: name, ageLow, ageHigh, and optionally declarationType.

Verified declaration types: VERIFIED, SUPERVISED

{
"name": "google-play",
"ageLow": 13,
"ageHigh": 17,
"declarationType": "VERIFIED"
}

Xbox

How to obtain the signal: use XR-014 and XUserGetAgeGroup to get the player's age group.

What to send to k-ID: name and category.

Accepted categories: child, teen, adult

How k-ID interprets them:

  • child = [0, digitalConsentAge - 1]
  • teen = [digitalConsentAge, civilAge - 1]
  • adult = [civilAge, 100]

Xbox signals aren't considered verified for verified-age permissions.

{
"name": "xbox",
"category": "adult"
}

Meta Horizon

How to obtain the signal: use the Get Age Category API to get CH, TN, or AD.

What to send to k-ID: name and category.

Accepted categories: CH, TN, AD

How k-ID interprets them:

  • CH = [10, digitalConsentAge - 1] with a minimum age of 10
  • TN = [digitalConsentAge, civilAge - 1]
  • AD = [civilAge, 100]

For a typical Brazil configuration, that results in CH=10-12, TN=13-17, AD=18+.

Meta Horizon signals aren't considered verified for verified-age permissions.

{
"name": "meta-horizon",
"category": "TN"
}

k-ID

How to obtain the signal: use a previously completed k-ID verification and pass its verificationId.

What to send to k-ID: name: "k-id" and verificationId. You can also send category or ageLow and ageHigh if your flow needs them, but whether the signal counts as verified comes from the verification lookup.

Server-side verification checks: the signal is considered verified only when the verification:

  1. Exists
  2. Has status PASS
  3. Belongs to the same organization as the requesting product

Caller-provided declarationType values are ignored for k-id signals.

{
"name": "k-id",
"category": "adult",
"verificationId": "a50f4f73-3c0c-4720-a8b3-ec57ccb0aa34"
}
note

verificationId is limited to one active session per product within an organization. The same verification can be reused across different products in the same organization, but not by multiple active sessions in the same product.

API reference

The six endpoints below are the most relevant to platform age signal integration. Each entry describes when and why to call it. For the full request and response schema, follow the link to the API reference.

GET /age-gate/get-requirements

Call this before showing the age gate. Pass platform signal fields as query parameters (platformName, platformAgeLow, platformAgeHigh, platformCategory, platformDeclarationType, platformVerificationId) to let k-ID factor the signal in before you even collect input.

Key response fields to act on:

  • shouldDisplay: false when a verified platform signal proves the player is an adult; skip your age gate UI when this is false
  • ageAssuranceRequired: false only when every verified-age permission is already satisfied by the signal
  • permissions: lists permissions with a verifiedAgeThreshold; useful even when all are already satisfied

GET /age-gate/get-default-permissions

Call this when you want to preview permission states without creating a session. Useful for checking whether a verified signal would immediately satisfy a threshold permission before the full age gate flow runs.

  • Permissions with verifiedAgeThreshold default to enabled: false
  • A verified signal with ageLow >= threshold sets those permissions to enabled: true
  • For k-id signals, the declaration type is resolved server-side from platformVerificationId

GET /session/get

Refresh the session after check, VPC, or an age assurance challenge. The response includes an ageVerification object when a verified platform signal (or completed age assurance) has been recorded on the session. Check ageVerification.platformName and ageVerification.declarationType to understand the verification source.

POST /age-gate/check

Creates or updates the session. Pass a platformAgeSignal in the request body, either on its own or alongside dateOfBirth, age, or kuid. k-ID uses the more conservative of the two ages when both are present.

Possible outcomes relevant to platform signals:

  • Verified signal + age meets threshold: session contains ageVerification and the permission is enabled: true
  • Signal present but not verified: session is created without ageVerification; high-risk permission needs age assurance later
  • Player age below threshold: permission is managedBy: PROHIBITED; the age assurance recovery flow applies
  • Age conflict: returns 400 AGE_CONFLICT when age-conflict detection is enabled and the platform signal indicates a younger age category than the player's self-reported age

POST /age-gate/get-platform-age-range

Converts a platform category string into a concrete ageLow/ageHigh pair for a given jurisdiction. Only needed for category-based platforms (Xbox, Meta Horizon, k-ID). If the platform already gives you a numeric range, skip this call and send the values directly.

POST /session/upgrade

Requests additional permissions for a player's existing session. This is the endpoint that determines whether a high-risk permission can be unlocked immediately or needs an age assurance challenge first.

The challenge type returned depends on what's being requested:

Scenariochallenge.type returned
Permission is PLAYER-managedNo challenge: permission enabled immediately
Permission is GUARDIAN-managedCHALLENGE_SESSION_UPGRADE (trusted adult consent)
Permission has verifiedAgeThreshold and session has no ageVerificationCHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE (player must verify age)
Permission has verifiedAgeThreshold and session already has ageVerification meeting the thresholdNo challenge: permission enabled immediately

Key constraint: all permissions in a single upgrade request must be of the same type. Mixing permissions with and without verifiedAgeThreshold in one call returns 400: "Can't mix permissions with and without verifiedAgeThreshold".

Example: request a high-risk permission (triggers age assurance):

POST /api/v1/session/upgrade
Content-Type: application/json
Authorization: Bearer your-api-key

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
]
}

Example: pass a k-ID signal from a completed age appeal to satisfy the threshold directly, without creating a new challenge:

POST /api/v1/session/upgrade
Content-Type: application/json
Authorization: Bearer your-api-key

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
],
"platformAgeSignal": {
"name": "k-id",
"verificationId": "a50f4f73-3c0c-4720-a8b3-ec57ccb0aa34"
}
}

When a CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE challenge is returned, direct the player to the challenge.url to complete age verification through AgeKit+. Once the challenge passes, retrieve the updated session: the permission is now enabled: true with an ageVerification object on the session.

Validation and edge cases

Input validation

ScenarioResult
platformAgeSignal with missing name400: "Platform name must be provided"
Unknown platform name400: "Unknown platform name"
apple-ios or google-play with category400: "Platform must have age range specified"
Both category and ageLow/ageHigh provided400: "Provide either category or ageLow and ageHigh, not both"
Only ageLow without ageHigh (or vice versa)400: "ageLow and ageHigh must both be provided"
ageLow greater than ageHigh400: Invalid range
Mixed threshold and non-threshold permissions in session/upgrade400: "Can't mix permissions with and without verifiedAgeThreshold"

Age conflict matrix

When both a primary age and a platform signal are present:

Platform age category \ Primary age categoryPrimary: MinorPrimary: YouthPrimary: Adult
Platform: MinorNo conflictCONFLICTCONFLICT
Platform: YouthNo conflictNo conflictCONFLICT
Platform: AdultNo conflictNo conflictNo conflict

A conflict only happens when the platform says the player is younger than the self-reported age category.

k-id signal security rules

  • declarationType is always resolved server-side from verificationId
  • Caller-provided declarationType is ignored
  • The verification must be PASS
  • The verification must belong to the same organization as the requesting product
  • Without a valid verificationId, the k-id signal is treated as unverified

Conservative defaults

  • If shouldDisplay is false and you have no platform signal to send, call POST /age-gate/check with age: 1
  • If the platform signal and primary age disagree but don't conflict, k-ID uses the lower age
  • Verified-age permissions default to enabled: false until they're actually satisfied