NEOLearn

IdentityService

Accounts, sign-in, guests, devices and account settings.

Updated October 17, 2026

On this page

Accounts and sign-in. Every method is a POST with a JSON body; see the overview for the protocol, authentication and errors.

Summary#

MethodAuthDescription
SignUpNone
SignInNone
RefreshNone
SignOutNone
GetMeAccount or guest
StartGuestNonePlay without an account: a guest token with child-safe limits (no chat, no purchases), upgradable to an account that keeps the guest's progress.
UpgradeGuestAccount or guestTurns the signed-in guest into a full account.
ChangePasswordAccountAccount management.
ChangeUsernameAccount
ListDevicesAccountSigned-in devices (refresh-token sessions) and revoking them.
RevokeDeviceAccount
SignOutEverywhereAccount
GetSettingsAccount
UpdateSettingsAccount
DeleteAccountAccountDeactivates the account (data deletion follows the retention policy).
IssueScopedTokenAccountA short-lived token for an embedded editor (the 3D avatar editor, the Studio), scoped to the calls it makes, instead of the player's access token. The page refreshes it before it expires and hands the new one to the editor (postMessage).
CreateHandoffAccountSingle sign-on between the platform's own web hosts (the main host and the studio host have separate browser storage): the signed-in host mints a one-time code for the other host's origin, bound to a PKCE challenge (RFC 7636 S256); the other host redeems it, from that origin and with the verifier, for a session of its own (a new device). Codes work once and live 60 seconds. Target origins are the API's web origins (NEO_WEB_URL, NEO_STUDIO_URL, NEO_WEB_ORIGINS; loopback hosts outside production).
RedeemHandoffNoneSpends a handoff code for a new device session. Must be called from the origin the code was made for (the browser's Origin header), with the verifier of its challenge; the code is spent even when the call fails.

Methods#

SignUp#

HTTP
POST /neo.platform.v1.IdentityService/SignUp
Content-Type: application/json

Auth: None.

Request: SignUpRequest. Response: AuthResponse.

SignIn#

HTTP
POST /neo.platform.v1.IdentityService/SignIn
Content-Type: application/json

Auth: None.

Request: SignInRequest. Response: AuthResponse.

Refresh#

HTTP
POST /neo.platform.v1.IdentityService/Refresh
Content-Type: application/json

Auth: None.

Request: RefreshRequest. Response: AuthResponse.

SignOut#

HTTP
POST /neo.platform.v1.IdentityService/SignOut
Content-Type: application/json

Auth: None.

Request: SignOutRequest. Response: SignOutResponse.

GetMe#

HTTP
POST /neo.platform.v1.IdentityService/GetMe
Content-Type: application/json

Auth: A signed-in account or a guest. Also callable with a scoped token: studio.

Request: GetMeRequest. Response: Me.

StartGuest#

Play without an account: a guest token with child-safe limits (no chat, no purchases), upgradable to an account that keeps the guest's progress.

HTTP
POST /neo.platform.v1.IdentityService/StartGuest
Content-Type: application/json

Auth: None.

Request: StartGuestRequest. Response: AuthResponse.

UpgradeGuest#

Turns the signed-in guest into a full account.

HTTP
POST /neo.platform.v1.IdentityService/UpgradeGuest
Content-Type: application/json

Auth: A signed-in account or a guest.

Request: SignUpRequest. Response: AuthResponse.

ChangePassword#

Account management.

HTTP
POST /neo.platform.v1.IdentityService/ChangePassword
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: ChangePasswordRequest. Response: ChangePasswordResponse.

ChangeUsername#

HTTP
POST /neo.platform.v1.IdentityService/ChangeUsername
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: ChangeUsernameRequest. Response: Me.

ListDevices#

Signed-in devices (refresh-token sessions) and revoking them.

HTTP
POST /neo.platform.v1.IdentityService/ListDevices
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: ListDevicesRequest. Response: ListDevicesResponse.

RevokeDevice#

HTTP
POST /neo.platform.v1.IdentityService/RevokeDevice
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: RevokeDeviceRequest. Response: RevokeDeviceResponse.

SignOutEverywhere#

HTTP
POST /neo.platform.v1.IdentityService/SignOutEverywhere
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: SignOutEverywhereRequest. Response: SignOutResponse.

GetSettings#

HTTP
POST /neo.platform.v1.IdentityService/GetSettings
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: GetSettingsRequest. Response: AccountSettings.

UpdateSettings#

HTTP
POST /neo.platform.v1.IdentityService/UpdateSettings
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: AccountSettings. Response: AccountSettings.

DeleteAccount#

Deactivates the account (data deletion follows the retention policy).

HTTP
POST /neo.platform.v1.IdentityService/DeleteAccount
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: DeleteAccountRequest. Response: DeleteAccountResponse.

IssueScopedToken#

A short-lived token for an embedded editor (the 3D avatar editor, the Studio), scoped to the calls it makes, instead of the player's access token. The page refreshes it before it expires and hands the new one to the editor (postMessage).

HTTP
POST /neo.platform.v1.IdentityService/IssueScopedToken
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: IssueScopedTokenRequest. Response: ScopedToken.

CreateHandoff#

Single sign-on between the platform's own web hosts (the main host and the studio host have separate browser storage): the signed-in host mints a one-time code for the other host's origin, bound to a PKCE challenge (RFC 7636 S256); the other host redeems it, from that origin and with the verifier, for a session of its own (a new device). Codes work once and live 60 seconds. Target origins are the API's web origins (NEO_WEB_URL, NEO_STUDIO_URL, NEO_WEB_ORIGINS; loopback hosts outside production).

HTTP
POST /neo.platform.v1.IdentityService/CreateHandoff
Content-Type: application/json

Auth: A signed-in account. Guests are refused.

Request: CreateHandoffRequest. Response: Handoff.

RedeemHandoff#

Spends a handoff code for a new device session. Must be called from the origin the code was made for (the browser's Origin header), with the verifier of its challenge; the code is spent even when the call fails.

HTTP
POST /neo.platform.v1.IdentityService/RedeemHandoff
Content-Type: application/json

Auth: None.

Request: RedeemHandoffRequest. Response: AuthResponse.

Types#

AccountSettings#

Privacy and preferences. Who-can values: everyone, friends, nobody.

FieldTypeDescription
whoCanMessagestring
whoCanFriendstring
whoCanJoinstring
showOnlineStatusboolean, optional
emailNotificationsboolean, optional
themestring

AuthResponse#

FieldTypeDescription
accessTokenstringEd25519 JWT, short-lived.
refreshTokenstring
expiresInSecondsstring (int64)
meMe

ChangePasswordRequest#

FieldTypeDescription
currentPasswordstring
newPasswordstring

ChangePasswordResponse#

Other devices are signed out; this device gets fresh tokens.

FieldTypeDescription
authAuthResponse

ChangeUsernameRequest#

FieldTypeDescription
newUsernamestring
passwordstring

CreateHandoffRequest#

FieldTypeDescription
targetOriginstringThe origin the code is for, e.g. "https://studio.neoengine.io".
codeChallengestringbase64url(SHA-256(code_verifier)) without padding: 43 characters.

DeleteAccountRequest#

FieldTypeDescription
passwordstring

DeleteAccountResponse#

No fields: send {}.

Device#

FieldTypeDescription
idstring
labelstringFrom the client descriptor (e.g. "Web · Chrome", "Desktop · macOS").
createdAtstring
lastUsedAtstring
currentboolean

GetMeRequest#

No fields: send {}.

GetSettingsRequest#

No fields: send {}.

Handoff#

FieldTypeDescription
codestringThe one-time code (goes in the URL fragment, never a query string).
expiresInnumberSeconds until it expires.

IssueScopedTokenRequest#

FieldTypeDescription
scopestring"avatar" (AvatarService) or "studio" (the Studio's CatalogService calls, GetMe).

ListDevicesRequest#

No fields: send {}.

ListDevicesResponse#

FieldTypeDescription
devicesarray of Device

Me#

FieldTypeDescription
userUserSummary
ageBandAgeBand (enum)
createdAtstring
guestboolean

RedeemHandoffRequest#

FieldTypeDescription
codestring
codeVerifierstringThe verifier whose S256 challenge the code was made with (43-128 characters).

RefreshRequest#

FieldTypeDescription
refreshTokenstring

RevokeDeviceRequest#

FieldTypeDescription
deviceIdstring

RevokeDeviceResponse#

No fields: send {}.

ScopedToken#

FieldTypeDescription
tokenstring
expiresInnumberSeconds until it expires.

SignInRequest#

FieldTypeDescription
usernamestring
passwordstring

SignOutEverywhereRequest#

No fields: send {}.

SignOutRequest#

FieldTypeDescription
refreshTokenstring

SignOutResponse#

No fields: send {}.

SignUpRequest#

FieldTypeDescription
usernamestring
passwordstring
birthdatestringYYYY-MM-DD; sets the age band (never shown to others).
displayNamestring

StartGuestRequest#

No fields: send {}.

See also#