Open Spanner
Concepts

Meter Dimensions

Use meter dimensions to filter and group usage events.

Meter dimensions are the contextual fields attached to usage events. In Open Spanner, dimensions are defined on the meter and values are sent in each usage event's metadata object.

Use dimensions to answer questions such as:

  • How many requests came from each region?
  • How many tokens were used by each model?
  • Which plan generated the most usage?
  • How much usage came from production versus staging?

Define Dimensions On The Meter

Open Spanner validates event metadata against the meter's dimensions.

{
  "name": "api_requests",
  "unit": "request",
  "aggregation": "sum",
  "dimensions": [
    { "name": "region-name", "type": "string", "required": true },
    { "name": "service.tier", "type": "string", "required": true },
    { "name": "status_code", "type": "number", "required": true },
    { "name": "cache_hit", "type": "boolean", "required": false }
  ]
}

Supported dimension types are:

  • string
  • number
  • boolean

Send Dimension Values With Usage

Every usage event for a meter must match that meter's dimensions.

{
  "subject": "org_123",
  "meter": "api_requests",
  "quantity": 1,
  "idempotency_key": "usage_001",
  "metadata": {
    "region-name": "us-east",
    "service": {
      "tier": "gold"
    },
    "status_code": 200,
    "cache_hit": true
  }
}

Required schema-backed dimensions must be present and must match their configured type. Optional dimensions may be omitted. Extra metadata is accepted and stored, but dimensions defined on the meter are the stable fields to use for dashboard filtering, grouping, and export.

Dotted dimension names represent nested metadata paths. A meter can define service.tier, while the usage event sends the value as nested JSON:

{
  "metadata": {
    "service": {
      "tier": "gold"
    }
  }
}

Open Spanner also accepts a flat key such as "service.tier": "gold" for a defined dotted dimension and stores it as nested metadata. Prefer nested JSON in new code because it is easier to extend over time.

Discover Dimension Values

Open Spanner can list observed values for a dimension. Use this when you want to build filter pickers, audit which values are being sent, or help users choose valid grouping values.

curl "http://localhost:18081/v1/usages/dimensions?meter=api_requests&field=service.tier&from=2026-06-01T00:00:00Z&to=2026-06-10T00:00:00Z" \
  -H "Authorization: Bearer osp_live_your_api_key"

Add subject=org_123 when you only want values observed for one subject.

The response is ordered by the number of matching usage events:

{
  "items": [
    { "field": "service.tier", "value": "gold", "events": 128 },
    { "field": "service.tier", "value": "silver", "events": 42 }
  ]
}

The dashboard usage page uses discovered values to make metadata filters easier to select.

Rank Dimension Values By Usage

Discovery answers "which values exist?" Breakdowns answer "which values matter most for this query?"

Use breakdowns when you want top endpoints, plans, regions, models, or other dimensions by aggregated usage:

curl "http://localhost:18081/v1/usages/breakdowns/search" \
  -H "Authorization: Bearer osp_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "meter": "api_requests",
    "field": "endpoint",
    "from": "2026-06-01T00:00:00Z",
    "to": "2026-06-10T00:00:00Z",
    "limit": 5
  }'

The response is ordered by aggregated quantity, then value:

{
  "items": [
    {
      "field": "endpoint",
      "value": "/api/orders",
      "quantity": 9312,
      "events": 412,
      "aggregation": "sum",
      "unit": "request"
    },
    {
      "field": "endpoint",
      "value": "/api/users",
      "quantity": 6420,
      "events": 305,
      "aggregation": "sum",
      "unit": "request"
    }
  ]
}

Use field: "subject" to rank subjects by usage without adding subject to the meter schema.

Query By Dimension

Use metadata filters for direct queries:

curl "http://localhost:18081/v1/usages?meter=api_requests&from=2026-06-01T00:00:00Z&to=2026-06-10T00:00:00Z&bucket_size=day&metadata.service.tier=gold" \
  -H "Authorization: Bearer $OPEN_SPANNER_API_KEY"

Use group_by to split buckets by one or more dimensions. Repeat the query parameter or send a comma-separated list:

curl "http://localhost:18081/v1/usages?meter=api_requests&from=2026-06-01T00:00:00Z&to=2026-06-10T00:00:00Z&bucket_size=day&group_by=service.tier&group_by=region-name" \
  -H "Authorization: Bearer $OPEN_SPANNER_API_KEY"

The search endpoint accepts the same grouping as an array:

{
  "meter": "api_requests",
  "from": "2026-06-01T00:00:00Z",
  "to": "2026-06-10T00:00:00Z",
  "bucket_size": "day",
  "group_by": ["service.tier", "region-name"]
}

The dashboard usage page uses the same dimension fields for filtering and grouping. Grouping by several fields returns one bucket per unique dimension combination.

subject is built in, not part of dimensions, but it can be used with group_by:

curl "http://localhost:18081/v1/usages?meter=api_requests&from=2026-06-01T00:00:00Z&to=2026-06-10T00:00:00Z&bucket_size=day&group_by=subject&group_by=service.tier" \
  -H "Authorization: Bearer $OPEN_SPANNER_API_KEY"

Use this when you want a report like daily requests by customer and service tier.

Good Dimension Names

Choose names that are stable, short, and meaningful across services:

  • region
  • region-name
  • plan
  • service
  • service.tier
  • environment
  • model
  • route
  • status_code

Dimension names can use letters, numbers, underscores, hyphens, and dots. Dots are useful for nested metadata paths such as service.tier or request.region. Avoid spaces, slashes, leading dots, trailing dots, and empty dot segments.

subject is reserved for the built-in subject field. You can group and filter by subject without adding it to dimensions.

Avoid putting high-cardinality values in dimensions unless you really need to query by them. Request IDs, trace IDs, and raw payload values are usually better left out of dimensions.

Planned Direction

Open Spanner may add more dimension management over time, such as richer dashboard controls, dimension catalogs, and looser ingestion modes. Today, dimensions are explicit and schema-backed.

On this page