OBAPI OBAPI

Usage & Metering

Usage-based billing metrics for hosted services.

This capability lets a central billing system (typically the OBAPI client) pull consumption metrics from any hosted service (mail hosting, proxy, storage, Nextcloud, etc.) in a normalized way, without knowing the service internals.

The design is self-describing in two steps:

  1. The server declares which metrics it exposes (GET /obapi/v1/usage/metrics).
  2. The client asks for the values of those metrics for one account over a period (GET /obapi/v1/usage).

A service that only implements this capability is a valid minimal OBAPI server: its discovery response lists ["usage"] and nothing else.

Metric catalog

  • Method: GET /obapi/v1/usage/metrics
  • Headers: Authorization: Bearer {apikey}

Returns the list of metrics this server can measure. This endpoint takes no account parameter: it describes the service, not a specific customer.

{
    "metrics": [
        {
            "code": "storage_bytes",
            "label": "Storage used",
            "description": "Total disk space occupied by the account",
            "unit": "byte",
            "kind": "gauge",
            "aggregation": "last",
            "billable": true,
            "product_ref": "NC-STORAGE"
        },
        {
            "code": "user_count",
            "label": "Number of users",
            "unit": "count",
            "kind": "gauge",
            "aggregation": "max",
            "billable": true,
            "product_ref": "NC-USER"
        },
        {
            "code": "bandwidth_bytes",
            "label": "Bandwidth consumed",
            "unit": "byte",
            "kind": "counter",
            "aggregation": "sum",
            "billable": true,
            "product_ref": "PROXY-TRAFFIC"
        }
    ]
}

Metric object

Field Type Description
code string Stable machine identifier of the metric (see standard vocabulary below)
label string Human-readable name
description string Optional longer description
unit string Measurement unit, always an SI base unit (byte, count, second)
kind string gauge (point-in-time value) or counter (accumulated over the period)
aggregation string How to reduce the metric over a period: last, max, avg, sum
billable boolean Hint: this metric is meant to drive billing
product_ref string Optional. Product/service reference the metric maps to, for automatic line mapping

gauge vs counter

The distinction is essential to bill correctly over a period:

  • gauge -- a value that exists at a point in time (storage used, number of users). The server states how to reduce it over the period through aggregation (last = value at end of period, max = peak, avg = average).
  • counter -- a value accumulated during the period (bandwidth, sent emails). It is naturally reduced with aggregation: "sum".

The client MUST honor the declared aggregation and never guess.

Units

Units are always expressed as SI base units, never as multiples, so any tool can convert consistently:

Unit Meaning
byte bytes (not KB / MB / GB)
count a plain integer count
second seconds (not minutes / hours)

Standard metric vocabulary

To let tools auto-map metrics to products, common metrics SHOULD reuse these code values. Services MAY expose additional custom metrics prefixed with x- (for example x-antispam_rules).

Code Unit Typical kind Description
storage_bytes byte gauge Disk space occupied
bandwidth_bytes byte counter Network traffic over the period
user_count count gauge Number of user accounts
mailbox_count count gauge Number of mailboxes
mailbox_quota_bytes byte gauge Total mailbox quota allocated
email_sent_count count counter Emails sent over the period
request_count count counter Requests served over the period
compute_seconds second counter Compute time consumed

Metric values for an account

  • Method: GET /obapi/v1/usage
  • Headers: Authorization: Bearer {apikey}
Parameter Type Required Description
account string yes Account identifier -- the customer email address on the service
period string no Billing period YYYY-MM (default: current month)
metrics string no Comma-separated list of metric codes to restrict the response

Account identification

The account parameter is the email address of the customer account on the service. It is the natural business key for mail, storage and proxy hosting, and the central billing system already knows it from the customer record.

A customer holding several accounts on the same service (several mailboxes, several users) is represented as several accounts: one request per account. The central system is responsible for summing per-customer if needed.

Response

{
    "account": "client@example.com",
    "period": {
        "start": "2026-06-01",
        "end": "2026-06-30",
        "granularity": "month"
    },
    "measures": [
        {
            "code": "storage_bytes",
            "value": "48318382080",
            "unit": "byte",
            "captured_at": "2026-06-30T23:59:59Z"
        },
        {
            "code": "user_count",
            "value": "12",
            "unit": "count"
        },
        {
            "code": "bandwidth_bytes",
            "value": "912680550400",
            "unit": "byte"
        }
    ]
}

Measure object

Field Type Description
code string Metric code, matching a code from the catalog
value string Value as a decimal string (never a float) in the metric unit
unit string Unit of the value, echoed from the catalog
captured_at string Optional. ISO 8601 timestamp when a gauge value was read

Errors

If the account is unknown to the service:

{
    "error": {
        "type": "not_found",
        "code": "ACCOUNT_NOT_FOUND",
        "message": "No account matches the provided identifier"
    }
}

Reference implementation

A single-file PHP example implementing this capability on top of a Nextcloud instance is available in the repository: examples/usage-nextcloud.php. It is a complete minimal OBAPI server (discovery + usage only, no dependency but curl) that maps a customer account (email) to a Nextcloud group and reports the group's total storage used and user count via the OCS Provisioning API.

Example calls:

GET /                    -> { "capabilities": ["usage"], ... }
GET /usage/metrics       -> { "metrics": [ storage_bytes, user_count ] }
GET /usage?account=client@example.com&period=2026-06
                         -> { "measures": [ ... ] }