Base URL
POST /validate
Checks a key and claims (or refreshes) this server’s license slot. Call on boot and periodically as a heartbeat.| Body field | Required | Description |
|---|---|---|
pluginId | yes | Your 8-character NMKey plugin id (Licensing tab). |
key | yes | The buyer’s NMK-… license key. |
fingerprint | yes | A stable per-server hash — this is the unit the seat lock counts against. |
nonce | yes | A fresh random value per request; echoed into the signature (replay defence). |
hostname | no | Display name for the studio’s key-management UI. |
200 — the verdict is in the body:
status | Meaning |
|---|---|
valid | Run. This server holds a seat (ok: true, only for this status). |
max_servers | The key is already live on its maximum number of other servers. |
expired | Past the key’s expiresAt. |
disabled | Revoked / disabled by the studio. |
not_found | No such license for this plugin. |
invalid_format | Malformed pluginId / key, or missing required fields. |
valid responses include a human-readable message.
Verifying the signature
When signing is enabled,signature is a base64url Ed25519 signature over this pipe-delimited canonical string, which you rebuild from values you already know plus the returned status / issuedAt:
GET /public-key. Embed that public key in your plugin rather than fetching it at runtime from the same host you’re distrusting — otherwise a rerouted API could serve both a fake “valid” and a matching fake key.
POST /release
Frees this server’s seat on graceful shutdown, so the buyer can move hosts instantly instead of waiting for the seat to go stale.{ "ok": true } when a seat was released.
GET /public-key
Returns the Ed25519 public key as SPKI PEM (text/plain). 404 when response signing is not enabled on the server.
GET /health
Reachability check plus integration hints:heartbeatMs is the recommended re-validation interval; a seat that hasn’t validated for staleAfterMs is considered stale and can be claimed by another server.