API Reference
License Key API
Integrate Guild license keys directly into your software. Validate keys at launch, auto-bind hardware IDs, and let buyers reset or regenerate their keys.
Introduction
Base URL and authentication
All license key endpoints use POST. The key string and parameters are always sent as a JSON body — never in the URL or query string.
Base URL
https://guildly.co/api/license-keys
Content-Type
application/json
Methods
POST (all), GET (events only)
Auth
Validate: public · Shuffle/Reset: buyer session
Call POST /validate on every app launch with your device HWID. On first launch the key auto-binds to that hardware ID — no separate activate step needed.
POST /validate
Check a license key and bind hardware ID
Check whether a license key is valid and optionally bind or verify a hardware ID. On first call with an HWID the key is permanently bound to that device. Subsequent calls with the same HWID succeed; calls with a different HWID fail.
/api/license-keys/validatePublic — no auth required| Name | In | Required | Description |
|---|---|---|---|
key | body | required | The license key string, e.g. GLD-ABCD-EF23-GH45-JK67. |
hwid | body | optional | Hardware identifier for this device. On first call the key binds to this ID. Omit to skip hardware binding. |
{
"key": "GLD-ABCD-EF23-GH45-JK67",
"hwid": "your-machine-id"
}{
"valid": true,
"status": "ACTIVE",
"reason": null,
"key": "GLD-ABCD-EF23-GH45-JK67",
"activationCount": 1,
"maxActivations": null,
"hwid": "your-machine-id",
"hwidResetCount": 0,
"expiresAt": null,
"product": {
"name": "My Software",
"slug": "my-software",
"image": null
}
}{
"valid": false,
"status": "REVOKED",
"reason": "Key has been revoked",
"key": "GLD-ABCD-EF23-GH45-JK67"
}{ "valid": false, "error": "License key not found" }- Always returns HTTP 200 for found keys — check the valid field in your code.
- If hwid is omitted or empty, hardware binding is skipped without error.
- Subscription-linked keys also verify the membership is still active.
- If the key's expiry date has passed, status is automatically updated to EXPIRED.
POST /shuffle
Regenerate a key string (full reset)
Generate a new key string for the buyer. This is a full reset: the old key string becomes invalid, the hardware binding is cleared, and activation counts reset to zero. Useful when a buyer suspects their key has been leaked.
/api/license-keys/shuffleBuyer session required| Name | In | Required | Description |
|---|---|---|---|
key | body | required | The current license key string to regenerate. |
{ "key": "GLD-ABCD-EF23-GH45-JK67" }{ "key": "GLD-ZYXW-VUTS-RQPO-NMLK" }{ "error": "Unauthorized" } // 401
{ "error": "Key regeneration is disabled for this product. Contact the seller." } // 403
{ "error": "Forbidden" } // 403
{ "error": "License key not found" } // 404- The old key string is immediately invalidated — update your stored key after this call.
- Complete reset: HWID, activation count, and reset count all go back to zero.
- Sellers can disable shuffle per-product in License Key app settings (allowBuyerShuffle).
- Only the buyer who owns the key can shuffle it.
POST /reset
Clear hardware ID binding
Clear the hardware ID binding so the key can be activated on a new device. The key string stays the same. Use this when a buyer switches machines and their key is locked to the old hardware.
/api/license-keys/resetBuyer session required| Name | In | Required | Description |
|---|---|---|---|
key | body | required | The license key string whose hardware binding should be cleared. |
{ "key": "GLD-ABCD-EF23-GH45-JK67" }{ "success": true }{ "error": "Unauthorized" } // 401
{ "error": "Device reset is disabled for this product. Contact the seller." } // 403
{ "error": "Forbidden" } // 403
{ "error": "License key not found" } // 404- Only clears the hwid field — key string, activation count, and expiry are unchanged.
- After resetting, the next POST /validate with a new HWID will re-bind the key.
- Sellers can disable buyer resets per-product (allowBuyerReset).
- Each reset increments hwidResetCount on the key.
GET /[keyId]/events
Fetch activity log for a key
Fetch the activity log for a specific license key in reverse-chronological order. Intended for seller dashboards — available under License Keys → Activity.
/api/license-keys/[keyId]/eventsSeller session required| Name | In | Required | Description |
|---|---|---|---|
keyId | path | required | The license key database ID (cuid). Find it in the License Keys dashboard. |
[
{
"id": "evt_abc123",
"type": "VALIDATED",
"createdAt": "2026-04-14T10:30:00.000Z",
"hwid": "device-hwid",
"ip": "1.2.3.4",
"userAgent": "MyApp/2.0 Windows"
},
{
"id": "evt_def456",
"type": "HWID_RESET",
"createdAt": "2026-04-13T08:00:00.000Z",
"hwid": null,
"ip": "1.2.3.4",
"userAgent": null
}
]{ "error": "Unauthorized" } // 401
{ "error": "Forbidden" } // 403
{ "error": "Not found" } // 404- Event types: VALIDATED, HWID_RESET, SHUFFLED, REVOKED, CREATED.
- ip and userAgent may be null if not captured.
- This endpoint is for seller dashboards, not end-user software.
Error Reference
Error messages and HTTP status codes
All errors return JSON with an error or reason field describing what went wrong.
Error messages
| Message | Meaning |
|---|---|
| License key not found | The key string doesn't exist in the system. |
| Key has been revoked | The seller has revoked this key — permanently invalid. |
| Key has expired | The key's expiry date has passed. |
| Membership is no longer active | The buyer's subscription has lapsed or been cancelled. |
| Hardware ID mismatch | The provided hwid doesn't match the bound device. |
| Key regeneration is disabled for this product. Contact the seller. | allowBuyerShuffle is off. |
| Device reset is disabled for this product. Contact the seller. | allowBuyerReset is off. |
| License key is not active | Shuffle/reset attempted on a non-ACTIVE key. |
HTTP status codes
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Success, or invalid key (check valid field for /validate) |
| 400 | Bad Request | Missing required fields |
| 401 | Unauthorized | Session required but not present |
| 403 | Forbidden | HWID mismatch, wrong user, or feature disabled |
| 404 | Not Found | Key or resource doesn't exist |
| 500 | Server Error | Unexpected internal error |