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
    email
    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.