Source: https://www.revvly.ai/docs/guides/scoped-pricing

Guide

# One component. Four *scopes*.

Variable Components describe the shape of pricing. Variable Component Prices ship the numbers. The same component can carry different numbers at the Subscription, Bundle, Module, and Global default scopes — Revvly walks them at billing time and picks the first match.

## The resolution order

From most specific to least specific.

When a subscription is being billed, Revvly looks at every Variable Component on the subscription and resolves a price for each one. For each component, the resolver walks the scopes in this order until it finds a published row with a matching currency:

1. 1Subscription scopeA Variable Component Price targeting this exact subscription. Rarely used — Custom Pricing Agreements are usually a better fit.
2. 2Bundle scopeA price targeting the subscription’s pinned (Bundle id, Bundle version). Only applies if the subscription is bundle-based.
3. 3Module scopeA price targeting any (Module id, Module version) that the subscription pins — directly or through its bundle.
4. 4Global defaultThe fallback price ladder for the component. Required: every component needs at least one Global default published.

**Currency selection.** At each scope, Revvly looks for a row whose`pricesByCurrency` list contains the subscription’s currency. A Bundle-scope price with only USD won’t apply to an EUR subscription — the resolver keeps walking. This means you can ship a Bundle override in only the currencies where you actually want it, and fall through to Global for the rest.

**Shape matching.** A scope replaces the resolved price rather than merging into it, so every row has to carry the monetary fields its component’s model bills on — one rate per tier for a volume or graduated tiered component, one flat fee per step for a stairstep one, both halves of the committed and overage pair. A row carrying a single rate for a tiered component is rejected when you save it, at every scope, because it could never produce a charge. See [overriding component pricing](https://www.revvly.ai/docs/guides/override-pricing) for the field-by-field breakdown.

**Custom Pricing Agreements sit above all of this.** A Published[Custom Pricing Agreement](https://www.revvly.ai/docs/concepts/customPricingAgreement) for the same (customer, component) wins even over a Subscription scope. See the[private-deal guide](https://www.revvly.ai/docs/guides/custom-agreements) for the full flow.

Price resolution order

Most specific first

1. Custom Pricing AgreementPublished, for this customer and component.
2. Subscription scopeA price on this exact subscription.
3. Bundle scopeThe pinned bundle and version.
4. Module scopeA pinned module and version, directly or through the bundle.
5. Global defaultRequired fallback for every component.

Revvly stops at the first published row that matches the subscription's currency.

## The four scopes, with examples

### Global default

**When to reach for it.** Every component needs at least one Global default — the fallback used when no more-specific scope applies.

A Global default Variable Component Price ships the canonical numbers for a component, per currency. Most components will only ever need this one row.

```
Seats v2 → Global default → { USD: $5, EUR: €4.50, GBP: £4 }
```

### Module override

**When to reach for it.** Use when a specific module bundles the component at a different rate than the global default — for example, the “Analytics Module” gives a built-in seat discount.

Module-scoped prices target a single (Module id, Module version) pair. They apply to any subscription whose pinned module composition includes that exact module version.

```
Seats v2 → Module: Analytics v3 → { USD: $4 } (seats inside Analytics are cheaper)
```

### Bundle override

**When to reach for it.** Use to ship plan-level pricing — the Pro Bundle includes seats at one rate, Enterprise at another.

Bundle-scoped prices target a single (Bundle id, Bundle version) pair and beat module-scoped prices for subscriptions on that bundle.

```
Seats v2 → Bundle: Enterprise v1 → { USD: $3, EUR: €2.80 }
```

### Subscription override

**When to reach for it.** Use for one-off deals you don’t want as a Custom Pricing Agreement — typically while migrating a single customer or testing a new rate.

Subscription-scoped prices target a single subscription. They are the most specific scope and beat every other scope for that subscription only — which is why they must carry the component’s whole price, not just the figure being changed. If you need a richer override (different model, custom tiers, multi-axis change), prefer a Custom Pricing Agreement.

```
Seats v2 (flat) → Subscription: Acme’s prod sub → { USD: $2.50 }
Events v3 (3 tiers) → Subscription: Acme’s prod sub → { USD: [$0.010, $0.008, $0.005] }
```

## Why scopes, not Pricing Rules?

The original Revvly pricing model used [Pricing Rules](https://www.revvly.ai/docs/concepts/pricingRule) with a single price per Bundle × Region × Period. Scope-based component pricing replaces that with a layered model so you can express the same intent more locally: a regional override is just a Bundle-scope price in that region’s currency, an enterprise rate is a Bundle-scope price on the Enterprise bundle, a one-off discount is a Subscription scope or a Custom Pricing Agreement. The pricing engine still consults Pricing Rules for legacy subscriptions and for the bundle-pricing calculator, but new work should reach for the component model.

## Next up

- [Per-customer overrides with Custom Pricing Agreements ›](https://www.revvly.ai/docs/guides/custom-agreements)
- [How version pinning interacts with scope ›](https://www.revvly.ai/docs/guides/versioning)
- [The Variable Component Price concept ›](https://www.revvly.ai/docs/concepts/variableComponentPrice)

