Integration
Wire a product to Spiky in three calls.
Authentication
Every product request carries the product API key in x-api-key. Panel routes use an operator session instead.
Activate
Call once per machine. The response is a signed entitlement; store the license key and fingerprint locally.
curl -X POST https://license.vertalt.my.id/api/v1/activate \
-H "content-type: application/json" \
-H "x-api-key: spky_live_..." \
-d '{
"licenseKey": "SPKY-XXXX-XXXX-XXXX-XXXX-XXXX",
"fingerprint": "sha256-of-machine-hwid",
"serverId": "srv-eu-01",
"serverName": "eu-01.xcord.example",
"version": "1.75"
}'{
"ok": true,
"data": {
"allowRuntime": true,
"reason": "active",
"payload": { "v": 1, "productSlug": "xcord", "plugins": [...] },
"signature": "…base64url…",
"keyId": "90e1c8fd60d7610e",
"nextCheckIn": 60
}
}Validate
Call on a 60-second schedule. Generate a fresh nonce per call. Verify the signature before trusting allowRuntime.
POST /api/v1/validate
{
"licenseKey": "SPKY-...",
"fingerprint": "sha256-of-machine-hwid",
"nonce": "n_01J8Z9K2",
"serverId": "srv-eu-01"
}A nonce can be used once. Spiky stores it in Redis for 180 seconds and rejects replays with409 nonce_reused. Every denial is still signed, so the client can verify allowRuntime:false instead of trusting an HTTP error.
Verify a response
Canonicalize the payload (sorted keys, no whitespace), then verify with the public key. The SDK in sdk/spiky-client.js does this for you.
import { SpikyClient } from './sdk/spiky-client.js'
const client = new SpikyClient({
baseUrl: 'https://license.vertalt.my.id',
apiKey: process.env.SPIKY_API_KEY,
licenseKey: process.env.SPIKY_LICENSE_KEY,
fingerprint: machineFingerprint(),
serverId: 'srv-eu-01'
})
const verdict = await client.validate()
if (!verdict.allowRuntime) {
stopService(verdict.reason) // license_suspended | product_killed | ...
}Heartbeat
Report hostname, version, and installed plugins. Unlicensed servers still appear in the fleet.
await client.heartbeat({
serverName: 'eu-01.xcord.example',
version: '1.75',
region: 'eu-central',
plugins: [
{ slug: 'anti-cheat', version: '1.2.0' },
{ slug: 'permissions', version: '3.0.1' }
],
metrics: { players: 42, uptime: 86400 }
})Public key
Pin this key in the client. It is public and rotates only with an explicit signing-seed change.
Operational notes
Client SDK
The JavaScript client is in sdk/spiky-client.js. The Java integration example is in examples/xcord-java/.