Entitlements
What the shop’s plan grants right now. This is the snapshot every gate reads from.
All three maps are keyed by the app-local key you set in the dashboard. Event keys and view keys share one namespace per app, which is what lets
getUsage(key) resolve either kind.
EntitlementFeature: { enabled: boolean, limit?: number }.
EntitlementEvent: { usedThisPeriod: number, includedQuantity?: number, cappedAmount?: number }. Present for every event in your catalog; includedQuantity and cappedAmount only where the shop’s plan meters it. usedThisPeriod counts the current period only. See Usage tracking.
EntitlementView: { eventKey, value, eventCount, window, windowStart?, windowEnd? }. The shop’s current reading of one view, measured over the view’s own window rather than the entitlements’ periodStart/periodEnd. value is fractional when the view sums an event property; eventCount is how many events contributed to it. window is the window id (billing_period, calendar_month, last_7_days, last_30_days or all_time), and the ISO 8601 bounds follow it, windowEnd exclusive. Both bounds are absent on an all_time view, which is unbounded.
Plan
One of your active plans, priced in the shop’s currency.PlanFeatureRef: { featureId, name?, value? }, where value is the numeric limit this plan sets.
PlanEventRef: { key, name?, unit?, includedQuantity, overageRate, overageUnit, cappedAmount }. An overageRate of 0 means the plan does not bill overage, so the included quantity is a hard allowance rather than a threshold. overageRate is the price of one block of overageUnit units in the shop’s currency, converted exactly and never rounded to the cent (0.10 USD at an FX rate of 0.92 is 0.092): the figure Shopify’s approval screen states, before it restates a rate under one cent per ten times the units (0.005 per 1 is approved as 0.05 per 10). cappedAmount is in cents, the spending limit sent to Shopify. unit is the singular word set on the event in the catalog ("translation"), or null when it has none. Older API versions omit it, so treat a missing unit as null. A view has no unit: it can total money, a weight or a count of something else.
PlanViewRef: { key, name?, eventKey?, includedQuantity, overageRate, overageUnit, cappedAmount }. The same four terms as PlanEventRef, with two shapes a view forces: includedQuantity is fractional, because a view can total money (“the first 1,000 of GMV”), and overageRate is exact here too, because a percentage-of-value term is a rate like 0.02 and rounding it to cents would turn 0.005 into nothing. A plan carries at most one usage-priced subject across events and views, since a Shopify subscription has a single usage line item.
PlanInterval: "EVERY_30_DAYS" or "ANNUAL".
MeridianCustomer
The shop’s CRM record.customFields is keyed by each field’s immutable handle. A field the store has no value for is absent, so a store with no values reads {}. Values keep their type: a number reads as a number, a JSON field as the parsed structure, a date as its YYYY-MM-DD string.
MeridianMe: { customer, entitlements, plans }. One read gives you all three.
identify returns identity only: its customer carries no customFields.Results
Tracking inputs
track and trackMany on the server client and on createMeridianApp take either input. The useMeridian() hook’s track takes a TrackEventInput only. TrackEventInput is still a plain object type, so a type of your own can extend it.
DiscountPreview carries valid plus, when it applies, the discount’s type (percentage or fixed_amount), its value, a human-readable durationLabel, and the original and discounted prices for both intervals. appliedToCurrentSubscription distinguishes a discount the shop’s subscription already carries from an offer only a new subscription could take. When nothing applies, valid is false with a generic message that never reveals whether a code exists.
Custom field values
CustomFieldValue: string | number | boolean | unknown[] | Record<string, unknown> | null.
On the write side, null clears a field, and so does "", so a stored text value is always non-empty. A read never yields null: a cleared field is absent from the map.
Server types
React types
MeridianContextValue is everything useMeridian returns, and MeridianProviderProps is the provider’s prop shape. Both are exported, for a wrapper component of your own.