Kaiten

Entitlements

Entitlement Exceptions

Your dated decision on one entitlement of one Instance, without a code — the three kinds, the window and the reason, how an exception overrides the License, add-ons and boosts, one at a time per entitlement, revocation, and the events.

An entitlement exception is your decision about one entitlement of one Instance, for a period, without a code: SSO for two weeks, twenty more menu items while a prospect weighs an upgrade, a load test without a limit on orders. You set it with your organization's credentials — a customer never can — and it ends on its own. It is the last layer of the Instance's effective value: it wins over the License, the add-ons, and the boosts of vouchers, and it may lower a value as well as raise it.

An exception belongs to entitlements, not to billing: it works whether billing is enabled or not, and it changes no License, subscription, or price.

Sakura Tokyo's demo instance, on Starter, carries three exceptions — an example to build:

EntitlementExceptionWindowStatusReason
menu-itemsAdd 20Two weeks from todayACTIVETwo weeks of the larger menu, for the Premium upgrade talk
delivery-trackingSet to trueStarts laterSCHEDULEDThe Shibuya pilot
monthly-ordersMake unlimitedA week, last monthEXPIREDA load test
Sakura Tokyo Demo's Entitlements & Usage tab with its Entitlement exceptions card: Menu Items, Add 20, active for two weeks with its reason; Delivery Tracking, Set value Enabled, scheduled; Monthly Orders, Make unlimited, expiredSakura Tokyo Demo's Entitlements & Usage tab with its Entitlement exceptions card: Menu Items, Add 20, active for two weeks with its reason; Delivery Tracking, Set value Enabled, scheduled; Monthly Orders, Make unlimited, expired

The three kinds

kindConsoleEntitlement typesvalueEffect
SETSet valueEvery typeA number of 0 or more; true or false; a JSON object for a CONFIGReplaces the value, whatever the layers below gave — an unlimited one included
ADDAddNUMBER, NUMBER_AI_CREDITA number above 0Adds to the value; an unlimited value stays unlimited
UNLIMITEDMake unlimitedNUMBER, NUMBER_AI_CREDITNoneMakes the value unlimited

ADD or UNLIMITED on a BOOLEAN or CONFIG entitlement answers 422 CreateEntitlementException.InvalidKind, and a value that does not fit the kind and the type, 422 .InvalidValue. The entitlement need not be granted by anything else: an exception on an entitlement the License and the add-ons leave out makes the Instance hold it, from 0 or false, with source: exception.

Create an exception

Open Customers → Instances, then the instance, then its Entitlements & Usage tab. The Entitlement exceptions card lists the instance's exceptions; Create an exception asks for the entitlement, the operation, the value, the reason, and the start and end, in UTC. Leave the start empty to start now, and the end empty for no end. A SET that lowers the value the instance currently holds is warned about before it is created.

The Create an exception dialog on Sakura Tokyo Demo: Delivery Drivers, Add, 3, with its reason, Three more drivers for the Golden Week rush, and the start and end fieldsThe Create an exception dialog on Sakura Tokyo Demo: Delivery Drivers, Add, 3, with its reason, Three more drivers for the Golden Week rush, and the start and end fields

Twenty more menu items for two weeks:

ENDS_AT=$(date -u -d '+14 days' +%Y-%m-%dT%H:%M:%SZ)   # macOS: date -u -v+14d +%Y-%m-%dT%H:%M:%SZ

curl -X POST "$KAITEN_API/instances/sakura-tokyo-demo/entitlement-exceptions" \
  -H "Authorization: Bearer $KAITEN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entitlementSlug": "menu-items",
    "kind": "ADD",
    "value": 20,
    "endsAt": "'"$ENDS_AT"'",
    "reason": "Two weeks of the larger menu, for the Premium upgrade talk."
  }'
{
  "id": "1e2d3c4b-5a69-4788-97a6-b5c4d3e2f1a0",
  "instanceSlug": "sakura-tokyo-demo",
  "entitlementSlug": "menu-items",
  "entitlementType": "NUMBER",
  "kind": "ADD",
  "value": 20,
  "startsAt": "2026-10-27T09:00:00Z",
  "endsAt": "2026-11-10T09:00:00Z",
  "reason": "Two weeks of the larger menu, for the Premium upgrade talk.",
  "status": "ACTIVE",
  "createdAt": "2026-10-27T09:00:00Z",
  "revokedAt": null
}

201 Created, and INSTANCE_ENTITLEMENT_EXCEPTION_CREATED is emitted. The value is sent bare — 20, true, or the object — not in the type/value shape of a grant, and left out for UNLIMITED. Creating and revoking take write:instances, reading read:instances.

The window. startsAt defaults to now; a future instant schedules the exception, and a past one is taken as given. endsAt is optional — no end without it — and must fall after both the start and now (422 CreateEntitlementException.InvalidWindow).

The reason is required, 1 to 500 characters (422 .ReasonRequired). It is for you: the effective value's provenance and the customer portal never show it.

One at a time. An Instance holds at most one exception per entitlement at any instant. An exception whose window overlaps one that is not revoked is refused with 409 CreateEntitlementException.Overlap, and errors[0].value.exceptionId names the one in the way: revoke it, or start the new one after it ends.

What an exception changes

The effective value of the entitlement, for every reader of it, for the whole window:

  • Usage reports are compared with it: twenty more menu items take Sakura Tokyo's demo from a hard cap of 5 to one of 25. Each accepted report is recorded in the usage journal with the limit in force, so a price that bills overage bills what lies above that limit.
  • Usage reads return it, with source and provenance — abridged:
{
  "entitlementSlug": "menu-items",
  "licenseSlug": "starter",
  "value": { "type": "number", "value": 3, "event_count": 3 },
  "limit": { "type": "number", "value": 25 },
  "limitCapExceededOveragePercent": 0,
  "source": "license",
  "provenance": {
    "license": { "value": { "type": "number", "value": 5 }, "limitCapExceededOveragePercent": 0, "…": "…" },
    "addons": [],
    "boosts": [],
    "exception": { "kind": "ADD", "value": { "type": "number", "value": 20 }, "startsAt": "2026-10-27T09:00:00Z", "endsAt": "2026-11-10T09:00:00Z", "…": "…" },
    "number": { "license": 5, "afterAddons": 5, "unlimited": false, "afterBoosts": 5, "effective": 25, "…": "…" }
  }
}
  • Feature flag rules read it in __kaiten.entitlements when the evaluation's subject is the Instance — when the context names it with kaiten.instanceSlug (targeting rules). Once the Shibuya pilot's exception starts, __kaiten.entitlements['delivery-tracking'] == true holds for Sakura Tokyo's demo instance, and delivery-tracking-enabled answers on for an evaluation that names it.
  • The customer portal shows the value with source: exception where only the exception grants it, never the reason.

An exception never sets an overage allowance of its own: the value it produces keeps the allowance of the layers beneath it, and becomes a hard cap where they were unlimited — UNLIMITED excepted.

A SET below the value the Instance holds lowers it for the whole window, an unlimited grant included. Usage already counted is not touched: the next report that would land above the new maximum is refused, until the exception ends.

Revoke an exception

curl -i -X DELETE "$KAITEN_API/instances/sakura-tokyo-demo/entitlement-exceptions/1e2d3c4b-5a69-4788-97a6-b5c4d3e2f1a0" \
  -H "Authorization: Bearer $KAITEN_TOKEN"

204 No Content: an active exception ends at once, a scheduled one never starts, and INSTANCE_ENTITLEMENT_EXCEPTION_REVOKED is emitted. The exception is kept, with its reason, and reads REVOKED — Ended in the console, whose End exception does the same. Revoking one already revoked or ended changes nothing and emits nothing.

Statuses and events

GET /instances/{instanceSlug}/entitlement-exceptions lists the exceptions not revoked or ended, scheduled ones included, latest start first; ?filter=all adds the others. Each carries its status at the read:

StatusWhen
SCHEDULEDBefore startsAt
ACTIVEFrom startsAt, until endsAt when it has one
EXPIREDFrom endsAt
REVOKEDOnce revoked

An exception stops applying the instant its end passes: every read checks its window. INSTANCE_ENTITLEMENT_EXCEPTION_EXPIRED follows, once per exception, with the next pass of the lifecycle job — every 15 minutes by default — and never for a revoked one.

EventEmitted when
INSTANCE_ENTITLEMENT_EXCEPTION_CREATEDAn exception is created
INSTANCE_ENTITLEMENT_EXCEPTION_REVOKEDAn exception not yet ended is revoked
INSTANCE_ENTITLEMENT_EXCEPTION_EXPIREDAn exception's end has passed

The three carry the exception — reason included — and are recorded on the Instance's own audit trail, whether billing is enabled or not. Payloads: the event catalog; shapes: the API reference.

Where to go next

The layers an exception sits on: add-ons and vouchers. How a report is compared with the effective value: Usage & Thresholds. Exact reference: the data model.

On this page