Integration reference

Licence API

The endpoints your daemon talks to. This is the contract implemented by src/license.cpp in the SentinelX repository, served by this portal.

Shared-secret authentication. Every call must carry the x-api-secret header. Keep it out of version control. If it leaks, rotating it invalidates every daemon still built with the old value.

Base URL and authentication

# Base URL, hardcoded in src/license.cpp API_BASE = "https://license.sentinelx.me" # Headers sent on every request Content-Type: application/json Accept: application/json x-api-secret: <shared secret>

Requests must arrive over HTTPS. The daemon verifies the server certificate, so a self-signed endpoint will fail validation.

Rate limits

Per source IP: 30 requests per minute and 500 per day. A node revalidating once every 24 hours produces one call per day, so normal operation stays far below the ceiling and a whole fleet fits comfortably.

POST /api/validate

Called once at activation, then again on every revalidation cycle. This is the call that decides whether the daemon is allowed to keep running.

// Request POST https://license.sentinelx.me/api/validate { "code": "SNTX-XXXX-XXXX-XXXX", "machine_id": "64-character sha256 hex" } // 200 — accepted { "valid": true, "message": "License valid and activated.", "code": "SNTX-XXXX-XXXX-XXXX", "plan": "standard", "status": "active", "expires_at": "2026-11-06 21:11:59", "machine_id": "aaaa...9999", "slots": "1/1" } // 200 — refused (message is shown verbatim in the terminal) { "valid": false, "message": "This license is already bound to 1 node(s). Run /sentinelx deactivate on the old node first." } // 401 — bad or unconfigured secret { "valid": false, "message": "Invalid or unconfigured API secret." }

Rejection reasons

MessageCause
Voucher code not found. No such voucher, or it has been deleted.
Invalid voucher code format. Not SNTX-XXXX-XXXX-XXXX.
License revoked: <reason> Revoked by an operator. The reason is passed through to you.
License expired on <date>. The expiry date on the voucher has passed.
This license is already bound to N node(s). Binding limit reached. Deactivate the old node first.
Voucher code or machine ID is missing. Request body incomplete.
Rejections count towards the three-attempt activation lockout. A network failure also stops activation from succeeding, so verify a code on the Check Licence page before you type it in.

POST /api/revalidate

An explicit alias for the same handler, provided so integrations can express intent clearly. Behaviour and response shape are identical to /api/validate; the daemon itself uses /api/validate for both activation and revalidation.

POST /api/deactivate

Releases the node binding so the voucher can be activated elsewhere. Triggered by the /sentinelx deactivate bot command. The response body is advisory: the daemon removes its local licence file regardless.

POST https://license.sentinelx.me/api/deactivate { "code": "SNTX-XXXX-XXXX-XXXX", "machine_id": "64-character sha256 hex" } // 200 { "ok": true, "message": "License released. You can activate it on the new node." }

GET /api/status

Health probe for uptime monitoring. Also requires the secret header.

GET https://license.sentinelx.me/api/status { "ok": true, "service": "sentinelx-license-api", "server_time": "2026-10-08 04:11:59", "licenses_total": 12, "licenses_active": 10, "events_last_24h": 34, "daemon_secret_configured": true }

Machine fingerprint

The daemon derives a stable machine identity and sends it as machine_id: the lowercase hex SHA-256 of the concatenation of, in this exact order,

  1. the first line of the system machine identifier, falling back to the D-Bus machine identifier when that file is empty;
  2. the MAC address of the first non-loopback, non-zero network interface;
  3. the system hostname.

The components are concatenated with no separator before hashing, so the result is 64 hexadecimal characters. The first 16 are shown during activation, which is what we use to match a node to a voucher when you contact support.

Re-imaging a node or changing its hostname changes the fingerprint and therefore counts as a different machine. Deactivate on the old host before migrating, or the voucher will appear bound to a node that no longer exists.

Voucher format

Codes are issued as SNTX-XXXX-XXXX-XXXX. The character set excludes 0, O, 1 and I to avoid transcription errors. Input is normalised on our side, so pasting sntxabcd2345 or SNTX ABCD 2345 resolves to the same voucher.

Verifying our responses

The reference daemon uses a minimal hand-written JSON reader rather than a full parser. If you write your own client, keep two rules in mind so it reads our responses the same way:

  • the boolean is emitted as true or false, never as a string;
  • message is always present on a rejection and is the exact text a user sees, so forward it rather than replacing it with your own wording.

Need something else?

Running your own portal, building a deployment tool, or pointing a fleet at a different endpoint: tell us via the contact form and include your node count.