Skip to main content
All three resolve the exact same entitlement - they only differ in what they hand back. Pick based on what you’re about to do with the answer.

Parameters

string
required
The feature’s key, as configured in the dashboard.
string
Whose entitlement to check - the external id you bill against (a Kerne user id, or any id you picked for BYO auth / an org). Optional in the type, but with a secret key there’s no “current user”, so pass it explicitly.
number
For quota features: “can this customer use requested more units?” - defaults to 1.
string
For a feature whose limit binds per dimension (per machine, per project, per seat): which slice to check. The SDK param is dimension; it goes on the wire as dimension_id. See consume() > Dimensions for the full behavior.

enforce() throws EntitlementDeniedError

enforce() runs the same check() and throws when allowed is false. The throw is an EntitlementDeniedError - a KerneError subclass, so instanceof KerneError / isKerneError() catch it - with:
  • .check - the full EntitlementCheck (allowed, limit, used, remaining, access_limit, overage_behavior, configured, has_override, …), so a guard can branch on why access was denied without a second call.
  • .code === 'ENTITLEMENT_DENIED', .statusCode === 403, .type === 'AUTHORIZATION_ERROR'.
  • .requestId unset - it’s built client-side from a successful (200) check(), not from an API error response.
The message text is unchanged (Entitlement denied for feature '<key>'), so a bare catch (e) { e.message } still works; use instanceof only when you branch on the shape.

Reading the result of check()

check() returns an EntitlementCheck. Every field, and whether to gate on it:
remaining is plain subtraction and does go negative once a customer runs past what its plan includes. On a feature whose overage is ALLOW or BILL, allowed stays true there - the customer hasn’t hit a wall, they’ve started paying. Read overage_behavior before turning a negative remaining into “limit reached”. used itself is never negative: a credit (rollover, or an admin adjustment) is folded into limit instead.

configured vs allowed

allowed is the go/no-go. configured only tells you whether the catalog (or an override) said anything about this feature for this customer. On the public check path the two always deny together - configured: false implies allowed: false - in every one of these cases:
  • the feature key does not exist (feature_type: 'UNKNOWN')
  • the customer has no subscription and no override and no active default plan
  • an offer version resolved, but this feature isn’t in it and there is no override
Do not treat configured: false as “open by default”. Read it only when you must tell “not sold yet” apart from “sold and denied” - a diagnostic, or a documented fallback while the catalog is still being filled in. See Entitlements for the three kinds of capability.