This guide meters a billable action end to end. check-and-record atomically verifies quota and writes the usage event in one call, so an over-limit request returns 402 instead of silently inserting. An idempotencyKey makes retries safe. You then read the usage summary, gate a feature on the tenant's plan entitlement, and preview the next invoice.
-
Meter the action with
usage.checkAndRecord, passing a stableidempotencyKeyso a retried request is not double-counted. -
Branch on
result.allowed. Whenfalse, the quota was exceeded - the API maps this to402(plan_limit). -
Read the rolling usage with
usage.summary(tenantId, period). -
Before exposing a paid feature, call
billing.entitlement(tenantId, feature)and checkallowed. -
Preview the upcoming invoice with
billing.invoicePreview(tenantId).
import { GatekeeperCore, UsageService, BillingService } from '@orkait/sdk';
const core = new GatekeeperCore({ baseUrl: 'https://gatekeeper-api.example.workers.dev' });
core.setToken(accessToken);
const usage = new UsageService(core);
const billing = new BillingService(core);
// 1-2. Atomic check + record. The idempotencyKey makes retries safe.
const result = await usage.checkAndRecord({
tenantId: 't_acme',
service: 'api',
action: 'call',
quantity: 1,
idempotencyKey: 'req-2026-06-03-42',
});
if (!result.allowed) {
throw new Error(`quota exceeded: ${result.quota.used}/${result.quota.limit}`);
}
// 3. Read the rolling usage summary for the period.
const summary = await usage.summary('t_acme', 'month');
console.log(`${summary.totalUsage} units this ${summary.period}`);
// 4. Gate a paid feature on the plan entitlement.
const ent = await billing.entitlement('t_acme', 'advanced_export');
if (!ent.allowed) {
throw new Error('feature not in plan');
}
// 5. Preview the next invoice.
const invoice = await billing.invoicePreview('t_acme');
console.log(invoice);There is no subscribe method. To change a tenant's plan, drive the provider checkout flow with billing.createCheckoutSession(...) and manage the active subscription with billing.getSubscription(tenantId) and billing.createPortalSession(...).