Skip to content

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.

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.

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.

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.

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 /check result 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.

GuaranteeDetail
Grants are re-minted, not patchedAfter a tier change the subject’s grants reflect the new tier as a whole.
No partial money statesA tier change is applied only against a confirmed, exact-amount payment; a mismatched payment never moves the tier.
/consume is authoritativeIt 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.

  • Entitlements — the full check / consume / reserve surface.
  • Errors — response-code shape and retry semantics.