Sign in →
SDKs1 min read

SDKs & Client Libraries

Where and how to download every Aforo metering client — base SDKs (Node, Python, Go, Java), protocol SDKs, MCP tooling, and gateway plugins.

Updated 2026-06-30Suggest edits
Docs SDKs Overview
Get the SDKs & plugins
Every metering SDK, protocol client, and gateway plugin lives in one public repo: github.com/aforoai/SDKs
View on GitHub Download ZIPgit clone https://github.com/aforoai/SDKs.git

When to Use SDKs#

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. Tenant 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.

Node.js#

@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.

Python#

The only hard dependency is httpx>=0.25. AforoClient enqueues into a ring buffer and a background daemon thread flushes batches.

terminal
# Not yet on PyPI — clone and install from source:
git clone https://github.com/aforoai/SDKs.git
cd SDKs/aforo-metering-sdks/python
pip install -e .            # or: pip install -e ".[fastapi]"

Manual Tracking

usage.py
import os
from aforo import AforoClient

client = AforoClient(api_key=os.environ["AFORO_API_KEY"])

client.track(
    customer_id="cust_1",      # who is billed
    metric_name="api_calls",   # what you're metering
    quantity=1,
)

# Force a synchronous flush when you need delivery confirmed:
result = client.flush()        # FlushResult(sent=..., failed=...)
client.shutdown()              # also registered via atexit

Framework Middleware

middleware.py
# FastAPI / Starlette
from aforo.middleware.fastapi import AforoMeteringMiddleware
app.add_middleware(AforoMeteringMiddleware, api_key=os.environ["AFORO_API_KEY"])

# Flask
from aforo.middleware.flask import AforoMetering
AforoMetering(app, api_key=os.environ["AFORO_API_KEY"])

# Django settings.py
MIDDLEWARE = [..., "aforo.middleware.django.AforoMeteringMiddleware"]
AFORO_API_KEY = os.environ["AFORO_API_KEY"]

Each adapter reads the customer id from X-Customer-Id (falling back to X-Api-Key); a request with no resolvable customer id is not metered.

Go#

Zero dependencies beyond the standard library. The module path is github.com/aforoai/SDKs/aforo-metering-sdks/go.

terminal
# Resolves once the first Go module tag is pushed. Until then, clone + replace:
git clone https://github.com/aforoai/SDKs.git
go.mod
require github.com/aforoai/SDKs/aforo-metering-sdks/go v1.0.0

replace github.com/aforoai/SDKs/aforo-metering-sdks/go => ../SDKs/aforo-metering-sdks/go

Direct Client + Middleware

main.go
package main

import (
    "net/http"
    "os"

    metering "github.com/aforoai/SDKs/aforo-metering-sdks/go"
)

func main() {
    client := metering.NewClient(metering.Options{
        APIKey:  os.Getenv("AFORO_API_KEY"),
        BaseURL: "https://ingest.aforo.ai", // default
    })
    defer client.Close() // flushes the buffer before exit

    // Manual track when you know an event happened:
    client.Track(metering.TrackEvent{
        CustomerID: "cust_acme_001",
        MetricName: "api_calls",
        Quantity:   1,
    })

    // Or meter every request — reads X-Customer-Id, emits after the response:
    mux := http.NewServeMux()
    wrapped := metering.HTTPMiddleware(mux, metering.MiddlewareOptions{
        APIKey: os.Getenv("AFORO_API_KEY"),
    })
    http.ListenAndServe(":8080", wrapped)
}

A Chi adapter is also provided: r.Use(metering.ChiMiddleware(metering.MiddlewareOptions{APIKey: ...})).

Java / Spring Boot#

Requires Java 17+ (uses java.net.http.HttpClient and records). The artifact is com.aforo:metering.

pom.xml
<dependency>
  <groupId>com.aforo</groupId>
  <artifactId>metering</artifactId>
  <version>1.0.0</version>
</dependency>
terminal
# Not yet on Maven Central — build from source into your local ~/.m2:
git clone https://github.com/aforoai/SDKs.git
cd SDKs/aforo-metering-sdks/java
mvn clean install

Manual Tracking

Usage.java
import com.aforo.metering.AforoClient;
import com.aforo.metering.AforoOptions;
import com.aforo.metering.TrackEvent;

// AforoClient is AutoCloseable — the buffer flushes on close
try (AforoClient client = new AforoClient(new AforoOptions(System.getenv("AFORO_API_KEY")))) {
    client.track(TrackEvent.builder("cust_acme_001", "api_calls")
            .quantity(1)
            .metadata(java.util.Map.of("route", "POST /v1/charges"))
            .build());
}

Spring Boot Auto-Configuration

application.yml
aforo:
  enabled: true          # auto-config is off unless this is exactly "true"
  api-key: ${AFORO_API_KEY}
  base-url: https://ingest.aforo.ai

The auto-configuration wires an AforoClient bean and a request-end servlet filter that runs after the response is committed (no added latency). It resolves the customer from the Spring Security principal, then X-Customer-Id, then X-Api-Key; requests with none of those are skipped.

More SDKs & Plugins in the Repo#

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
gRPCUnary and streaming RPC calls{lang}-grpc
WebSocketConnection lifetime, message count + bytes{lang}-ws
MQTTPublish / subscribe message volume{lang}-mqtt

AI & MCP

PackageWhat it doesRepo path
MCP metering SDKMeter MCP tool invocations from your servernode-mcp · python-mcp
MCP transport proxyMeter stdio / SSE MCP servers with no code change (CLI sidecar)mcp-proxy
Agent SDKSession + step metering for AI agentsnode-agent

Background on the agent + MCP surfaces: and .

Gateway Plugins — zero code

Meter at the edge with no application changes. Each lives under aforo-gateway-plugins/ and has a step-by-step guide:

An EMQX (MQTT broker) plugin also ships in the repo under aforo-emqx-plugin/.

SDK vs. Gateway: When to Use Which#

CriteriaGateway PluginSDK
Code changesZeroMinimal (middleware) or a manual track() call
Metering granularityRequest-levelCustom (tokens, bytes, compute time)
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.