Docs / Licences
Validate
POST
/api/v1/licenses/validate Checks whether a licence key is good, and returns it if so. Requires the license.validate scope.
Request
- Field
- key
- Type
- string
- Required
- Yes
- Notes
- 8 to 200 characters.
- Field
- hwid
- Type
- string
- Required
- Only if the licence is locked to hardware
- Notes
- 4 to 200 characters.
- Field
- version
- Type
- string
- Required
- No
- Notes
- Up to 50 characters, recorded but not enforced by this endpoint.
- Field
- productId
- Type
- string
- Required
- No, and worth sending
- Notes
- The product the calling software is. When present, a licence bought for a different product in the same workspace is refused with wrong_product. An API key is scoped to a workspace, not to a product, so without this a key for one of your products validates inside another.
- Field
- hostname
- Type
- string
- Required
- No
- Notes
- Up to 200 characters.
Response
On success:
json
{
"valid": true,
"license": { /* the licence, shaped by LicenseValidator */ }
}On refusal:
json
{
"valid": false,
"reason": "expired"
}Reasons
- Status
- 400
- reason
- invalid_request
- When
- The body did not parse, or key was missing, too short (under 8 characters) or too long (over 200).
- Status
- 401
- reason
- unauthorized
- When
- No key on the request, or the key does not match any live key.
- Status
- 403
- reason
- plan_limit
- When
- The workspace owner's plan is over its limits and the workspace is dormant.
- Status
- 429
- reason
- rate_limited
- When
- The plan's rate limit was hit. Retry-After tells you when to try again.
- Status
- 403
- reason
- forbidden
- When
- The key does not carry the license.validate scope.
- Status
- 404
- reason
- not_found
- When
- No licence with that key exists in this workspace.
- Status
- 403
- reason
- wrong_product
- When
- The licence is real, but it was bought for a different product than the productId sent with the request.
- Status
- 403
- reason
- <the licence status>
- When
- A licence that is not 'active' (e.g. suspended, revoked) refuses with its own status as the reason.
- Status
- 403
- reason
- expired
- When
- Not lifetime, and expiresAt has passed.
- Status
- 403
- reason
- over_plan_limit
- When
- The workspace is past its plan's licence ceiling; oldest licences keep working, newest stop.
- Status
- 403
- reason
- blocked
- When
- The hwid or IP is on the workspace blacklist.
- Status
- 400
- reason
- hwid_required
- When
- The licence is hardware-locked and no hwid was sent.
- Status
- 403
- reason
- activation_limit
- When
- A new machine tried to activate and the licence is already at its cap.
- Status
- 403
- reason
- blocked
- When
- This exact machine was individually blocked on this licence, even if the hwid is not on the workspace blacklist.
See Errors for the full set of reason strings across every endpoint.
Example
javascript
const res = await fetch('https://bloomcloud.pro/api/v1/licenses/validate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + process.env.BLOOM_API_KEY,
},
body: JSON.stringify({
key: config.licenseKey,
hwid: machineId(), // omit to check without locking to a machine
version: app.version,
}),
});
const result = await res.json();
if (!result.valid) {
throw new Error('License refused: ' + result.reason);
}