Reach for an SDK when your service already knows who the customer is and what to count, and you want Aforo to own buffering, batching, and retry. Every SDK is emit-only: track(...) pushes onto an in-memory buffer and returns immediately, and a background worker flushes batches to the ingestor — so metering never sits in your request path.
No gateway present
Internal microservices, background jobs, or CLI tools that bypass the API gateway
Drop-in middleware
Meter one event per HTTP request with a framework adapter (Express, FastAPI, Chi, a Spring filter) — no per-route code
Custom metering logic
Count computed metrics (tokens processed, MB stored, minutes elapsed) that the gateway never sees, with a manual track() call at the point you know the quantity
Hybrid coverage
Gateway plugins meter edge traffic; SDKs meter the internal services and batch jobs behind them
INFO
All four SDKs live in one public distribution repo: github.com/aforoai/SDKs (under aforo-metering-sdks/). The install commands below show the intended public package names; where a package isn't on its registry yet, clone or Download ZIP from the repo and install from source. Workspace scope comes from the API key; there is no tenantId argument, and these SDKs only emit usage — they do not read entitlements or block requests.
Pick your language — the tab below switches the install command and a copy-paste quickstart.
@aforo/metering requires Node 18+ (it uses the built-in fetch). Events POST to https://ingest.aforo.ai/v1/ingest/batch.
terminal
# Not yet on npm — clone or Download ZIP and install from source:
git clone https://github.com/aforoai/SDKs.git
cd SDKs/aforo-metering-sdks/node
npm install && npm run build && npm pack
# then in your app:
npm i /path/to/aforo-metering-1.0.0.tgz
Manual Tracking
usage.js
import { AforoClient } from '@aforo/metering';
const aforo = new AforoClient({ apiKey: process.env.AFORO_API_KEY });
// Count one billable action — non-blocking, flushes in the background
await aforo.track({
customerId: 'cust_123',
metricName: 'api_calls',
quantity: 1,
});
// Flush remaining events before the process exits:
await aforo.shutdown();
Express Middleware
app.js
import { expressMiddleware } from '@aforo/metering/middleware/express';
// Meters every request after the response is sent — zero added latency
app.use(expressMiddleware({
apiKey: process.env.AFORO_API_KEY,
customerId: (req) => req.user?.id ?? null, // return null to skip metering
}));
The middleware hooks res.on('finish'), so it runs after the response. The default metric name is "<METHOD> <normalized-path>" (e.g. GET /users/:id). Fastify and Koa adapters live under the same @aforo/metering/middleware/* path.
The same public repo carries metering clients beyond the four base SDKs above. Clone it — or use Download ZIP — and follow each package's README; every package ships its own install + usage steps.
Protocol SDKs
Meter at the protocol layer instead of per-HTTP-request. Each protocol ships for Node, Python, Go, and Java — e.g. aforo-metering-sdks/node-graphql, python-grpc. The exact call API is in each package's README.
ProtocolWhat it metersPackage suffix
GraphQLOperations (query/mutation/subscription) with complexity scoring{lang}-graphql
Where it runsAt the edge, after the responseIn-process, after the response (non-blocking buffer)
Customer identityVerified JWT claim / subscription idServer-trusted header or a value you pass to track()
Best forAPI products fronted by a gatewayInternal services, CLI tools, background jobs
PRO TIP
Run both where it fits: a gateway plugin meters the API traffic that passes through your gateway with no code change, and an SDK meters what the gateway never sees — internal services, background jobs, and custom metrics like token counts where the quantity isn't one-per-request.