Docs

Errors

Every status code and reason string the licensing API can hand back, in one place, so an integration can handle all of them rather than the ones it happened to see in testing.

The shape of a refusal

Validate and Issue never throw a generic error body. Every refusal is { valid: false, reason } or { issued: false, reason }, with the HTTP status set to match. Check reason, not only the status: several different reasons share the same status code.

Status codes

StatusMeaning
200The call was made and answered, including a refused licence (valid: false with a reason).
201A licence was issued (Issue endpoint only).
400The request body did not parse, or a field failed validation.
401No API key on the request, or it does not match a live key.
403The key exists but lacks the scope, or the workspace's plan is dormant, or the licence itself refuses.
404The licence or product does not exist in this workspace.
429The plan's rate limit was hit. Retry-After header names the wait, in seconds.

Reason strings

  • reason
    invalid_request
    From
    Validate, Issue
    Meaning
    The body failed its schema check (wrong type, wrong length, missing field, or unparseable JSON).
  • reason
    unauthorized
    From
    Validate, Issue
    Meaning
    No key, an unknown key, or a key outside its IP allowlist.
  • reason
    plan_limit
    From
    Validate, Issue
    Meaning
    The workspace owner's plan is over its limits (see rate-limits.vue's Dormancy note) and the workspace is dormant.
  • reason
    rate_limited
    From
    Validate, Issue
    Meaning
    The plan's request ceiling for this key or IP was exceeded.
  • reason
    forbidden
    From
    Validate, Issue
    Meaning
    The key does not carry the scope the endpoint requires (license.validate or license.issue).
  • reason
    not_found
    From
    Validate, Issue
    Meaning
    Validate: no licence with that key in this workspace. Issue: no product with that id in this workspace.
  • reason
    wrong_product
    From
    Validate
    Meaning
    The key is good and the licence is real, but it belongs to a different product than the productId on the request. Only ever returned when the caller sends one.
  • reason
    <license.status>
    From
    Validate
    Meaning
    A licence whose status is not 'active' refuses with its own status string as the reason, e.g. suspended or revoked.
  • reason
    expired
    From
    Validate
    Meaning
    A non-lifetime licence past its expiresAt.
  • reason
    over_plan_limit
    From
    Validate
    Meaning
    The workspace is past its plan's licence ceiling. Oldest licences keep validating, the newest stop.
  • reason
    blocked
    From
    Validate
    Meaning
    The hwid or IP is on the workspace blacklist, or this specific machine was individually blocked on the licence.
  • reason
    hwid_required
    From
    Validate
    Meaning
    The licence is hardware-locked and no hwid was sent. 400, not 403.
  • reason
    activation_limit
    From
    Validate
    Meaning
    A new machine tried to activate and the licence is already at its cap.