Agent Skill · Stigg

stigg-entitlements

RUNTIME skill — use when implementing the runtime side of Stigg — gating feature access (`hasAccess`, `getMeteredEntitlement`, `getBooleanEntitlement`, `getEntitlement`), reporting usage (`reportEvent` for raw events vs `reportUsage` for calculated measurements), promotional entitlements, and configuring local caching / fallback so checks stay reliable when Stigg is unreachable. Triggers include "gate this feature with Stigg", "check entitlement", "is the customer allowed to", "hasAccess", "feature flag with Stigg", "report usage to Stigg", "report a usage event", "increment usage", "events.report vs usage.report", "Stigg fallback strategy", "Stigg cache", "Stigg sidecar", "Stigg goes down", "Stigg offline", "stale entitlements", "promotional entitlement", "grant a one-off entitlement". Skip for catalog modeling (stigg-pricing-modeling), subscription lifecycle (stigg-subscriptions), or generic feature flags with no Stigg integration (e.g., LaunchDarkly).

Provider: Stigg Path in repo: skills/stigg-entitlements/SKILL.md

Skill body

Stigg Entitlements — Gate Features and Report Usage

This skill covers the runtime side: checking entitlements at request time, reporting usage, and keeping checks reliable when Stigg is briefly unreachable.

Before You Start

Per the umbrella stigg skill: search first. SDK init signatures and entitlement-method names evolve — open the relevant SDK / REST page (Mintlify Stigg docs MCP) before authoring.

The Two Most Important Rules

Rule 1 — Raw events vs calculated usage is by throughput, not by who counts

Stigg accepts usage data through two paths. They look similar; their scaling characteristics are different.

Naming note: the GraphQL mutations / Node SDK methods are reportEvent (raw events) and reportUsage / reportUsageBulk (calculated). Direct REST callers hit POST /api/v1/events and POST /api/v1/usage for the same operations. The shorthand “events.report” / “usage.report” you’ll see used in this skill refers to the conceptual operation, not a specific SDK namespace.

Path What it is Scale model When to pick
Raw eventsreportEvent (Node SDK / GraphQL) / POST /api/v1/events You stream individual events with dimensions; Stigg filters and aggregates server-side. Async, high-throughput. Designed for production volume. Buffered + deduped. Limits: 1 MB per event; 1,000 events per batch; 1,000 events / sec peak. Default for production usage reporting. Per-request increments, AI-token deductions, billable events at scale.
Calculated usagereportUsage / reportUsageBulk (Node SDK / GraphQL) / POST /api/v1/usage Your app aggregates locally; you push the delta or the set value to Stigg. Sync, measurement-style. Lower-throughput by design. reportUsageBulk accepts up to 100 measurements per call. Rare, batched updates: “the customer now has 5 seats” (set), or “+2 seats” (delta). Backfills. Periodic infra polling.

Common misconception: “events” = consumption-y things, “usage” = entitlement-y things. No. The split is operational. Both paths can drive metering and billing. Pick by throughput / latency budget, not by what the data represents.

Rule 2 — Always have a fallback

Entitlement checks are on the critical path of your app. Stigg’s SDKs cache locally and support persistent caches; configure both the cache and the fallback before going to production. See references/fallback.md.

Gating — The Three Entitlement Shapes

Feature type Method (frontend / backend SDK) Returns
Boolean getBooleanEntitlement({ featureId }) { hasAccess, accessDeniedReason? }
Configuration getNumericEntitlement({ featureId }) / getEnumEntitlement({ featureId }) the configured value
Metered getMeteredEntitlement({ featureId, options: { requestedUsage } }) { hasAccess, currentUsage, usageLimit, ... }

Re-check the actual method names in the SDK page you’re targeting — names occasionally evolve (e.g. getEntitlement is also exposed as a unified, generic check on backend SDKs).

Detailed gating patterns — backend / frontend init, per-resource gating, response shape, anti-patterns: references/gating.md.

Frontend (browser) gating

import Stigg from '@stigg/js-client-sdk';

// initialize() is SYNCHRONOUS — it returns the client.
// To wait for the client to finish loading, await waitForInitialization().
const stiggClient = Stigg.initialize({
  apiKey: 'client-...',          // publishable key, not server key
  customerId: 'customer-123',
});
await stiggClient.waitForInitialization();

const ent = stiggClient.getMeteredEntitlement({
  featureId: 'api_calls',
  options: { requestedUsage: 1 },
});

if (ent.hasAccess) {
  // allow
} else {
  // show paywall / upgrade prompt
}

For React: wrap in <StiggProvider> and use the hooks the React SDK exposes.

Backend gating

import Stigg from '@stigg/node-server-sdk';

const stigg = await Stigg.initialize({ apiKey: process.env.STIGG_SERVER_API_KEY! });

const ent = await stigg.getMeteredEntitlement({
  customerId: 'customer-123',
  featureId: 'api_calls',
  options: { requestedUsage: 1 },
});

if (!ent.hasAccess) throw new HttpError(402, 'Upgrade required');

For raw REST, the equivalent is GET /api/v1/customers/{id}/entitlements. (The GraphQL query is getEntitlementsState.) See the REST API reference for query params.

Reporting Usage — Pick the Path

Full event-schema field tables, dimension-design guidance, cloud-ingestion paths (S3 / Pub/Sub), and the GraphQL vs direct-REST surface map: references/usage-reporting.md.

Default — Raw events (events.report / reportEvent)

// Backend Node SDK
await stigg.reportEvent({
  events: [{
    customerId: 'customer-123',
    eventName: 'api.request',
    idempotencyKey: 'req-abc-1234',          // required
    dimensions: { region: 'us-east-1', endpoint: '/search' },
    // timestamp is optional; server time is used if omitted
  }],
});

Notes:

Set / delta — Calculated usage (usage.report / reportUsage)

import { UsageUpdateBehavior } from '@stigg/node-server-sdk';

// "Customer now has 5 seats" — Set behavior
await stigg.reportUsage({
  customerId: 'customer-123',
  featureId: 'seats',
  value: 5,
  updateBehavior: UsageUpdateBehavior.SET,
});

// "+2 seats" — Delta behavior (default)
await stigg.reportUsage({
  customerId: 'customer-123',
  featureId: 'seats',
  value: 2,
  // updateBehavior defaults to DELTA
});

Use this when your app has the authoritative value (seat counts, configured quotas) and you don’t want Stigg aggregating per-event.

Bulk variant (reportUsageBulk) supports up to 100 measurements per call — note its rate limit.

Cache + Fallback — Required for Production

Stigg SDKs cache effective entitlements locally so checks don’t pay a network round trip on every request. Configure the cache and the fallback before production:

Full guidance: references/fallback.md.

Promotional Entitlements

Per-customer entitlement overrides — granted directly to a customer, outside any subscription. Owned by this skill end-to-end (granting, revoking, reading) since they’re per-customer runtime concerns, not catalog modeling.

Modeling shape (which features exist) lives in stigg-pricing-modeling; promotional entitlements just override configuration on those features for a specific customer.

When NOT to Use This Skill

Common Mistakes

Mistake Fix
Picking usage.report because it “sounds canonical” The split is by throughput. For production volume, default to events.report.
Omitting idempotencyKey on events Required. Without it you get either rejections or duplicate counting.
Reporting usage from the browser Usage reporting is a backend concern; the publishable key is read-only.
Treating cache as optional Cache + fallback are part of the contract for production. Configure both.
Defining no fallback rules When Stigg is briefly unreachable and the cache is cold, the SDK has nothing to return. Pick a sensible default (usually allow with a log).
Synchronously calling Stigg on every API request The SDK already caches — let it. Don’t double-cache in your app.
Per-call await to events.report in the hot path Buffer / batch and flush async. The events path is designed for this.
Using a raw event when a configuration value would do Configuration features (numeric / enum) are simpler to model and don’t need event ingestion.