Skip to content
UsageRail

API analytics by customer and endpoint

Updated October 20, 2026

API analytics for a paid API should answer three questions: who is calling, which endpoints they use, and what happened to each request. With UsageRail, one middleware in your API server counts every request by customer, endpoint and outcome, and your dashboard shows those numbers next to each customer's quota and billing. Counting and quotas work today; the billing side, through Stripe, isn't live yet.

What API analytics should show

If you sell API access, traffic graphs aren't enough. Useful API usage analytics tie each request to a customer and a price:

QuestionWhat to look at
Who uses the API, and how much?Requests and units per customer, per day
Which endpoints matter?Requests per endpoint, grouped by method and route template
Is anything failing?Outcomes: 2xx, 3xx, 4xx, 5xx, and requests rejected before your handler ran
Who is about to hit a limit?Usage against each customer's quota and rate limit
What will each customer pay?This period's usage, priced against their plan

Two details make these numbers usable. First, group endpoints by route template (GET /v1/users/:id), not by raw path (/v1/users/8231), or every ID becomes its own row. OpenTelemetry's HTTP conventions make the same call: its http.route attribute is "the matched route template" and must be low-cardinality. Second, count in the unit you charge for. If you price per token or per page, request counts alone say little about revenue.

What UsageRail records

The SDK counts each request in memory and groups the counts by four things:

DimensionWhat it holds
CustomerThe customer who owns the API key, or your own customer ID (hashed by default) if you keep your own authentication
EndpointHTTP method plus route template. Past 500 distinct routes, the rest are grouped as _other
Outcome2xx, 3xx, 4xx, 5xx or aborted, plus four rejections the SDK makes itself: a key that's invalid, revoked or expired; a customer you've suspended; a rate limit or quota reached; prepaid credits used up
MinuteThe minute the request started

Each group holds two numbers: the request count and the units. A request counts as 1 unit unless you say otherwise. Call track(units) in a handler to count tokens, rows or pages instead, or give a route a fixed weight, such as 10 units per call to an image endpoint.

Only 2xx and 3xx responses count toward billing. Client errors, server errors, aborted requests and the SDK's own rejections are recorded so you can see them, but never billed. A WebSocket connection counts once, when it opens.

How the counts feed limits and invoices

Quotas and invoices use the billable part of those counts (2xx and 3xx), and after each period UsageRail checks what Stripe billed against its own total:

  • A stop-at-limit plan answers a customer who has used up the period's quota with a 429 (quota_exceeded) and a Retry-After that runs to the end of the period. A prepaid plan returns a 402 (insufficient_credits) when the balance runs out. An overage plan doesn't stop customers at the quota. It bills the extra at the end of the period, and rate limits still apply.
  • At 80% and 100% of a quota, the customer gets an email and you get a webhook. You can change the percentages.
  • Two hours after a billing period ends, UsageRail sends Stripe one usage event per customer, and it shows up on that customer's Stripe invoice. Mid-period usage is visible in UsageRail (your dashboard, the customer portal and the usage widget), not in Stripe's upcoming invoice. Metered billing explains the period-end model.
  • Each customer sees their own daily usage and a breakdown by endpoint in the customer portal, so "why is my bill higher this month?" has an answer they can look up.

What we don't collect

The SDK doesn't send us request or response bodies, and it doesn't record IP addresses or raw API keys. We receive per-minute totals, not individual requests, so there's no request log to search. There are no response times either: UsageRail counts usage and doesn't measure latency. If you need traces, latency percentiles or payload inspection, keep your APM or logging tool for that job.

How the SDK collects it

Add one middleware to your API server. In Express it looks like this (the SDK is still in development, so names may change before release):

js
import { usageRail } from "@usagerail/node/express";

app.use(usageRail({ appKey: process.env.USAGERAIL_APP_KEY, auth: "api-key" }));

app.post("/v1/generate", async (request, response) => {
  const result = await generate(request.body);
  request.usageRail.track(result.tokens); // optional: count tokens instead of requests
  response.json(result);
});

What happens after that:

  • Requests never pass through UsageRail. The SDK checks keys and limits inside your process and keeps counts in memory.
  • Counts are grouped per minute and sent to us in batches every 60 seconds.
  • SDKs cover Node.js (Express, Hono, Fastify, Next.js) and Python (FastAPI, Flask, Django), under the MIT license. Other languages can call an HTTP check endpoint, at the cost of one extra network call per request.
  • Our design target is under 1 ms of added time per request at p99 once keys and limits are loaded. It stays a target until we publish the benchmark.
  • If a process is killed hard (kill -9, out of memory), up to about 10 minutes of unsent counts are lost and never billed.

How far back you can look depends on your UsageRail plan: 7 days on Free, 30 on Starter, 90 on Growth and 365 on Scale. See pricing.

Other ways to get API analytics

ApproachExampleGood atGaps for a paid API
Gateway access logsAWS API GatewayA line per request with the fields you chooseYou build the pipeline that turns log lines into per-customer usage, and nothing ties it to billing
APMDatadogRequests, errors and latency per endpoint, plus tracesPer-customer views need your own span tags, with no link to plans or invoices
Product analyticsPostHogTrends, funnels and retention on events you sendAn event per API call adds up fast, and the counts don't drive limits or invoices
API analytics toolsMoesif, ApitallyAPI metrics and request logs from a few lines of middleware. Moesif also inspects payloads and can report usage to StripeAnother SDK and data pipeline to run next to your keys, limits and billing code

UsageRail uses the same per-customer counts for API usage tracking, quotas and billing. Keep your existing tools for latency, payload inspection and request logs.

See usage by customer next to what you bill them

Requests by customer, endpoint and outcome, shown next to each customer's quota and this period's bill.

Start free

Stripe billing isn't live yet. Keys, rate limits, quotas and the portal work today.