Integration guide
1. Create a project and a key
From your dashboard, create a project for the API you want to track, then generate an API key — optionally scoped to a specific client app.
2. Option A — ASP.NET Core middleware (automatic)
Reference the UsageWatch.Client project, then register it in Program.cs:
builder.Services.AddUsageWatch(options => { options.ApiKey = builder.Configuration["UsageWatch:ApiKey"]!; options.IngestBaseUrl = "https://usagewatch.yourdomain.com"; }); var app = builder.Build(); app.UseRouting(); app.UseUsageWatch(); // after UseRouting, before endpoints app.MapControllers();
Every request is queued in memory and delivered by a background service — it never blocks or slows down your API's response.
Telling UsageWatch which client made the call
UsageWatch never guesses who's calling — you tell it, using whichever of these fits your app (checked in this order, first match wins):
builder.Services.AddUsageWatch(options => { options.ApiKey = "uw_live_..."; options.IngestBaseUrl = "https://usagewatch.yourdomain.com"; // 1. Full control — read it however your app already knows the caller options.ClientIdentifierResolver = ctx => ctx.Items["TenantId"]?.ToString(); // 2. Or just read a header your callers send (this is the default: "X-Client-Id") options.ClientIdHeaderName = "X-Client-Id"; // 3. Or a query string param options.ClientIdQueryParamName = "client_id"; // 4. Or a claim on the authenticated user (JWT / API-key auth) options.ClientIdClaimType = "client_id"; });
If none of the configured strategies resolve a value for a given request, the call is still tracked and counted toward quota — it just won't show up broken out by client until one does.
3. Option B — plain REST call (any language)
POST https://usagewatch.yourdomain.com/api/ingest/usage X-Api-Key: uw_live_your_key_here Content-Type: application/json { "endpoint": "/v1/orders/123", "method": "GET", "statusCode": 200, "responseTimeMs": 42, "clientIdentifier": "acme-corp" }
Returns 200 with the current month's usage and quota, or 429 if the project's plan enforces a hard limit and the call is over quota.
4. Manual tracking from code
Inject IUsageWatchClient anywhere — background jobs, gRPC, custom endpoints — for full control over what gets recorded:
public class OrdersService(IUsageWatchClient usageWatch) { public void Handle() { usageWatch.Track("/v1/orders", "POST", 201, 84, clientIdentifier: "acme-corp"); } }
Quota enforcement
Each project has a monthly quota (from its plan, or a custom override). Turn on "Block calls once quota is exceeded" in project settings to have the ingestion endpoint return 429 Too Many Requests once a project goes over — otherwise calls are still logged and counted, just never blocked.