wellworn

Keys

Create, name and revoke a key, where the cap actually lives, and the header an agent sends.

A key raises the no-key allowance of 60 calls a day per IP to your plan's monthly cap, and it is the one thing submit_trap requires. Everything else works without one.

Create a key

Sign up at wellworn.dev/keys, confirm the address from the mail that arrives, then open /app/keys. Every key needs a name, up to 40 characters; use the machine or the job it belongs to, such as laptop, ci, staging, so the last-used column tells you something later.

The value is shown once, in the dialog that opens right after creation. It is stored as a SHA-256 hash, so nobody, including us, can read it back. Lose it and the fix is to create a new key and revoke the old one.

Sign-up refuses disposable addresses. The list is 200 domains and is matched on the exact domain, so a subdomain of a listed host passes; it is a spam control, not a security control.

What the list shows

ColumnWhat it holds
NameThe name you typed. Editing it is not open yet.
PrefixThe first characters of the key, always starting ww_, so you can tell two keys apart.
CreatedThe day the key was made, in UTC.
Last usedThe day of the most recent verified call, or never.

Last used comes from Better Auth's own lastRequest field on the key row, updated when the server verifies the token, so a key that only ever failed verification still reads never.

Revoke

Revoking deletes the key row. There is no undo and no grace period: the next call carrying that value is verified against nothing and the server answers 401 invalid key rather than dropping the caller to the no-key tier. Rotating a key is therefore create, change the config, then revoke, in that order.

The header

The key is a bearer token.

every request
Authorization: Bearer ww_your_key

Every client page in the Clients section shows where that header goes for that client. A typo is rejected with 401 instead of being silently downgraded, so a broken config shows up on the first call.

The cap belongs to the organization

Signing up creates one organization for you, and the key row points at it (references: "organization" in packages/auth/src/index.ts). The monthly cap is counted against the organization, so a second key buys nothing extra: it is a second label on the same allowance. Keys are visible to everyone in the organization, which is why one key per machine beats one key shared by hand.

Tiers

TierCapWindowBurst
No key60 callsday, per IP10 a minute
Free key2,000 callsmonth, per organization30 a minute
Pro20,000 callsmonth, per organization120 a minute
Team100,000 callsmonth, pooled300 a minute

The burst counter is a fixed 60-second window that starts at the first call of a burst and sits on top of the window cap, so a runaway loop cannot spend a month of calls in a minute. Full details in plans and credits.

What counts as a call

One tool call is one call. The initialize handshake, tools/list, and /health are not metered. A request to the plain-text traps endpoint at /api/traps goes through the same limiter, which is why the Claude Code hook is counted the same way a tool is.

At the cap

Nothing throws. The tool returns one line:

tool result at the cap
limit reached: no-key 60/60 today (resets 2026-09-09T00:00:00.000Z). Free key or plans: https://wellworn.dev/pricing

The agent reads that as an answer and carries on with the rest of its work. A keyed caller gets the same line with plan and this month in place of no-key and today.