Xtopay

Usage-Based Billing

Meter API requests, compute events, and bill customer dynamically.

Usage-Based Billing

Usage-based (or metered) billing allows you to charge customers based on their active consumption of your service (e.g. database storage, AI API tokens, text messages, or seat logs).


How it Works

  1. Define a Meter: Set up a meter tracking a specific event type (e.g. api_request) and choose an aggregation strategy.
  2. Link Price to Meter: Create a product price that links to the meter. Define how much each aggregated unit costs.
  3. Ingest Events: Call the Xtopay API in real-time as customers consume resources.
  4. Automatic Billing: At the end of the billing period, Xtopay aggregates the events and compiles the renewal invoice.

Aggregation Strategies

When creating a meter, choose one of these aggregation strategies to calculate the customer's total usage:

  • SUM: Sums the values of all ingested events (e.g. total gigabytes of transfer).
  • COUNT: Counts the total number of events (e.g. total API calls made).
  • MAX: Takes the maximum event value recorded (e.g. maximum peak concurrent server seats).
  • LAST: Takes the value of the most recently ingested event.

Define a Meter

Create a new meter to start tracking a billable metric.

POST /v1/meters

Request Scopes

  • meters:write

Request Parameters

ParameterTypeRequiredDescription
namestringYesHuman-readable name of the meter (e.g. "AI GPT-4 Token Meter").
eventNamestringYesThe exact event name you will use when sending events (e.g. "gpt4_tokens"). Must be unique.
aggregationstringNoStrategy to sum/aggregate usage: SUM, COUNT, MAX, LAST. Defaults to SUM.
valueFieldstringNoThe JSON key in the event payload containing the quantity. Defaults to "value".

Example Request

curl https://api.xtopay.co/v1/meters \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "AI Text Ingestion",
    "eventName": "ai_words_processed",
    "aggregation": "SUM",
    "valueField": "value"
  }'

Example Response

{
  "success": true,
  "data": {
    "id": "met_cl8z2e...",
    "name": "AI Text Ingestion",
    "eventName": "ai_words_processed",
    "aggregation": "SUM",
    "valueField": "value",
    "active": true,
    "createdAt": "2026-06-05T12:00:00Z",
    "updatedAt": "2026-06-05T12:00:00Z"
  }
}

Ingest a Usage Event

Submit usage data in real-time as a customer consumes services. Xtopay supports high-throughput event ingestion.

POST /v1/meters/:id/events

Request Scopes

  • meters:write

Request Parameters

ParameterTypeRequiredDescription
customerIdstringNoThe customer ID to associate with the usage.
valuenumberNoThe numeric count/quantity to ingest. Defaults to 1.
timestampstringNoISO 8601 date string when the event occurred. Defaults to the current server time.
idempotencyKeystringNoA unique string to prevent double-ingesting the exact same event. Duplicate keys are safely ignored.
metadataobjectNoOptional key-value object containing transaction metadata.

Example Request

curl https://api.xtopay.co/v1/meters/met_cl8z2e.../events \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_cl8z2e9z...",
    "value": 150,
    "idempotencyKey": "evt_unique_1289182391283",
    "metadata": {
      "modelUsed": "gpt-4o"
    }
  }'

Example Response

{
  "success": true,
  "data": {
    "id": "mte_cl8z2f...",
    "meterId": "met_cl8z2e...",
    "customerId": "cust_cl8z2e9z...",
    "value": 150,
    "idempotencyKey": "evt_unique_1289182391283",
    "timestamp": "2026-06-05T12:05:00Z",
    "metadata": {
      "modelUsed": "gpt-4o"
    },
    "createdAt": "2026-06-05T12:05:00Z"
  }
}

Query Ingested Events

Fetch the logs of usage events recorded by a specific meter.

GET /v1/meters/:id/events

Request Scopes

  • meters:read

Query Parameters

ParameterTypeDescription
customerIdstringFilter logs by customer ID.
fromstringISO 8601 date string. Filter events created on or after this date.
tostringISO 8601 date string. Filter events created on or before this date.
limitintegerMaximum results to return per page (range 1–100, default 20).
cursorstringPagination cursor. Retrieve from the nextCursor value of a previous response.

Example Request

curl "https://api.xtopay.co/v1/meters/met_cl8z2e.../events?customerId=cust_cl8z2e9z...&limit=10" \
  -H "Authorization: Bearer YOUR_SECRET_KEY"

How is this guide?

Edit this page on GitHub
Last updated on June 6, 2026

On this page