DOCS LLMs

Validate License

Validate License

Validates a license key and returns its current status.

POST /api/v1/products/{slug}/licenses/{key}/validate

Try it in the Interactive API Docs →

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_locked licenses, you must provide a device_id to verify the device is activated. Without it, validation returns valid: false with code device_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

  1. Cache results — Don't call on every user action; cache for ~1 hour
  2. Handle network failures — Use cached results or allow a grace period when offline
  3. Pass device_id — For hardware-locked licenses, always include to verify activation
  4. Check entitlements — Use active_entitlements to enable/disable features
  5. Monitor expiration — Warn users before expires_at date

See Also