Docs / Licences
Issue
POST
/api/v1/licenses/issue Claims a hardware-locked licence for a product, for an app that ships with no key. Requires the license.issue scope, which is deliberately kept separate from license.validate: a key baked into a downloadable build can be pulled out of it, and this is the one permission it should carry.
Request
- Field
- productId
- Type
- string (UUID)
- Required
- Yes
- Notes
- Must belong to the same workspace as the key.
- Field
- hwid
- Type
- string
- Required
- Yes
- Notes
- 4 to 200 characters. The machine this licence is claimed for.
- Field
- hostname
- Type
- string
- Required
- No
- Notes
- Up to 200 characters.
- Field
- Type
- string
- Required
- No
- Notes
- Stored as the licence's contact email, lowercased.
Response
On success, 201:
json
{
"issued": true,
"reused": false,
"license": {
"key": "BLM-XXXX-XXXX-XXXX",
"status": "active",
"expiresAt": null
}
}On refusal:
json
{
"issued": false,
"reason": "not_found"
}Idempotency
Idempotent on the pair of product and hwid. If a licence already exists for this product with an activation on this exact hwid, the same key comes back with reused: true and 200, rather than a new licence being created. A first launch that times out after the licence was created can safely ask again.
Reasons
- Status
- 400
- reason
- invalid_request
- When
- productId is not a UUID, or hwid is missing or the wrong length.
- Status
- 401
- reason
- unauthorized
- When
- No key on the request, or it does not match a 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. A retryAfter (seconds) is included in the body.
- Status
- 403
- reason
- forbidden
- When
- The key does not carry the license.issue scope.
- Status
- 404
- reason
- not_found
- When
- No product with that id exists in this workspace.
Example
javascript
// First launch: no key shipped, so claim one for this machine.
let key = store.get('licenseKey');
if (!key) {
const res = await fetch('https://bloomcloud.pro/api/v1/licenses/issue', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + BLOOM_API_KEY, // needs license.issue
},
body: JSON.stringify({ productId: BLOOM_PRODUCT_ID, hwid: machineId() }),
});
const issued = await res.json();
if (!issued.issued) throw new Error(issued.reason);
key = issued.license.key;
store.set('licenseKey', key);
}
// Every later launch goes through validate, exactly as above.