Skip to main content
All authenticated endpoints need a JWT. The SDK handles acquisition, storage, and refresh for you — in most apps you call LoginAsync once and forget about it.

Simple login

using STX.Sdk.Services;

var login = serviceProvider.GetRequiredService<STXLoginService>();

var user = await login.LoginAsync(
    email:    "you@example.com",
    password: "your-password");

Console.WriteLine($"Logged in as {user.UserId}");
LoginAsync returns STXUserDataCollection with:
Field
TokenBearer token for subsequent GraphQL calls
RefreshTokenUsed by STXTokenService.RefreshTokenAsync
UserId, UserUid, SessionIdIdentifiers for channel subscriptions
CurrentLoginAtLogin timestamp
PromptTncAcceptancetrue if the user still needs to accept new T&Cs
The token is automatically cached in STXUserStorage and attached to every subsequent GraphQL call. You never need to pass it manually.

Two-factor authentication

If the account has 2FA enabled, the initial LoginAsync returns partial user data — authentication isn’t complete until you confirm the code:
var partial = await login.LoginAsync(email, password);

if (partial.PromptTwoFactor)
{
    Console.Write("2FA code: ");
    var code = Console.ReadLine();

    var tokenService = serviceProvider.GetRequiredService<STXTokenService>();
    var confirmed = await tokenService.Confirm2FAAsync(
        code:      code!,
        sessionId: partial.SessionId,
        email:     email);

    Console.WriteLine($"Authenticated: {confirmed.UserId}");
}
The 2FA flow is backed by the same GraphQL confirm2Fa mutation the Python SDK and other clients use.

Keep the session alive

Long-running bots should refresh the token before it expires. Pass keepSessionAlive: true and the SDK’s STXSessionBackgroundService will refresh in the background:
await login.LoginAsync(
    email,
    password,
    keepSessionAlive: true);
Requirements:
  • The service provider must be hosted under Host.CreateDefaultBuilder(...) so background services actually run.
  • The credentials stay in memory in STXUserStorage so the background service can re-login if the refresh token itself expires.
If you’d rather manage the refresh manually:
var tokenService = serviceProvider.GetRequiredService<STXTokenService>();

try
{
    var refreshed = await tokenService.RefreshTokenAsync();
}
catch (STXSessionExpiredException)
{
    // Token and refresh token both expired — re-login.
    await login.LoginAsync(email, password);
}

Accept terms & conditions

If PromptTncAcceptance is true, subsequent authenticated calls will fail until the user accepts. Pass checkTermsAndConditions: true to have the SDK surface the latest T&Cs for your app to display:
await login.LoginAsync(
    email,
    password,
    checkTermsAndConditions: true);
Programmatic accept (use only if the user has explicitly agreed in your UI):
var tnc = serviceProvider.GetRequiredService<STXTermsAndConditionsService>();
var latest = await tnc.GetTermsAndConditionsAsync();
await tnc.AcceptTermsAndConditionsAsync(latest.Version);

Logout

No server-side logout call is required — just drop the token:
var storage = serviceProvider.GetRequiredService<STXUserStorage>();
storage.Clear();
This also stops any active background services and closes websocket channels on their next tick.

Errors

ExceptionCause
STXWrongCredentialsExceptionBad email/password
STXSessionExpiredExceptionToken and refresh token both expired — re-login
STXGeoComplyExceptionGeo-compliance check failed; user is outside a permitted jurisdiction
See Errors & retries for the full list and recovery patterns.