Managing Customer Segments
Dynamic, reusable filters that group customers together.
Customer segments are dynamic, reusable filters that group customers by any combination of plan, type, metadata, usage, or margin. Once defined, a segment can be referenced by notifications (to scope alerts to specific customers) and by pricing rules (to apply different prices to a subset of customers without changing the plan).
Segments are workspace-level — shared with all members of your team and applied to both test and live environments.
What a segment is
A segment is a named condition. At runtime, Limitr evaluates the condition against each customer object and the live policy to determine whether the customer matches. The condition is a Stof expression that returns a truthy value for matching customers.
Three variables are available in every condition:
customer — The full customer object: customer.id, customer.plan, customer.type, customer.label, customer.meters, customer.grants, customer.metadata, customer.cloud_created, customer.cloud_updated.
policy — The active Limitr policy API. Call ?policy.entitlement(customer.id, name), ?policy.limit(customer.id, name), ?policy.value(customer.id, name), ?policy.customer_local_margin_breakdown(customer.id), and other policy methods directly from the condition.
data — A shorthand alias for customer.metadata. Use data.my_key instead of customer.metadata.my_key.
Conditions are evaluated per-customer whenever a matching event fires (for notifications) or when resolving the effective price for a billable action (for pricing rules).
Creating a segment
Navigate to Customer Segments in the dashboard and click + New Segment. Give the segment a name and optional description, then define the condition.
Simple mode
A point-and-click condition builder. Add one or more conditions using these types:
| Type | Description |
|---|---|
| Plan | Match customers on a specific plan. Selects from your policy's plan list. |
| Customer Type | Match by customer type string: user, org, or any custom type. |
Match by customer.metadata.email. Supports ==, !=, contains, starts_with, ends_with. | |
| Metadata Key | Match by any key in customer.metadata. Supports all comparison operators. Values are auto-coerced to boolean, number, or string. |
| Created | Match customers created before or after a specific date. |
All conditions are combined with AND — a customer must satisfy every condition to match. Simple mode converts your conditions to Stof automatically. Switch to Advanced mode at any time to see and edit the generated expression.
Advanced mode (Stof)
A code editor for writing the condition directly in Stof. The editor validates syntax in real time — a green ✓ valid indicator means the expression parses correctly. The last expression in the condition is the return value; truthy means the customer matches.
customer.plan == "growth"
customer.plan == "enterprise" && customer.type == "org"
// Match customers with a specific metadata field
data.internal_tier == "pilot"
Advanced mode is required for conditions involving policy calls, meter state, or multi-step logic.
Templates
The From template… dropdown provides six ready-to-use conditions that cover the most common operational use cases. Applying a template switches to Advanced mode with the condition pre-filled.
Recently Created
Customers created within the last 7 days.
const ts: ms = Time.now() - 7days;
customer.cloud_created != null && customer.cloud_created > ts
Active Customers
Customers updated within the last 30 days.
const ts: ms = Time.now() - 30days;
customer.cloud_updated != null && customer.cloud_updated >= ts
Inactive Customers
Customers not updated in the last 30 days.
const ts: ms = Time.now() - 30days;
customer.cloud_updated != null && customer.cloud_updated < ts
Overage
Customers with at least one entitlement where the meter has exceeded a soft limit.
for (const field in customer.meters.fields()) {
const name = field[0];
const ent = ?policy.entitlement(customer.id, name);
if (ent != null && ent.limit != null && ent.limit.mode == 'soft') {
const limit = ?policy.limit(customer.id, name);
const current = ?policy.value(customer.id, name);
if (limit != null && current != null && current > limit) return true;
}
}
false
Hard Limit Imminent
Customers with a hard-limited entitlement at 90% or more of its limit.
for (const field in customer.meters.fields()) {
const name = field[0];
const ent = ?policy.entitlement(customer.id, name);
if (ent != null && ent.limit != null && ent.limit.mode == 'hard') {
const limit = ?policy.limit(customer.id, name);
const current = ?policy.value(customer.id, name);
if (limit != null && current != null && current >= limit * 0.9) return true;
}
}
false
Negative Snapshot Margin
Customers with a negative margin in the current snapshot.
const snapshot = ?policy.customer_local_margin_breakdown(customer.id);
(?snapshot.get('margin') ?? 0) < 0
Custom condition examples
Customers on Growth or Enterprise
customer.plan == "growth" || customer.plan == "enterprise"
Org customers only
customer.type == "org"
Enterprise orgs with more than 20 seats used
customer.type == "org" &&
customer.plan == "enterprise" &&
(?policy.value(customer.id, "seats") ?? 0) > 20
Customers with a specific metadata tag
data.billing_tier == "custom" || data.account_manager != null
Customers with active grants
customer.grants != null && customer.grants.fields().len() > 0
High-value customers approaching their limit
for (const field in customer.meters.fields()) {
const name = field[0];
const ent = ?policy.entitlement(customer.id, name);
if (ent != null && ent.limit != null && ent.limit.mode == 'hard') {
const pct = ?policy.value(customer.id, name, true);
if (pct != null && pct >= 80) return true;
}
}
false
Using segments in notifications
When creating a notification, you can scope it to a segment. The notification only fires for customers that match the segment condition at the time the event occurs.
For example: a meter-overage notification that should only alert your team when a Growth or Enterprise customer goes into overage — not every free-tier user. Create a segment for customer.plan == "growth" || customer.plan == "enterprise" and attach it to the notification.
Segment evaluation in notifications is real-time. A customer who upgrades from Starter to Growth immediately starts matching a Growth segment — no re-sync required.
Using segments in pricing rules
Pricing rules let you apply a different price to a segment of customers without changing the plan. The rule specifies a segment and a set of price overrides keyed by target (credit:name, topup:name).
When Limitr resolves the effective price for a billable action, it evaluates segment conditions in priority order. The first matching rule's overrides apply. If supersedes: 'customer-overrides' is set on the rule, it takes precedence even over per-customer price overrides.
Pricing rules are configured in the dashboard under your policy settings. Define the segment first, then reference it in the rule.
Setting an active segment
On the Segments page, each segment has a Set Active button. The active segment filters the customer view across the dashboard — the customer list, margin views, and usage tables all apply it as a filter.
This is how you scope your operational view to a specific group: "show me only Growth customers in overage" or "show me only customers created this week."
Only one segment can be active at a time. Click Set Active on a different segment to switch, or click the active segment's button again to clear it.
Editing and deleting segments
Click Edit on any segment row to modify its name, description, or condition. Changes take effect immediately — notifications and pricing rules referencing the segment use the updated condition on the next evaluation.
Changing a segment condition affects all notifications and pricing rules that reference it. Review those before saving a condition change.
Click Delete to remove a segment. Notifications and pricing rules that reference it by ID are not automatically updated — update those separately before deleting the segment.