Validate License
Validate License
Validates a license key and returns its current status.
POST /api/v1/products/{slug}/licenses/{key}/validate
When to Use
- App startup to check license validity
- Periodic background checks
- After user enters a license key
- Before enabling premium features
Path Parameters
| Parameter | Required | Description |
|---|---|---|
slug |
Yes | Product slug (e.g., my-app) |
key |
Yes | License key to validate |
Request Body
| Parameter | Required | Description |
|---|---|---|
device_id |
Conditional | Required for hardware_locked licenses. Unique device ID for seat validation. Optional for floating licenses. |
Important: For
hardware_lockedlicenses, you must provide adevice_idto verify the device is activated. Without it, validation returnsvalid: falsewith codedevice_not_activated.
Example Request
curl -X POST https://licenseseat.com/api/v1/products/my-app/licenses/XXXX-XXXX-XXXX-XXXX/validate \
-H "Authorization: Bearer pk_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"device_id": "device-unique-id"}'
Response
{
"object": "validation_result",
"valid": true,
"code": null,
"message": null,
"license": {
"object": "license",
"key": "XXXX-XXXX-XXXX-XXXX",
"status": "active",
"mode": "hardware_locked",
"starts_at": "2024-01-01T00:00:00Z",
"expires_at": null,
"seat_limit": 3,
"active_seats": 1,
"plan_key": "pro",
"active_entitlements": [
{
"key": "updates",
"expires_at": "2025-01-01T00:00:00Z",
"metadata": null
}
],
"metadata": {},
"product": {
"slug": "my-app",
"name": "My App"
}
},
"activation": {
"object": "activation",
"id": 123,
"device_id": "device-unique-id",
"device_name": "John's MacBook Pro",
"activated_at": "2024-01-15T10:30:00Z"
}
}
Response Fields
| Field | Description |
|---|---|
valid |
Boolean indicating license validity |
code |
Error code if invalid (null when valid) |
message |
Human-readable message if invalid |
warnings |
Array of non-fatal advisories (e.g., license_expiring_soon) |
license.status |
active, expired, revoked, suspended, pending |
license.expires_at |
Expiration timestamp (null for perpetual) |
license.seat_limit |
Max simultaneous activations |
license.active_seats |
Currently active activations |
license.active_entitlements |
Features granted by this license |
activation |
Device activation details (if device_id provided) |
Response with Warnings
When a license is valid but has advisories:
{
"object": "validation_result",
"valid": true,
"warnings": [
{
"code": "license_expiring_soon",
"message": "License expires in 7 days"
}
],
"license": { ... }
}
Invalid License Response
When a license is invalid, the response still returns HTTP 200 but with valid: false:
{
"object": "validation_result",
"valid": false,
"code": "expired",
"message": "License has expired.",
"license": { ... }
}
Error Codes
| Code | Meaning |
|---|---|
license_not_found |
License key doesn't exist |
expired |
License has expired |
revoked |
License has been revoked |
suspended |
License temporarily suspended |
device_not_activated |
Device not activated (when device_id provided) |
seat_limit_exceeded |
No available seats for this device |
product_mismatch |
License is for a different product |
Best Practices
- Cache results — Don't call on every user action; cache for ~1 hour
- Handle network failures — Use cached results or allow a grace period when offline
- Pass device_id — For hardware-locked licenses, always include to verify activation
- Check entitlements — Use
active_entitlementsto enable/disable features - Monitor expiration — Warn users before
expires_atdate
See Also
- Activate Device — Register a device for the license
- Quickstart — Complete validation workflow
- Full API Schema → — Request/response details, try it live