Integration Guide
How to add Mystic license checks to your own application.
Getting Set Up
No signup page for app IDs — just DM @decamped on Discord and you'll get one.
How It Works
- Open a session when your app starts.
- First run on a new device, the user confirms once in a browser — after that it's remembered.
- Register with a key, or log in if they've already got an account.
- Keep checking in while it runs, so a ban or expired key takes effect right away.
Code Samples
Pick a language for a full example.
import hashlib, hmac, json, os, time, urllib.request, webbrowser
BASE_URL = "https://mysticbin.xyz"
APP_ID = "app_xxxxxxxxxxxxxxxx"
def sha256_hex(s: str) -> str:
return hashlib.sha256(s.encode()).hexdigest()
def call(path, body, session_id="none", session_token=None):
payload = json.dumps(body).encode()
headers = {"Content-Type": "application/json", "X-App-Id": APP_ID}
if session_token:
ts = str(int(time.time()))
nonce = os.urandom(16).hex()
canonical = "\n".join(["POST", path, ts, nonce, session_id, payload.decode()])
key = sha256_hex(session_token)
sig = hmac.new(key.encode(), canonical.encode(), hashlib.sha256).hexdigest()
headers.update({"X-Session-Id": session_id, "X-Timestamp": ts,
"X-Nonce": nonce, "X-Signature": sig})
req = urllib.request.Request(BASE_URL + path, data=payload, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())
hwid = sha256_hex("this-machine")
# open a session
init = call("/session/init", {"hwid": hwid})
session_id, session_token = init["session_id"], init["session_token"]
# new device - confirm once in a browser and wait
if not init["browser_verified"]:
webbrowser.open(init["verify_url"])
while True:
poll = call("/session/browser-verified",
{"challenge_token": init["challenge_token"]}, session_id, session_token)
if poll["verified"]:
break
time.sleep(2)
# solve the captcha, log in
cap = json.loads(urllib.request.urlopen(BASE_URL + "/auth/captcha").read())
a, b = (int(x) for x in cap["question"].split(" + "))
login = call("/auth/login", {
"username": "player1", "password_hash": sha256_hex("their-password"), "hwid": hwid,
"captcha_token": cap["token"], "captcha_answer": a + b,
}, session_id, session_token)
user_token = login["user_token"]
# heartbeat, keep this running
call("/auth/validate", {"user_token": user_token, "hwid": hwid}, session_id, session_token)Client Endpoints
Calls your application makes directly.
| Endpoint | Purpose | Browser Verified |
|---|---|---|
POST /session/init | Open a session for this run; pass a hwid to enable device trust | No |
POST /session/browser-verified | Poll the one-time browser confirmation result | No |
GET /auth/captcha | Fetch a simple math captcha for login/register | No |
POST /auth/register | Redeem a license key and create an account | Yes |
POST /auth/login | Log in on the current device | Yes |
POST /auth/validate | Heartbeat: extend the session, confirm the license is still valid | No |
POST /auth/logout | End the current session | No |
POST /auth/upgrade | Redeem another key onto the current account | Yes |
POST /auth/change-username | Rename the current account | Yes |
POST /me/account | Read the current user/license/device summary | No |
POST /me/setvar | Set the current user's saved variable | Yes |
POST /me/getvar | Read the current user's saved variable | Yes |
POST /app/var | Read a global app variable | No |
POST /app/stats | Read public app stats | No |
POST /files/fetch | Download a protected file/blob | Yes |
