API reference
Client API
Your software talks to SAUTH through one URL. The type field says what to do.
API URL
POST https://<your-sauth-domain>/api/v1/clientYour App ID, public key and the exact URL are on the application's Overview page in the dashboard.
Request
Send JSON. Every request contains:
type— the operation (table below).nonce— 16–64 random characters, never reused. A repeated nonce is rejected withREQUEST_REPLAYED.timestamp— current Unix time in milliseconds, within 60 seconds of server time (otherwiseREQUEST_EXPIRED).sessionToken— returned byinit; required for every other type.
If you prefer, nonce, timestamp and sessionToken can be sent as the X-Sauth-Nonce, X-Sauth-Timestamp and Authorization: Bearer headers instead.
POST https://<your-sauth-domain>/api/v1/client
Content-Type: application/json
{
"type": "license",
"sessionToken": "<from init>",
"key": "SAUTH-XXXXX-XXXXX-XXXXX-XXXXX",
"hwid": "<device id>",
"nonce": "8f1c2b7e9a4d4f0c9b6e1a2d3c4b5a69",
"timestamp": 1793540000000
}| type | Fields | What it does |
|---|---|---|
| init | appId, version, hwid?, hash? | Open a session. Returns sessionToken. |
| license | key, hwid | Sign in with a license key. |
| login | username, password, hwid | Sign in with a user account. |
| register | username, password, key, hwid, email? | Create a user by redeeming an unused key. |
| validate | — | Check the session is still valid. |
| heartbeat | — | Keep the session alive; ends it if access was revoked. |
| variables | — | Values set in the dashboard for this application. |
| info | — | Application name, latest version, maintenance flag. |
| session | — | Current session, user and license details. |
| refresh | — | Rotate the session token (the old one stops working). |
| logout | — | End the session. |
| hwid-reset | reason? | Request a device reset. |
Verifying responses
Successful responses carry X-Sauth-Signature, X-Sauth-Timestamp and X-Sauth-Key-Id. Verify the signature with your application's Ed25519 public key over the exact string <X-Sauth-Timestamp>.<your nonce>.<raw response body>. Treat any response that fails verification — including error responses, which are unsigned — as a failure. This stops fake servers from "approving" a cracked copy of your software.
Errors
Failures return a non-2xx status with this body. Branch on code, which never changes; show message to the user (you can customise messages per application in the dashboard).
{
"error": {
"code": "LICENSE_EXPIRED",
"message": "This license has expired.",
"requestId": "0b6a5a52-7a51-4c8e-9a3b-6ab0f1c1f2de"
}
}| Status | Typical codes |
|---|---|
| 401 | LICENSE_INVALID, USER_INVALID_CREDENTIALS, SESSION_INVALID, REQUEST_REPLAYED |
| 403 | LICENSE_EXPIRED, LICENSE_REVOKED, HWID_MISMATCH, USER_BANNED, APP_DISABLED |
| 409 | LICENSE_ALREADY_USED, USER_ALREADY_EXISTS |
| 422 | VALIDATION_FAILED |
| 426 | APP_VERSION_OUTDATED, APP_VERSION_BLOCKED |
| 429 | RATE_LIMITED |
| 503 | APP_MAINTENANCE |