npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@katrinalaszlo/agentkey-clerk

v0.2.0

Published

Dollar spend caps for the Clerk API keys your users create: per-customer budget, scope, and expiry (also supports Clerk M2M)

Readme

agentkey-clerk

Spend caps for the Clerk API keys your users create. Your customers make API keys with Clerk; agentkey-clerk caps what each one can spend, scopes what it can do, and sets when its access ends.

Why

When you give your customers API keys through Clerk, each key calls your API on that customer's behalf. Clerk issues, verifies, and revokes the key. What it doesn't do is cap how much a customer's key can spend against your paid API, so one customer's runaway script can burn through usage that affects everyone else.

agentkey-clerk adds that layer. The customer keeps using their Clerk-issued key. You add one middleware, and every request is checked against a per-customer budget, scope, and expiry before it runs. It caps dollars (not just request counts) and blocks the call the moment a key crosses its budget.

agentkey-clerk is an independent, open-source companion to Clerk. It is not affiliated with Clerk.

| Layer | What it controls | Who covers it | |---|---|---| | Identity | Which customer's key is calling | Clerk API Keys | | Budget | How much this key can spend (in dollars) | agentkey | | Scope | What this key can do | agentkey | | Expiry | When access ends | agentkey |

Built on @katrinalaszlo/agentkey.

Install

npm install @katrinalaszlo/agentkey-clerk @katrinalaszlo/agentkey

You bring your own Clerk client (@clerk/backend or @clerk/express) and a Postgres pool — this package doesn't wrap either.

Quick start

import express from "express";
import pg from "pg";
import { createClerkClient } from "@clerk/backend";
import { AgentKey } from "@katrinalaszlo/agentkey";
import { clerkApiKeyMiddleware, trackByApiKey } from "@katrinalaszlo/agentkey-clerk";

const pool = new pg.Pool();
const ak = new AgentKey({ pool });
await ak.migrate(); // adds the columns agentkey needs to your keys table

const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY });

const app = express();

app.use(
  "/api",
  clerkApiKeyMiddleware({
    clerkClient,
    ak,
    // Applied the first time each customer's key is seen.
    defaults: { budgetCents: 5000, budgetPeriod: "month" },
  }),
);

// Inside a handler, after the customer's billable work:
app.post("/api/chat", async (req, res) => {
  const cost = await callTheModel(req.body);
  await trackByApiKey(ak, req.clerkApiKey!.subject, cost.cents);
  res.json(cost.result);
});

The customer calls your API with their Clerk API key in Authorization: Bearer <key>. The middleware:

  1. verifies the key with Clerk (clerkClient.apiKeys.verify),
  2. provisions a budget row for the customer — the key's subject, a user_ or org_ id — on first sight,
  3. enforces budget, scope, and expiry,
  4. attaches req.clerkApiKey (the verified key) and req.agentKey (the budget state).

Responses

| Condition | Status | |---|---| | Valid, in budget, has scope | next() | | Missing Bearer key | 401 Missing API key | | Invalid / revoked / expired key | 401 invalid_key | | Over budget | 429 budget_exceeded | | Missing required scope | 403 insufficient_scope | | DB fault | 500 auth_unavailable (fails closed) |

Per-customer budgets

Pass onFirstSeen to set budget/scope from the verified key — for example, read a plan tier off the key's claims:

clerkApiKeyMiddleware({
  clerkClient,
  ak,
  onFirstSeen: (apiKey) => ({
    accountId: apiKey.subject, // user_xxx or org_xxx
    scopes: ["proxy.chat"],
    budgetCents: apiKey.claims?.tier === "pro" ? 20000 : 2000,
    budgetPeriod: "month",
    expiresIn: "30d",
  }),
});

accountId defaults to the key's subject if you don't set it.

A note on scope

agentkey's scopes (what a key may doproxy.chat, usage.read) are enforced by this package against the budget row. They're separate from Clerk's own API-key scopes. Set them in defaults/onFirstSeen.

Also: internal services (Clerk M2M)

If you also want to cap your own backend services (microservices, workers) that authenticate with Clerk M2M tokens — which are distinct from customer API keys — use clerkAgentKeyMiddleware + trackByM2M. Same shape, keyed on the M2M machine subject. That's internal cost control rather than customer spend caps.

What it doesn't do

Per-key dollar spend caps only. No hierarchical org > team > key budget composition. For non-Clerk apps, use @katrinalaszlo/agentkey directly with its own ak_ keys.

License

MIT