AppHub Tether
Verify
License check — verifies whether the connected AppHub account is licensed to run your app. Returns a cryptographically signed response when a nonce is provided.
GET
http://127.0.0.1:7420/verify
This endpoint requires AppHub Store to be running on your machine. The live tester calls your local AppHub instance directly.
Query parameters
| Parameter | Required | Description |
|---|---|---|
| appid | required | Your app's packagename as registered on AppHub (e.g. com.studio.mygame) |
| nonce | recommended | Random hex string (16–64 chars). Required for signature verification — always include it for paid apps. |
Test this endpoint
Headers
Query Parameters
Success response 200
{
"ok": true,
"reason": "licensed",
"appid": "com.studio.mygame",
"ts": 1747012345678,
"nonce": "a3f7b2c9d1e4f508",
"sig": "3a7b4c9f1d2e5a8b..."
}
Response fields
| Field | Type | Description |
|---|---|---|
| ok | boolean | true = authorized to run. false = should not run. |
| reason | string | Explanation code (see table below) |
| appid | string | Echoed packagename |
| ts | number | Unix timestamp (ms) when AppHub generated this response. Verify within 60 seconds. |
| nonce | string | The nonce you sent, echoed back. Verify it matches exactly. |
| sig | string | HMAC-SHA256 hex digest. Present when nonce was sent and app is paid. |
| cached | boolean | true if the result came from the local cache |
| offline | boolean | true if AppHub could not reach the network (stale cache used) |
Reason codes
| Reason | ok | Meaning |
|---|---|---|
free | true | App is free — no account required. Skip signature check. |
licensed | true | Account owns the app |
no_account | false | App is paid but no account is connected in the launcher |
no_license | false | Account connected but does not own this app |
offline | false | Could not reach AppHub API and no cached result available |
missing_appid | false | The appid parameter was not provided |
internal_error | false | Unexpected error inside AppHub Tether |
Signature verification
The sig field is HMAC-SHA256(itemKey, message) encoded as lowercase hex, where:
message = "${ok ? 1 : 0}:${appid}:${ts}:${nonce}"
Your code must verify all three independently:
1. response.nonce === nonce_you_sent
2. abs(Date.now() - response.ts) < 60_000
3. HMAC-SHA256(itemKey, message) === response.sig
If any check fails, treat the response as unauthorized. See the AppHub Tether guide for full code examples.