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
- User requests access in your app/bot.
- Prompt for a license key.
- Build a stable identity string (for example
tg:123456789). - Initialize SDK with HWID override set to that identity.
- Call
validateLicense()/validate_license/ValidateLicense(orlogin()if you want a long-lived session and heartbeats). - 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
maxHwidSlotsfor your use case (often1for 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.