ai-cost-guard
v1.0.0
Published
AI API budget protection middleware — track token usage per user, set limits, auto block when exceeded
Maintainers
Readme
ai-cost-guard
AI API budget protection — track token usage per user, set cost limits, and auto-block when thresholds are exceeded. Works with OpenAI (and easy to extend to Anthropic, etc.).
The problem
- Unexpected API bills from OpenAI / Anthropic / Gemini
- Abuse from power users or bots
- No per-user token or cost visibility
What it does
- Track token usage per user
- Estimate cost from token counts (model-aware)
- Enforce a per-user budget (e.g. $2 or $5)
- Auto-block when limit exceeded
- Express middleware that injects
req.aiCostGuard.track()
Install
npm install ai-cost-guardQuick start
const OpenAI = require("openai");
const express = require("express");
const AICostGuard = require("ai-cost-guard");
const aiCostMiddleware = require("ai-cost-guard/middleware");
const app = express();
const client = new OpenAI({ apiKey: process.env.OPENAI_KEY });
const guard = new AICostGuard({
userLimit: 2 // $2 per user
});
app.use(express.json());
app.use(aiCostMiddleware(guard));
app.post("/chat", async (req, res) => {
try {
const completion = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: req.body.message || "Hello" }]
});
const tokensUsed = completion.usage.total_tokens;
await req.aiCostGuard.track({
model: "gpt-4o-mini",
tokensUsed
});
res.json(completion);
} catch (err) {
if (err.message.includes("blocked") || err.message.includes("exceeded")) {
return res.status(403).json({ error: err.message });
}
res.status(500).json({ error: err.message });
}
});
app.get("/usage", (req, res) => {
const userId = req.headers["x-user-id"];
if (!userId) return res.status(400).json({ error: "x-user-id required" });
res.json(guard.getUserStats(userId));
});
app.listen(3000);Send requests with a user identifier so the guard can track per user:
- Header:
x-user-id: user_123 - Or set
req.user = { id: "user_123" }(e.g. from your auth middleware).
API
AICostGuard(options)
options.store— optional store instance (default: in-memory). Must implementgetUser(userId),updateUsage(userId, tokens, cost),blockUser(userId).options.userLimit— max cost in dollars per user (default:5).
guard.track({ userId, model, tokensUsed })
- Updates usage and cost for
userId. - Throws if user is already blocked or if this update would exceed
userLimit(and blocks the user). - Returns
{ totalTokens, totalCost }.
guard.getUserStats(userId)
- Returns
{ tokensUsed, costUsed, blocked }for that user.
aiCostMiddleware(guard)
- Express middleware. Expects
req.user.idorreq.headers["x-user-id"]. - Attaches
req.aiCostGuard.track({ model, tokensUsed })(userId comes from request).
Usage without Express
const AICostGuard = require("ai-cost-guard");
const guard = new AICostGuard({ userLimit: 2 });
// After each OpenAI call:
await guard.track({
userId: "user_123",
model: "gpt-4o-mini",
tokensUsed: completion.usage.total_tokens
});
const stats = guard.getUserStats("user_123");Custom store
Replace the in-memory store with Redis or a DB by implementing the same interface:
const AICostGuard = require("ai-cost-guard");
const myStore = {
getUser(userId) { /* return { tokensUsed, costUsed, blocked } */ },
updateUsage(userId, tokens, cost) { /* persist */ },
blockUser(userId) { /* persist */ }
};
const guard = new AICostGuard({ store: myStore, userLimit: 5 });Supported models (cost estimation)
Default pricing is included for common OpenAI models (e.g. gpt-4o-mini, gpt-4o). Unknown models fall back to a default per-token rate. You can extend or override pricing in your app by wrapping or replacing the cost calculator.
License
MIT
