Skip to main content
Discord’s backend cross-references dozens of signals: user-agent strings, locale, timezone, installation UUIDs, client build numbers, and more, to distinguish legitimate browser sessions from automated ones. alterself’s SpoofEngine generates a self-consistent fingerprint for every token and injects it into every gateway connection and HTTP request automatically. You rarely need to touch it directly, but understanding how it works helps you debug unexpected authentication failures and tailor the fingerprint when needed.

How Identity Is Seeded

Rather than generating a random fingerprint on every run, SpoofEngine derives its values deterministically from a hash of your token. This seeded approach means the same token always produces the same locale, timezone, and installation UUIDs, making your sessions look like a stable, returning browser to Discord’s systems.
1

Token hash

When you call alterself.Client(token=...), the engine MD5-hashes your token and uses the digest as the seed for an internal RNG.
2

Profile generation

The seeded RNG picks a consistent locale (e.g. en-US), timezone (e.g. America/New_York), and a set of stable UUIDs for the installation and session identifiers.
3

READY rotation

When Discord dispatches the READY event, the engine rotates the session-level UUIDs while keeping the token-bound values (locale, timezone, installation ID) stable, matching how a real browser behaves across page refreshes.
The same token always produces the same fingerprint across restarts. If you switch tokens, you get a completely different but equally stable fingerprint for that token.

Chrome Version Resolution

alterself needs a realistic Chrome version string for the User-Agent header and X-Super-Properties. It resolves the version through a layered strategy:
  1. Live fetch: queries Google’s versionhistory.googleapis.com API for the latest stable Chrome release.
  2. Disk cache: if the API is unreachable, reads a previously cached version from disk.
  3. Hardcoded fallback: if both of the above fail, uses "136" as a safe default.
This means your bot always presents a plausible, up-to-date Chrome version without requiring you to maintain it manually.

Build Number Resolution

Discord’s X-Super-Properties header must contain the correct client build number or the gateway will reject the connection. alterself resolves it through its own layered strategy:
  1. Live scrape: fetches Discord’s login page and extracts the build number from the bundled JavaScript.
  2. Memory cache: caches the scraped value in memory for one hour to avoid repeated scrapes.
  3. Disk cache: persists the value to disk so it survives restarts.
  4. Hardcoded fallback: if all of the above fail, uses 612808.

Manual Build Refresh

If you suspect the cached build number is stale (for example, after a Discord client update), you can force a fresh scrape:
Call this before bot.run() or inside an on_ready handler. The engine will scrape Discord’s login page immediately and update both the memory and disk caches.

X-Super-Properties

Every HTTP request and the gateway IDENTIFY payload includes an X-Super-Properties header. Discord uses it to verify that your client looks like a real browser. alterself constructs it automatically from the generated profile. The header is a base-64-encoded JSON object containing fields such as: You never need to set these fields manually. The engine serialises and encodes the header for every request.

App State Tracking

Discord expects the client to report whether its window is currently focused. alterself tracks this with set_state(), which updates the client_app_state field sent in presence updates.
You might call this inside a command handler to simulate the user switching away from Discord while a long task runs.

Spoof Info Command

This command prints the active fingerprint at runtime. It is useful for verifying that the engine is working correctly or for debugging authentication errors.
Invoke it with .spoof (or .whoami) to see the exact values being sent to Discord on every request.