Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.authforge.cc/llms.txt

Use this file to discover all available pages before exploring further.

This guide shows how to bind licenses to an external identity (Telegram/Discord user ID, account ID, etc.) by setting SDK HWID override fields.

When to use this

Use HWID override when device fingerprinting is the wrong abstraction:
  • bot users
  • web users
  • cloud workers
  • multi-tenant service identities
For desktop apps, use default machine HWID behavior.

Flow

  1. User requests access in your app/bot.
  2. Prompt for a license key.
  3. Build a stable identity string (for example tg:123456789).
  4. Initialize SDK with HWID override set to that identity.
  5. Call validateLicense() / validate_license / ValidateLicense (or login() if you want a long-lived session and heartbeats).
  6. Allow features only after success.
Prefer validate-license APIs for stateless or per-request checks (API gateways, bots, cron): they run the same /auth/validate flow and signature verification as login without starting heartbeat threads or timers.

Identity format and rules

  • Include a provider prefix (tg:, discord:, user:).
  • Use immutable IDs (platform numeric user IDs), not usernames.
  • Keep values under AuthForge limits (short strings are best).

SDK examples

Node

const client = new AuthForgeClient({
  appId: process.env.AUTHFORGE_APP_ID,
  appSecret: process.env.AUTHFORGE_APP_SECRET,
  publicKey: process.env.AUTHFORGE_PUBLIC_KEY,
  heartbeatMode: "SERVER",
  hwidOverride: `tg:${telegramUserId}`,
});

Python

client = AuthForgeClient(
    app_id=APP_ID,
    app_secret=APP_SECRET,
    public_key=PUBLIC_KEY,
    heartbeat_mode="SERVER",
    hwid_override=f"discord:{discord_user_id}",
)

Go

client, err := authforge.New(authforge.Config{
    AppID:         appID,
    AppSecret:     appSecret,
    PublicKey:     publicKey,
    HeartbeatMode: "server",
    HWIDOverride:  fmt.Sprintf("tg:%d", telegramUserID),
})

C#

var client = new AuthForgeClient(
    appId: appId,
    appSecret: appSecret,
    publicKey: publicKey,
    heartbeatMode: "SERVER",
    hwidOverride: $"discord:{discordUserId}"
);

Rust

let client = AuthForgeClient::new(AuthForgeConfig {
    app_id: app_id.into(),
    app_secret: app_secret.into(),
    public_key: public_key.into(),
    heartbeat_mode: HeartbeatMode::Server,
    hwid_override: Some(format!("tg:{telegram_user_id}")),
    ..Default::default()
});

C++

authforge::AuthForgeClient client(
    appId,
    appSecret,
    publicKey,
    "SERVER",
    900,
    authforge::AuthForgeClient::kDefaultApiBaseUrl,
    onFailure,
    15,
    0,
    "tg:" + std::to_string(telegramUserId)
);

Operational tips

  • Set sensible maxHwidSlots for your use case (often 1 for user-bound bots).
  • Provide a support flow to reset bindings when users migrate accounts.
  • If abuse is expected, combine with IP/HWID security lists and command rate limits.