> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.solvimon.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.solvimon.com/_mcp/server.

# Designing your meters & events

What you can price, report on, and change later depends on the usage events you send. This page covers how to design them: work backward from what you need, work forward from what you have, and maximize your flexibility.

Solvimon's metering system can handle around 1 million transactions per second - suited for the most demanding workflows.

---

## Why this matters

Pricing plans can be reconfigured in minutes; the shape of the usage data feeding them cannot. Getting the split right up front, raw facts in events and billing logic in meters and plans, is the highest-leverage design decision in a Solvimon integration.

## Events carry facts, meters carry logic

A [usage event](/platform-guides/meter-and-event-design/usage-events) is a record of something that happened in your product: an API call, a completed job, a seat added. A [meter](/platform-guides/meter-and-event-design/meter) defines how those events are filtered and aggregated into a billable quantity.

Keep the billing logic out of your events. If you pre-aggregate ("total API calls this month: 41,203"), every pricing change, whether new tiers, new dimensions, or per-region pricing, needs an engineering change on your side. If you send one event per action, pricing changes are configuration in Solvimon.

## Start from what you need

Start from the invoice you want to produce and derive the minimum event that supports it. Suppose you charge for API calls. The billable number is "count of `api_calls` events, per customer, per billing period", so the minimum event is:

**`One event per action, with dimensions as properties`**

```json One event per action, with dimensions as properties
{
  "meter_reference": "api_calls",
  "customer_reference": "cust_8271",
  "timestamp": "2026-07-01T10:50:00+02:00",
  "reference": "evt_01J8ZQ3FJ2",
  "meter_properties": [
    { "reference": "endpoint_group", "value": "search" },
    { "reference": "region", "value": "EU" }
  ],
  "meter_values": [
    { "reference": "call_count", "number": "1" }
  ]
}
```

The exact pricing doesn't need to be settled just yet as prices, tiers, and commitments are plan configuration and can be applied or adjusted later, as long as the metric exists.

Invoicing is also not the only consumer: the same events power [usage limits and threshold alerts](/platform-guides/meter-and-event-design/usage-limits) and cost dashboards, so factor those requirements in too.

Two decisions should be derived from your needs:

1. **Choose the billable actions.** One meter per action (`api_calls`, `gb_processed`, `seats`, `megapixels_generated`), not per their price point. For example, "Premium API calls" is a property on `api_calls` and not a separate meter.
2. **Pick the aggregation.** A meter value plus a calculation method makes a [usage metric](/platform-guides/meter-and-event-design/meter/calculation-methods). Is the billable number a **count** of events (API calls), a **sum** of a value (GB processed, tokens), or a **max/last** of a level (seats, storage)? Levels deserve care: for seats, send the current seat count as a gauge (aggregated with max or last) rather than +1/−1 deltas, which corrupt the total if one event is lost.

## Work forward from what you already have built

The usage is recorded in your system today usually decides when and where you send events.

* If you have a central event stream or log pipeline, send one event per action as it happens. This is the best case: maximum granularity and best visibility.
* If usage only exists as periodic summaries (per node, per data source), send those summaries over the shortest window you can tolerate, for example per hour per customer, never per billing period. Keep any aggregation on your side a pure rollup of raw facts; pricing logic stays in Solvimon.
* Send events from the place that can resolve the customer. If edge systems don't know your customer IDs, aggregate centrally where the lookup is possible rather than sending events without a reliable `customer_reference`.

Always consider these best-practices:

* **Make references idempotent.** The event `reference` is your idempotency key: the first event with a given reference is processed, any later event with the same reference is flagged `DUPLICATE` and ignored. Derive it deterministically from the action in your system (for example your transaction GUID) so retries are safe. See [event ingestion best practices](/platform-guides/meter-and-event-design/usage-events/event-ingestion-api).
* **Timestamp when usage happened, not when you sent it.** The `timestamp` places the usage in the right billing period, including backfills.

## Maximize your flexibility for the future

Requirements frequently change in pricing and packaging. Since you can't anticipate all of it, you can make sure the data is already there when it arrives.

We recommend sending more events than you need today. Anything that might affect the price of the same action, or that anyone might want to slice usage by, belongs in `meter_properties`: region, endpoint group, model, plan tier. An unused property costs nothing; a missing one costs an engineering change and leaves you with no history for events already sent. With the property in place, a new requirement like per-region pricing is a [pricing rule](/platform-guides/products-and-pricing/pricing-plans/usage-based-pricing-methods/pricing-rules) conditioning on `region`, not a code change.

Two constraints on properties that you should take into account:

* Use a small, stable set of values. Don't send unbounded values (raw URLs, user IDs) as properties. Use something like a country ISO code.
* Properties used in pricing conditions must be configured as **required** on the meter.

> **Tip**
>
> Send usage as granularly as you can. Aggregation is the meter's job; granular events keep every future pricing model open.

### You don't have to define everything up front

Solvimon supports [dynamic meter creation](/platform-guides/meter-and-event-design/meter/dynamic-meter-creation): pass `meter_validation=DYNAMIC` on the [ingest call](https://docs.solvimon.com/api-docs/event-api/ingest/post-ingest-meter-data) and missing meters, values, and properties are created on the fly from the events themselves. This lets you start sending rich events immediately and let the meter configuration follow, which is useful while your usage model is still evolving.

## Common mistakes to avoid with meters

| Mistake                                         | Cost                                                                 |
| ----------------------------------------------- | -------------------------------------------------------------------- |
| Pre-aggregated events per billing period        | Every pricing change needs engineering; no real-time cost visibility |
| One meter per price point instead of properties | Meter sprawl; can't restructure tiers without new meters             |
| Random or timestamp-based event references      | Retries create duplicates that bill twice                            |
| Seat changes as +1/−1 deltas                    | One lost event corrupts the seat count for the whole period          |
| Optional properties used in pricing rules       | Events price incorrectly or fail to match                            |

## Where to go next

* [Meters](/platform-guides/meter-and-event-design/meter): meter values, properties, and calculation methods in detail
* [Usage events](/platform-guides/meter-and-event-design/usage-events): ingestion API, file uploads, and manual ingestion
* [Unmatched events](/platform-guides/meter-and-event-design/unmatched-events): what happens when events don't match a meter
* [Event reprocessing](/platform-guides/meter-and-event-design/event-reprocessing): fixing configuration and recalculating