track(), summed over each store’s billing period. That is what usedThisPeriod reports and what a plan bills. A view is for the other questions:
- How many times did this fire, ignoring quantity?
- What is the total of
properties.total_pricethis month? - How much has this store used in the last 7 days?
Adding one
Open the event under Usage → Events, then Add a view.
As you fill it in, Meridian previews the definition against events you have already stored: the value it would give, how many events counted, how many were skipped, and across how many stores. Get the number you expect there before you create the view.
The preview period
The preview reads Last 90 days by default, and the subtitle says so. That is a bound on the preview, never on what Meridian kept: your events are all still there, and the view reads every one of them when you create it. Switch the period to Last 12 months or All time to see the figure over more of your history. A developer who imported two years of events sees the lifetime count in the dialog, before the view exists.
Counts and quantity totals come from the daily totals Meridian already keeps per event key, so any period is instant and none of them is capped. That is also the same place the created view reads from, so the number in the dialog and the number on the view afterwards agree.
A total of an event property is the exception. Those daily totals hold a value and never the properties it came from, so previewing one means reading your raw events, which Meridian bounds to the last 90 days and to 20,000 rows, newest first. Over a longer period it says it cannot give you the number rather than answering with a 90-day figure under an “All time” label. Check the property is there over 90 days, create the view, and Meridian computes it across your whole history.
If your app tracks enough events to pass 20,000 inside 90 days, the preview says how many rows it read out of how many are in the window. Only the preview is capped. The view itself has no cap.
Keys are shared with your events
A view’s key lives in the same namespace as your event keys, one namespace per app. You cannot give a view a key an event already uses, or the reverse. Meridian refuses both with a 422. That is what makesgetUsage("anything") work: your app holds one string and does not have to know whether it names an event or a view.
What a view can read
Two aggregations, on purpose. Number of events counts everytrack() call, whatever quantity it carried. Use it when the call is the thing you care about: API requests, runs, exports.
A total adds up either the quantity you passed to track(), or one numeric property you sent with it. properties.total_price, properties.characters, properties.bytes: a dot path, so a nested property is order.total_price.
The property picker offers the numeric properties your recent events actually carry, with how many of them carry each one. Pick from that list rather than typing a name, and a typo can’t cost you a month of data.
Properties that aren’t there are skipped
A total over an event property can only add up events that carry it as a number. An event whose property is missing,null, or not numeric ("free", true, an object) is skipped: it stays stored, it still counts for the event itself and for billing, it just contributes nothing to that view.
Meridian counts those skips and shows them on the view, so a total that reads lower than you expect has an answer rather than a mystery. The create-time preview shows the same count over the last 90 days, before you commit to a definition. If it says every event was skipped, the property name is wrong or your app isn’t sending it yet.
Its history
The views list states one figure per view: its all-time total across every store, with a 30-day sparkline beside it. History, in the row’s menu or by clicking that sparkline, opens the same figure as a chart, over the period you pick: last 7, 30 or 90 days, the last 12 months, or all time. Coarse periods are drawn one bar per month, so two years of a metric is 24 bars rather than 730. This is the only place a total of an event property has a shape. The create-time preview of one is bounded to the last 90 days, because the daily totals hold a value and never the property it came from. The view has already reduced every one of those properties to a value, soproperties.total_price per month over two years is one read here, on a view that already exists.
The bars are every store together, for the same reason the total is. The per-store, windowed figure is the one your app reads through getUsage().
Windows
Five presets. No custom ranges.
The window is per store, and it is the window
getUsage() reports over. A store on Billing period gets its own cycle: 30 days from when its subscription activated when it is subscribed, the UTC calendar month when it is not. It is the same rule the rest of usage follows.
That is also why the numbers on the event’s page are all-time totals across every store rather than “this period”: with a Billing period view there are as many current windows as you have subscribed stores, so no single figure could mean it. The per-store, windowed number is the one your app reads.
Reading a view from your app
getUsage(key) takes an event key or a view key:
getView(key) carries it:
windowStart and windowEnd are absent on an All time view, which is unbounded. Both are also on the raw snapshot as entitlements.views[key], and the same pair exists on the server client as getUsage / getView.
Reacting to a view
A view is also something an automation can watch: Usage view crosses a threshold runs a flow the first time a store’s value for a view reaches a number you set, once per store, per window. The threshold is evaluated as your app tracks events, so a recompute or a backfill never sends anything.Editing and deleting
Right after you create a view it is Computing: it is reading your history, and the event page says so. Its numbers fill in as that runs. It becomes Ready when it has read everything. You can change what a view reads (its aggregation, its property, its window) at any time, until a plan prices it. Changing the aggregation or the property recomputes the view from your history and puts it back to Computing; changing only the window needs no recompute, because a window is applied when the value is read, not when it is stored. Two things never change: the key, because your app calls it, and the event it reads, because everything the view has computed came from that event’s rows. Deleting a view removes it and the daily totals it computed. Your stored events are untouched: a view is an interpretation of them, and dropping it changes nothing about what happened. Any code callinggetUsage() with its key stops resolving, so remove the call too.
Deleting the event a view reads deletes the view with it, the same way, and the event’s delete confirmation lists its views first. A view a plan prices blocks that delete too (see A priced view is locked).
Billing on a view
A plan can meter a view instead of an event key. That is how percentage-of-value pricing works: a view that totalsproperties.total_price over the billing period, priced at 0.02 per 1 unit, is 2% of GMV.
Set it in the Plan Builder alongside your events: same section, same four terms:
Once it is priced, the view behaves like a metered event everywhere:
getUsage(key) carries includedQuantity and cappedAmount, the account page renders a usage meter for it, and updateUsageCap takes its key.
Two rules, both from Shopify
Only a Billing period view can be priced. Shopify bills app usage per 30-day cycle, so “the overage of a rolling 7-day metric” is not a question with an answer. A Month-to-date or Last 7 days view stays perfectly useful for what you display and gate on. It just cannot carry a price, and Meridian refuses the plan term rather than inventing a meaning. A plan meters one subject in total, an event or a view, never both. A subscription carries a single usage line item. A view that is still Computing cannot be priced either: it has read only part of your history, and the first charge would be a figure nobody could explain.A priced view is locked
The moment any plan, draft or active, references a view, its definition freezes. Its aggregation, property, window and key can no longer be changed, it cannot be recomputed, and it cannot be deleted, and neither can the event it reads. Meridian answers a422 naming the plans holding it.
That is deliberate, and it is about money: redefining a metric merchants are billed on changes what they are charged for, and recomputing one rewrites the history a past invoice was computed against. Renaming it is still fine, because a name is not a definition. Removing it from every plan unlocks it again.
To meter something different, create a second view. That is the honest model anyway: the old one keeps its charge history, and nothing about a past invoice becomes unexplainable.