Webhooks
Push every auth event to your own server as signed JSON, with automatic retries and a delivery log. Discord channels are supported alongside.
What you receive
One POST per event, Content-Type: application/json. The event name is the server's log type.
JSON
{ "id": "6f1c0b7e-9c3a-4d52-8d0e-5a2f4f6b9a10", "event": "DENY", "created_at": "2026-10-03T09:41:07.512Z", "application_id": 77, "data": { "log_id": 48213, "type": "DENY", "message": "HWID mismatch - lock violation.", "license_key": "ATLAS-7F2C-91B8-E04D", "hwid": "9F3A61C27D08", "ip": "203.0.113.24", "timestamp": "2026-10-03T09:41:07.498Z" }}Events
| SUCCESS | A sign-in was accepted. | |
| DENY | A sign-in was refused. message carries the server's reason. | |
| BAN | An alert rule banned a license, machine or address. | |
| DISCONNECT | A session ended. | |
| WARN | Something worth a look that was not refused. | |
| ERROR | The server hit an error. | |
| ADMIN | An admin action on a session or license. | |
| LOG | A message your client sent with SubmitLog. | |
| ping | The Test button. |
Headers
| X-Atlas-Event | The event name. | |
| X-Atlas-Delivery | A delivery id, the same on every retry. Store it to ignore duplicates. | |
| X-Atlas-Timestamp | Unix seconds when the attempt was made. | |
| X-Atlas-Signature | v1= then the hex HMAC-SHA256 of timestamp + "." + body, keyed with your secret. |
Verify the signature
const crypto = require('crypto'); // rawBody must be the request body exactly as received, before any JSON parsing.function verify(rawBody, headers, secret) { const ts = headers['x-atlas-timestamp']; if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // reject replays const want = 'v1=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex'); const got = headers['x-atlas-signature'] || ''; return got.length === want.length && crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want));}Retries and limits
- Answer with any 2xx within 6 seconds. Anything else, or no answer, is retried after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours, then marked failed. Redirects are not followed.
- The log keeps the last 14 days per webhook, with the status code, time taken and attempt count. Send again re-queues a delivery.
- A webhook that fails 20 deliveries in a row is switched off and shows why. Turning it back on resets the count.
- https only, public addresses only. Atlas checks the address again when it connects, so a name that points at a private network is refused.
Was this page useful?