Skip to main content
A tier is a rule you define under your tenant: a name and a minimum XP threshold, with optional benefits text, an accent colour and an icon. A customer is in a tier when their XP balance has reached its threshold.

Membership is computed, not stored

Nothing writes a tier onto a customer. The tier a customer is in is the one whose threshold is the highest at or below their current balance, and that tier’s band runs up to the next higher threshold. The balance it is computed from is the on-chain one, summed across the wallets Kintra manages for the customer, which is the same number a balance read answers. Two things follow from that, and both catch an integration that assumed a stored membership. Membership moves when the balance moves, which is when the chain work settles. An earn or a redemption is accepted and queued, and the balance changes when the mint or the burn is indexed. A customer does not cross a threshold at the moment your write returns. Membership can move down. Eligibility is evaluated against the current balance rather than against a lifetime total, so a redemption that takes a customer below a threshold they had passed takes them out of that tier.

Thresholds are distinct and ordered

Under one tenant no two tiers may share a name, and no two may share a threshold. A duplicate name returns 409 TIER_DUPLICATE_NAME and a duplicate threshold returns 409 TIER_DUPLICATE_THRESHOLD, on a create and on an update alike. That is worth relying on: your thresholds are distinct, so their order is total and exactly one of them is the highest a given balance has reached. Creating a tier and updating one are both writes that require X-Idempotency-Key. A threshold comes back as a string on a read and is sent as a whole number on a write, which is the same split XP amounts have.

What the API answers about a tier

GET /gateway/customers/{userId}/tier/{tierId}/eligibility answers data.eligible for one tier: true when the customer’s balance is at or above that tier’s threshold. A tier id that is not yours returns 404 TIER_NOT_FOUND. No operation answers which tier a customer is in. To show a tier, read your tiers with GET /gateway/tiers, read the customer’s balance, and take the highest threshold at or below it. That is the same computation the platform runs, on the same two inputs. Give that comparison a tie rule. The duplicate-threshold refusal is a check the API runs before the write rather than a constraint the database holds, so two tiers at one threshold is a state your tooling can reach by creating both at once. If your list ever comes back with two, pick between them on a stable field such as the tier id and use the same rule everywhere you show a tier, rather than taking whichever the list happened to return first.

What changes when a customer moves

Inside Kintra a tier move changes one thing: which rewards the customer can redeem. A reward carrying a minimum tier is refused with 403 REWARD_TIER_LOCKED while the balance sits below that tier’s threshold, and the cost is never compared when it does. Everything else a tier means is yours. The benefits description, the colour and the icon are fields you fill in and render, and the platform stores them without acting on them. There is no moment at which the platform records a customer crossing a threshold, because there is no membership record to write. A product that reacts to a tier change computes the tier when it needs it and compares that against what it last showed.

Where to go next