Skip to content
AtlasDocs
Sign inGet started
Updated Aug 04, 2026

Authentication Paths

License keys and username / password accounts. Same session shape on the server, same continuous re-authentication on the client. Pick the path that matches your distribution model.

License path

A single key the user pastes on first launch. The server binds it to an HWID on first use (unless disabled in the dashboard) and a session starts. No email, no verification code.

// License path. Returns bool.
if (!Atlas::License::Login("ATLAS-A9F2K-4RMXM")) {
std::cout << Atlas::Data::GetErrorMessage();
return 1;
}
// Username/password variant - overload of Login, for a license bound to one user.
if (!Atlas::License::Login("marcus.reyes", "Wp7#kLm2vQ")) return 1;

The C++ binding exposes both forms as overloads of License::Login. The JS and Python bindings split them into License.Login (key) and License.LoginUser (username + password).

Register binds a license to a username and password (does NOT sign in)
// Bind an existing license to a username and password.
// Does NOT sign in - call License::Login(u, p) after.
Atlas::License::Register("ATLAS-A9F2K-4RMXM", "marcus.reyes", "Wp7#kLm2vQ");
Atlas::License::Login("marcus.reyes", "Wp7#kLm2vQ");

Account path

Username + password with 8-digit email verification, password reset, and license redemption. Whether a verification code is required on a given sign-in is controlled per-app in the dashboard - see Account Policy.

// Account path. Inspect r.status to drive the flow.
auto r = Atlas::Account::Login("marcus.reyes", "Wp7#kLm2vQ");
// On Status::Ok: r.expiry, r.level, r.note are populated.
// On Status::NeedsVerification: r.masked_email, r.sign_in_ip,
// r.sign_in_country are populated; pass the
// 8-digit code to SubmitVerification(code).

Status values

All seven Status values from Atlas::Account::LoginResult::Status (C++), atlas.Account.Status (JS / Python). Identical wire meaning; identical handling on the client.

StatusC++JSPythonMeaningWhat to do
OkStatus::Ok'Ok'Status.OkLogin succeeded. Session is live.Continue to your application's main flow.
WrongCredentialsStatus::WrongCredentials'WrongCredentials'Status.WrongCredentialsUnknown username/password.Show the error message; let the user retry or contact support.
NeedsVerificationStatus::NeedsVerification'NeedsVerification'Status.NeedsVerificationThe server emailed an 8-digit code. masked_email, sign_in_ip, sign_in_country are populated.Show the code-entry UI and call SubmitVerification.
BannedStatus::Banned'Banned'Status.BannedUser record or HWID is banned.Show the error message. The ban lifts when it expires or you remove it under Bans in the dashboard.
AccountPausedStatus::AccountPaused'AccountPaused'Status.AccountPausedAccount exists but is paused by the seller.Show the error message. The seller resumes the account from the dashboard.
ServerUnreachableStatus::ServerUnreachable'ServerUnreachable'Status.ServerUnreachableTCP/handshake failed. JS and Python return this from releases after 1.0.3; on 1.0.3 and earlier a network failure arrives as WrongCredentials with the cause in error_message.Transient. Back off and retry. Do not show a fatal dialog.
ErrorStatus::Error'Error'Status.ErrorGeneric catch-all. Inspect GetErrorMessage().Show the message and offer a retry path.

Method map

Account and License namespaces
MethodC++JavaScriptPythonReturns
Login (license, key)License::Login(key)License.Login(key)License.Login(key)bool
Login (license, user)License::Login(u, p) // overloadLicense.LoginUser(u, p)License.LoginUser(u, p)bool
Register (license)License::Register(key, u, p)License.Register(key, u, p)License.Register(key, u, p)bool
Login (account)Account::Login(u, p)Account.Login(u, p)Account.Login(u, p)LoginResult
Register (account)Account::Register(u, p, email)Account.Register(u, p, email)Account.Register(u, p, email)bool
Submit 8-digit codeAccount::SubmitVerification(code)Account.SubmitVerification(code)Account.SubmitVerification(code)bool
Resend codeAccount::ResendVerification()Account.ResendVerification()Account.ResendVerification()bool
Confirm emailAccount::ConfirmEmail(code)Account.ConfirmEmail(code)Account.ConfirmEmail(code)bool
Has pending emailAccount::HasPendingEmailConfirm()Account.HasPendingEmailConfirm()Account.HasPendingEmailConfirm()bool
Redeem key onto accountAccount::Redeem(key)Account.Redeem(key)Account.Redeem(key)bool
Request password resetAccount::RequestPasswordReset(id)Account.RequestPasswordReset(id)Account.RequestPasswordReset(id)bool (always true)
Complete password resetAccount::CompletePasswordReset(code, new_pass)Account.CompletePasswordReset(code, new_pass)Account.CompletePasswordReset(code, new_pass)bool

Win32 dialogs (C++ only)

The C++ SDK ships windows for every flow that needs one. JavaScript and Python have none: draw your own form and call the same functions.

  • Atlas::License::Dialog::Login() / Register()
  • Atlas::Account::Dialog::Login() / Register()
  • Atlas::Account::Dialog::VerifyCode()
  • Atlas::Account::Dialog::ConfirmEmail()
  • Atlas::Account::Dialog::ResetPassword()