TypeScript SDK
Use Entitler from your TypeScript and JavaScript servers and web apps.
The TypeScript SDK, @entitlerhq/entitler, has two clients: EntitlerServer for your servers, with a secret key, and EntitlerClient for browsers, with a customer token. Its source is at github.com/entitlerhq/entitler-typescript.
Install
npm install @entitlerhq/entitlerOn your server
import { EntitlerServer } from '@entitlerhq/entitler'
const entitler = new EntitlerServer({ key: process.env.ENTITLER_KEY ?? '' })
const ada = entitler.customer('ada')
if (await ada.isEntitled('priority_support', { default: false })) {
openTicket()
}
const check = await ada.check('ai_credits')
const entitlements = await ada.entitlements()
await ada.recordUsage('ai_credits', 3, { idempotencyKey: 'run-42' })
const { token } = await ada.token({ scopes: ['entitlements:read', 'usage:write'] })check(feature)answers the customer's entitlement to one feature:entitled,value,meterandupgrades. A meter'sremainingis a number, or'unlimited'.isEntitled(feature, { default })answersentitled, ordefaultwhen Entitler can't be reached.entitlements()answers every entitlement, withhas(feature)andget(feature).recordUsage(feature, amount, { idempotencyKey })reports usage. It answers the same fields ascheck, with the meter after the report, plusoutcome,refusal,amount,meterChangeandoverBy; see Usage and meters.withHold(feature, amount, work, { idempotencyKey })holds, runs your work and settles what it used; see Meter usage with holds.token({ scopes })mints a customer token for your app.
In the browser
import { EntitlerClient } from '@entitlerhq/entitler'
const entitler = new EntitlerClient({
token: async ({ signal }) => {
const response = await fetch('/api/entitler-token', { method: 'POST', signal, credentials: 'include' })
return (await response.json()).token
},
})
const check = await entitler.me.check('priority_support')me is the customer the token was minted for. The client calls token when it has none, and again when Entitler refuses the one it has.
Errors
Every error the SDK throws extends EntitlerError. A refusal from the API is an ApiError, with status, code, reason, parameters, requestId and retryAfter; ConnectionError and TimeoutError mean Entitler couldn't be reached. retryAfter is in milliseconds. See Errors.
Here a report for a customer who isn't registered yet registers them, then sends the same report again, with the same idempotency key.
import { ApiError } from '@entitlerhq/entitler'
const report = () => ada.recordUsage('ai_credits', 3, { idempotencyKey: 'run-42' })
try {
await report()
} catch (error) {
if (error instanceof ApiError && error.reason === 'CUSTOMER_NOT_FOUND') {
await registerAda()
await report()
} else {
throw error
}
}The SDK retries what is safe to retry on its own; see Limits and retries.