Membership tiers
Members of a United Pet Club organization’s program sit on a tier — a rung with its own benefits. On the platform’s own programs these rungs are the membership grades (Companion, Guardian, Steward, Patron; Associate, Fellow, Distinguished Fellow; Ally, Sanctuary Partner; Charter Member). Members change rung from their own dashboard, and the change can carry a fee that they pay by card.
This page is therefore about one thing — behaving correctly when a member’s tier moves underneath you.
Tiers reach you as entitlements
Section titled “Tiers reach you as entitlements”A tier’s benefits are granted as entitlements against the subject
(usually a PROFILE). When a member upgrades, downgrades, or leaves a program, the platform
re-mints those grants. From your side:
- A quota may increase or decrease.
- A feature flag may turn on or off.
- A previously available definition may stop resolving entirely.
Nothing about that is special-cased for memberships — it is the ordinary entitlement surface you already read.
Two properties to design around
Section titled “Two properties to design around”1. The change is asynchronous. A paid tier change is applied only after the payment provider confirms the charge, and the entitlement re-mint happens after that. A member who has just paid may briefly still resolve on their old tier. Design for the transition being eventually consistent, not instantaneous.
2. Entitlements are not stable. Because tiers move without your integration being
involved, a cached /check result can be wrong at any moment.
POST /api/entitlement/v1/check{ "subject": { "kindCode": "PROFILE", "id": "…" }, "definitionSysName": "televet.session.monthly", "requestedQuantity": 1 }Treat /check as advisory and momentary — call it to decide whether to offer an action,
then call /consume to actually take it. /consume is the authoritative draw-down and is
where a stale view gets corrected.
Handling a downgrade mid-session
Section titled “Handling a downgrade mid-session”The failure you should actually plan for is a member losing capacity between your check and
your consume — they downgraded, or their membership ended. /consume returns a blocking
reason rather than silently over-drawing.
{ "isAvailable": false, "availableQuantity": 0, "blockingReasonCode": "INSUFFICIENT_QUANTITY" }Surface that as “this is no longer included in your plan” rather than as an error. Retrying won’t help; the subject genuinely no longer holds the entitlement.
Always send an Idempotency-Key on /consume so a network retry across a tier change
cannot double-charge the member’s quota — the original result is replayed instead.
A subject may hold no membership at all
Section titled “A subject may hold no membership at all”Do not assume every profile carries a membership. Membership is applied for — a person creates an account, then joins a program through the platform’s own join flow — so a perfectly valid subject can exist for any length of time with no membership and therefore no grade-granted entitlements.
The practical consequences for your integration:
- An empty
/checkresult is a normal state, not a provisioning failure or a sign that the subject is broken. Surface it as “not included” and offer the action that leads the member to join, rather than retrying or erroring. - First entitlements can appear long after the profile does. A subject that resolved to nothing yesterday may resolve today because the member joined in between. Re-check on the same cadence you already use for tier changes.
Terms renew or lapse without any member action
Section titled “Terms renew or lapse without any member action”Paid grades run on a term — a year, a month, or a term paid once, as the organization decides for each grade. Where the dues renew automatically, the membership renews by itself at the end of each term and its entitlements simply keep resolving. A membership that is not renewed — the member switched automatic renewal off, pays once per term, or every renewal payment failed — moves through a grace period (benefits keep working) and then to expired (good standing drops and grade-granted entitlements stop resolving), with no member action at all. A renewal restores the membership and its entitlements.
For your integration this is the same lesson as a downgrade, with one addition: a member who resolved fine last month may stop resolving without ever touching their dashboard — and one who lapsed may resolve again after a late renewal. Re-check rather than cache, and surface a lapse as “this is no longer included in your membership — renew to restore it” rather than as an error.
What you can rely on
Section titled “What you can rely on”| Guarantee | Detail |
|---|---|
| Grants are re-minted, not patched | After a tier change the subject’s grants reflect the new tier as a whole. |
| No partial money states | A tier change is applied only against a confirmed, exact-amount payment; a mismatched payment never moves the tier. |
/consume is authoritative | It is the only call whose result you should treat as a decision. |
Localized names are display data, not identifiers
Section titled “Localized names are display data, not identifiers”Grade, tier and benefit names are localized — the same tier is “Steward” in
en-US, “Intendant” in fr-CA, and “Хранитель” in ru-RU. Never match on a display
name: key your integration on the stable identifiers (definitionSysName for
entitlements, public codes like UMT-… where you handle tier references), and treat
every name field per Localized names.
Availability also never varies by locale. Where a membership benefit is regionally constrained, that follows the member’s verified country — a member changing their UI language sees different words, never different entitlements.
See also
Section titled “See also”- Entitlements — the full check / consume / reserve surface.
- Errors — response-code shape and retry semantics.