Quota SDK for usage tracking, billing helpers, and AI SDK telemetry correlation.
@quotadev/sdk now exports createQuotaAISDKTelemetryMiddleware() for the Vercel AI SDK.
It:
- enables
experimental_telemetryby default - injects a correlation request ID (
x-request-id) - optionally injects Quota proxy headers (
x-quota-customer,x-quota-tag) - attaches Quota metadata to AI SDK telemetry spans
pnpm add @quotadev/sdk aiimport { wrapLanguageModel, generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { createQuotaAISDKTelemetryMiddleware } from "@quotadev/sdk";
const model = wrapLanguageModel({
model: openai("gpt-4o", {
// Point provider calls at your Quota proxy if desired
baseURL: "https://your-proxy.example.com/v1",
apiKey: process.env.QUOTA_KEY!,
}),
middleware: createQuotaAISDKTelemetryMiddleware({
functionId: "chat.reply",
customerId: "cus_123",
tags: {
feature: "chat",
route: "support",
env: process.env.NODE_ENV ?? "development",
},
metadata: {
app: "dashboard-web",
team: "growth",
},
}),
});
const result = await generateText({
model,
prompt: "Summarize the last 5 support tickets",
});import { wrapLanguageModel, streamText } from "ai";
import { openrouter } from "@openrouter/ai-sdk-provider";
import { createQuotaAISDKTelemetryMiddleware } from "@quotadev/sdk";
const model = wrapLanguageModel({
model: openrouter.chat("anthropic/claude-3.5-sonnet"),
middleware: createQuotaAISDKTelemetryMiddleware({
functionId: "assist.stream",
customerId: "cus_123",
tags: { feature: "assistant", mode: "stream" },
onStart(event) {
console.log("[ai:start]", event.requestId, event.operation);
},
onFinish(event) {
console.log("[ai:finish]", event.requestId, event.latencyMs);
},
onError(event) {
console.error("[ai:error]", event.requestId, event.error);
},
}),
});
const result = await streamText({
model,
prompt: "Draft a release note for the latest observability update",
});AI SDK telemetry emits OpenTelemetry spans. Configure an exporter in your app runtime.
// instrumentation.ts (or your server bootstrap file)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
// e.g. Honeycomb/Tempo/Datadog OTLP endpoint
url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
headers: process.env.OTEL_EXPORTER_OTLP_HEADERS
? Object.fromEntries(
process.env.OTEL_EXPORTER_OTLP_HEADERS.split(",").map((pair) => {
const [k, v] = pair.split("=");
return [k.trim(), v.trim()];
}),
)
: undefined,
}),
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "my-ai-app",
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]:
process.env.NODE_ENV ?? "development",
}),
});
sdk.start();Using both the Quota proxy and AI SDK telemetry gives you:
- proxy-level transport metrics (status, latency, stream timing, bytes, error taxonomy)
- SDK-level semantic spans (function IDs, metadata, tool activity, model call traces)
- end-to-end correlation via
x-request-id/quotaRequestId
- The middleware is additive; it does not replace provider SDK telemetry.
injectHeadersis enabled by default so Quota proxy correlation works out of the box.- For non-proxy direct provider calls, telemetry still works; only Quota-specific headers may be unused.