Metering quickstart

Create a meter and ingest reproducible usage from your server.

Prerequisites

Use a staging merchant key with the required meter/usage access and a customer belonging to that merchant. A meter counts consumption; a price and subscription determine how it is billed. Ingesting an event does not itself mean a payment was taken.

Create a meter with REST

This Node.js example includes the /v2 base path and checks HTTP errors. Store secrets in environment variables on your server.

const apiKey = process.env.REVKEEN_API_KEY;
if (!apiKey) throw new Error("Set REVKEEN_API_KEY to a staging merchant secret");
async function request(path, options = {}) {
  const response = await fetch(`https://staging-api.revkeen.com/v2${path}`, {
    ...options,
    headers: { "x-api-key": apiKey, "Content-Type": "application/json" },
  });
  if (!response.ok) throw new Error(`RevKeen request failed (${response.status})`);
  return response.json();
}
const meter = await request("/meters", {
  method: "POST",
  body: JSON.stringify({ name: "API calls", event_name: "api_call", aggregation: "count" }),
});
console.log(meter);

For sum, max, or last, select a numeric value_key or the supported arithmetic value_expression. For count_unique, set unique_count_key. Filters determine which events match. Inspect a small sample before enabling billing.

Ingest with the published TypeScript helper

Install @revkeen/sdk@1.20260822.1541. This release has usage.ingest; it does not have the complete regenerated meter/event-query surface.

import { RevKeenClient } from "@revkeen/sdk";
const apiKey = process.env.REVKEEN_API_KEY;
const customerId = process.env.REVKEEN_CUSTOMER_ID;
if (!apiKey || !customerId) throw new Error("Set staging key and customer UUID");
const client = new RevKeenClient({ apiKey, baseUrl: "https://staging-api.revkeen.com/v2" });
const result = await client.usage.ingest({
  events: [{
    name: "api_call",
    customer_id: customerId,
    quantity: 1,
    idempotency_key: "request_8b742e_completed",
    metadata: { environment: "staging" },
  }],
});
console.log(result);

Replace the sample key with a stable identifier derived from your own business event. Persist it before sending. A retry of that event must retain the same key and payload. Up to 1,000 events can be submitted per request; inspect each result rather than treating the HTTP status as all-or-nothing success.

OutcomeWhat to do
ingestedRecord the accepted event identifier.
duplicateReconcile the original event; do not submit a new key to force acceptance.
skippedInspect why the event was not billable or matched.
failedCorrect the reported validation/input problem; retain an audit trail.

All-duplicate results can return 200; mixed results can return 207. A missing idempotency key or malformed quantity is rejected. Retry transport failures with bounded backoff and the original identity, and honour Retry-After for rate limits.

Time and customer identity

Use the real occurrence timestamp in RFC 3339 format, not the retry time. Billing periods use [start, end) boundaries. Customer UUID, external customer reference, and optional subscription/meter filters serve different purposes; do not send another merchant's identifiers.

A percentage-priced meter interprets its input quantity as minor currency units. A count meter counts events. Agree the unit with the meter configuration before ingestion; never interchange currency, minor units, and consumption quantities.

Next: Inspect usage and invoice provenance.

On this page