API Request Metering
Track API traffic, customer activity, and request mix.
Use API request metering when each accepted request represents product usage. This is common for developer platforms, internal APIs, hosted services, and products with request-based plans.
Model
Create a meter such as api_requests with:
| Field | Value |
|---|---|
| Unit | request |
| Aggregation | sum |
| Quantity | Usually 1 per accepted request |
Useful dimensions:
endpointmethodstatus_coderegion-nameservice.tier
How To Use It
Record usage after your service accepts or completes the request. Use the customer, organization, account, or workspace as subject.
This lets you answer:
- How many requests did a customer make this billing period?
- Which endpoints are driving usage?
- How much traffic is erroring by status code?
- Which regions or service tiers serve the most traffic?
Use service.tier when request handling spans multiple internal service tiers. Send the event metadata as nested JSON:
{
"metadata": {
"endpoint": "/v1/orders",
"method": "POST",
"status_code": 201,
"region-name": "us-east",
"service": {
"tier": "gold"
}
}
}Queries still refer to the path by its dimension name, such as metadata.service.tier=gold or group_by=service.tier.
Example
Create a request meter with the dimensions you want to group by:
curl -X POST "$OPEN_SPANNER_BASE_URL/v1/meters" \
-H "Authorization: Bearer $OPEN_SPANNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "api_requests",
"description": "Accepted API requests",
"unit": "request",
"aggregation": "sum",
"event_retention_days": 90,
"dimensions": [
{ "name": "endpoint", "type": "string", "required": true },
{ "name": "method", "type": "string", "required": true },
{ "name": "status_code", "type": "number", "required": true },
{ "name": "region-name", "type": "string" },
{ "name": "service.tier", "type": "string" }
]
}'Record usage after a request is accepted or completed:
curl -X POST "$OPEN_SPANNER_BASE_URL/v1/usages" \
-H "Authorization: Bearer $OPEN_SPANNER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "req_01J0POSTORDERS",
"subject": "org_123",
"meter": "api_requests",
"quantity": 1,
"metadata": {
"endpoint": "/v1/orders",
"method": "POST",
"status_code": 201,
"region-name": "us-east",
"service": { "tier": "gold" }
}
}'Query daily request totals by endpoint:
curl "$OPEN_SPANNER_BASE_URL/v1/usages?meter=api_requests&subject=org_123&from=2026-06-01T00:00:00Z&to=2026-07-01T00:00:00Z&bucket_size=day&group_by=endpoint" \
-H "Authorization: Bearer $OPEN_SPANNER_API_KEY"