feat: add GET /v1/usage/me endpoint for user-facing usage stats
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m41s

This commit is contained in:
OpenClaw 2026-03-07 08:04:34 +01:00
parent 2b4fa0c690
commit dd337d30b5
4 changed files with 145 additions and 2 deletions

View file

@ -19,10 +19,10 @@ import { emailChangeRouter } from "./routes/email-change.js";
import { billingRouter } from "./routes/billing.js";
import { authMiddleware } from "./middleware/auth.js";
import { usageMiddleware, loadUsageData, flushDirtyEntries } from "./middleware/usage.js";
import { getUsageStats } from "./middleware/usage.js";
import { getUsageStats, getUsageForKey } from "./middleware/usage.js";
import { pdfRateLimitMiddleware, getConcurrencyStats } from "./middleware/pdfRateLimit.js";
import { initBrowser, closeBrowser } from "./services/browser.js";
import { loadKeys, getAllKeys } from "./services/keys.js";
import { loadKeys, getAllKeys, isProKey } from "./services/keys.js";
import { verifyToken, loadVerifications } from "./services/verification.js";
import { initDatabase, pool, cleanupStaleData } from "./services/db.js";
import { swaggerSpec } from "./swagger.js";
@ -142,6 +142,50 @@ const convertBodyLimit = express.json({ limit: "500kb" });
app.use("/v1/convert", convertBodyLimit, authMiddleware, usageMiddleware, pdfRateLimitMiddleware, convertRouter);
app.use("/v1/templates", defaultJsonParser, authMiddleware, usageMiddleware, templatesRouter);
/**
* @openapi
* /v1/usage/me:
* get:
* summary: Get your current month's usage
* description: Returns the authenticated user's PDF generation usage for the current billing month.
* security:
* - ApiKeyAuth: []
* responses:
* 200:
* description: Current usage statistics
* content:
* application/json:
* schema:
* type: object
* properties:
* used:
* type: integer
* description: Number of PDFs generated this month
* limit:
* type: integer
* description: Monthly PDF limit for your plan
* plan:
* type: string
* enum: [pro, demo]
* description: Your current plan
* month:
* type: string
* description: Current billing month (YYYY-MM)
* 401:
* description: Missing or invalid API key
*/
app.get("/v1/usage/me", authMiddleware, (req: any, res: any) => {
const key = req.apiKeyInfo.key;
const { count, monthKey } = getUsageForKey(key);
const pro = isProKey(key);
res.json({
used: count,
limit: pro ? 5000 : 100,
plan: pro ? "pro" : "demo",
month: monthKey,
});
});
// Admin: usage stats (admin key required)
const adminAuth = (req: any, res: any, next: any) => {
const adminKey = process.env.ADMIN_API_KEY;