Skip to content
Docs
Sign inGet started
Updated Oct 03, 2026

Account Namespace

Sign in with a username and password. Optional emailed codes, password reset, and adding keys to an account.

Use this when

  • Your users make their own username and password and keep one account for as long as they use your app. Use Login.
  • Customers add time later by entering a new key. Use Redeem. The days, level and entitlements stack on the account.
  • Customers only type a key? Use License instead.

Sign in

Login returns a result, not true or false. Read status first. Ok means you are signed in. NeedsVerification means an 8-digit code was emailed: ask the user for it, then call SubmitVerification(code).

Sign in
auto r = Atlas::Account::Login("marcus.reyes", "Wp7#kLm2vQ");
if (r.status == Atlas::Account::LoginResult::Status::Ok) {
// r.expiry, r.level, r.note populated. Session is live.
}
else if (r.status == Atlas::Account::LoginResult::Status::NeedsVerification) {
// r.masked_email, r.sign_in_ip, r.sign_in_country populated.
Atlas::Account::SubmitVerification(code); // 8-digit code from email
}
C++
Or one call - built-in Win32 dialog
// One call - collects creds, opens verify dialog if the server asks,
// opens the confirm-email dialog if needed. Same protocol, zero UI code.
bool authed = Atlas::Account::Dialog::Login();
LoginResult fields
FieldTypeDescriptionPopulated when
statusStatusSign-in outcome. Branch on this before reading any other field.always
user_idintNumeric row id assigned by the auth server.Ok only
expirystringA DD-MM-YYYY date. When there is no expiry: "" in C++, "Never" in JS and Python (the same string as GetExpiry()).Ok only
levelintAccess level for the signed-in user.Ok only
notestringAdmin-set note. When there is none: "" in C++, "None" in JS and Python (the same string as GetNote()).Ok only
masked_emailstringe.g. "m***[email protected]" - for the "we sent a code to X" UI.NeedsVerification only
sign_in_ipstringIP the server saw for the sign-in attempt.NeedsVerification only
sign_in_countrystringISO-2 country code.NeedsVerification only
error_messagestringHuman-readable reason. Populated on any non-Ok status.non-Ok

Status values

StatusC++JSPythonMeaningWhat to do
OkStatus::Ok'Ok'Status.OkSigned in. 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.NeedsVerificationServer emailed an 8-digit code. masked_email, sign_in_ip, sign_in_country populated.Show the code-entry UI and call SubmitVerification.
BannedStatus::Banned'Banned'Status.BannedAccount 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 is paused by the seller.Show the error message. The seller resumes the account from the dashboard.
ServerUnreachableStatus::ServerUnreachable'ServerUnreachable'Status.ServerUnreachableTCP or handshake failed.Transient. Back off and retry. Do not show a fatal dialog.
ErrorStatus::Error'Error'Status.ErrorGeneric catch-all.Inspect Data::GetErrorMessage(); show the user and offer a retry path.

Verification challenge

The code is 8 digits, single-use, bound to the IP and masked email that triggered the challenge. The server rate-limits ResendVerification to one code per 60 s.

  • SubmitVerification(code) - finish the pending sign-in. Returns true on success.
  • ResendVerification() - ask the server to email a new code. 60 s server-side cooldown.

Register

Email is optional - but required for password reset. If supplied, the account stays unverified until ConfirmEmail succeeds. Register does not sign in. Usernames and emails are unique per app, ignoring case.

// Create an account. Does NOT sign in.
if (!Atlas::Account::Register("marcus.reyes", "Wp7#kLm2vQ", "[email protected]")) {
std::cout << Atlas::Data::GetErrorMessage();
return 1;
}
// If email was supplied, the SDK is holding a confirm challenge.
// HasPendingEmailConfirm() returns true until ConfirmEmail() succeeds.
if (Atlas::Account::HasPendingEmailConfirm()) {
Atlas::Account::ConfirmEmail(code); // 8-digit code from email
}

Email confirm (post-Register)

After Register(u, p, email) the SDK holds a separate confirm challenge, consumed by ConfirmEmail(code). HasPendingEmailConfirm() returns true until it succeeds.

Password reset

Two calls. RequestPasswordReset(identifier) asks the server to email an 8-digit code - identifier can be the username or the email. CompletePasswordReset(code, new_password) finishes.

// identifier = username OR email. Server always returns OK
// (anti-enumeration - never leaks whether the identifier matched).
Atlas::Account::RequestPasswordReset("marcus.reyes");
// User reads the 8-digit code from email.
bool ok = Atlas::Account::CompletePasswordReset(code, "new-password");
// true when the password was changed. Sign in with the new password.

RequestPasswordReset returns true whether or not the identifier matches a real user. Anti-enumeration - the server never leaks whether it matched. It returns false only when the request itself fails (SDK not started, server unreachable).

Redeem a license key

Adds a license key to the signed-in account and uses the key up. Three things move across: its days are added to the account's expiry, its level replaces the account's if it is higher, and its entitlements are added (credits add to what the account holds, a feature keeps the later expiry, and a grant with a duration starts counting at redemption). It returns false if the key is unknown, paused, already used or has no days: read GetErrorMessage(). Customers who sign in with a license key never redeem. They use the new key.

// After Login, apply a license key to the account.
if (Atlas::Account::Redeem("ATLAS-A9F2K-4RMXM")) {
// The key's days were added to the expiry; level raised if the key's tier is higher.
}

Change email

Two calls, for an account that signed in with a password. RequestEmailChange(password, new_email) checks the password and emails an 8-digit code to the new address. ConfirmEmailChange(code) writes the new address, marked verified. The old address gets a notice that the email changed.

// Signed in with a password (Account::Login). The code goes to the new address.
if (!Atlas::Account::RequestEmailChange("Wp7#kLm2vQ", "[email protected]")) {
// Atlas::Data::GetErrorMessage() says why.
}
// The user reads the 8-digit code from the new address.
if (Atlas::Account::ConfirmEmailChange(code)) {
// The account now uses [email protected], marked verified.
}

The code expires after 10 minutes, and five wrong codes end the request. Three requests can be open at once, and a new code can be asked for once a minute. A new address that another account in the app already uses is refused.

Delete account

Two calls. RequestAccountDeletion(password) checks the password and emails an 8-digit code to the address on the account. ConfirmAccountDeletion(code) deletes the account and ends every session of it, or schedules the deletion when the developer has set a grace period. The license key is not changed.

// Checks the password, then emails an 8-digit code to the address on the account.
if (!Atlas::Account::RequestAccountDeletion("Wp7#kLm2vQ")) {
// Atlas::Data::GetErrorMessage() says why. An account with no email cannot delete itself.
}
if (Atlas::Account::ConfirmAccountDeletion(code)) {
// Deleted. Every session of the account has ended. Close the program.
}

An account with no email on file cannot delete itself. The developer removes it from the dashboard. Deleting an account removes its trusted devices, redemptions, entitlement grants and reset codes. The logs the app keeps follow the app's log retention settings. With a grace period (Settings, Application, Self-service resets), the account is scheduled for deletion instead of removed. Its sessions end, the customer is emailed the date when the app's deletion email is on, and signing in again before that date keeps the account.

Trusted devices

A device joins the account's trusted list after a sign-in the app's account policy accepted. ListDevices() shows each one. RevokeDevice(id) forgets its trust, and SignOutOtherDevices() ends every other session of the account.

// Every device the account has trusted, newest sign-in first.
auto devices = Atlas::Account::ListDevices();
for (const auto& d : devices) {
// d.id, d.trusted_at and d.last_seen_at are Unix seconds. d.last_seen_ip is the address it last signed in from.
// d.is_this_device is true for the device this program runs on.
}
// Forget a device's trust. Its next sign-in is checked again under the app's account policy.
Atlas::Account::RevokeDevice(devices[1].id);
// Ends every other session of this account. Returns how many, or -1 on failure.
int ended = Atlas::Account::SignOutOtherDevices();

Each device has id, trusted_at, last_seen_at (Unix seconds), last_seen_ip and is_this_device. The list holds up to 50 devices. Signing out other sessions takes effect on their next poll, within a few seconds.

Reset this machine

When the app binds accounts to a machine, two calls clear that binding. Neither changes the password. Signed in, ResetWhileSignedIn() clears it and ends the session. Before sign-in, RequestResetCode(identifier) emails an 8-digit code and ConfirmReset(identifier, code) clears it.

// Signed in with a password. Clears this machine's binding and ends the session.
if (Atlas::Account::ResetWhileSignedIn()) {
// Sign in again on this machine. It binds to this machine on that sign-in.
}
// Before sign-in. The 8-digit code goes to the account's verified email. The password does not change.
Atlas::Account::RequestResetCode("marcus.reyes");
// Clears this machine's binding for the account.
if (Atlas::Account::ConfirmReset("marcus.reyes", code)) {
// Sign in on this machine again.
}

Sign-in windows (C++ only)

The C++ library can show these windows for you. Each call blocks until the user closes it. JavaScript and Python have none: draw your own form and call the functions above.

  • Atlas::Account::Dialog::Login() - full flow: creds dialog → sign in → verify dialog if needed.
  • Atlas::Account::Dialog::Login(u, p) - creds pre-collected; opens verify dialog if the server requires it.
  • Atlas::Account::Dialog::Register() - register dialog → create account. Opens the confirm-code dialog automatically when an email was supplied.
  • Atlas::Account::Dialog::VerifyCode() - 8-digit code dialog for the pending sign-in verify challenge.
  • Atlas::Account::Dialog::ConfirmEmail() - 8-digit code dialog for the pending registration email-confirm.
  • Atlas::Account::Dialog::ResetPassword() - full password-reset flow: request-code → email → complete-reset dialogs.
Was this page useful?