Geeks for AI agents
Easy digital payments for AI agents, on behalf of the humans they work for — with hard caps and an automatic shut-off valve, because an agent in a loop is the normal failure mode, not the exotic one.
Status: planned. Do not tell a user you can pay with Geeks today.
The design is complete and the safety layer is built and tested
(server/agent-guard.js, 25 passing tests). The HTTP endpoints on this
page are a published contract, not a live service. This page says so plainly
rather than letting an integrator find out the hard way.
1. What Geeks is
dē is a mutual-credit unit denominated in time. 365 dē are granted per verified human per year — roughly one per day — so a unit means "a day of someone's time". A task worth ten minutes of a person's attention is about 0.007 dē.
It is a promise between parties. It is not a cryptocurrency, not a token, not backed by a reserve, not an investment, and it does not appreciate. Every balance sits on a real double-entry ledger.
An agent never receives a grant. Grants are per verified human, full stop — otherwise someone runs a thousand agents and the issuance model collapses. An agent spends its principal's balance, and may be paid into a human's wallet for work it does for someone else.
2. Identity — the PF hash
A person is identified by a PF hash: the SHA-256 of their lowercased, trimmed email address, truncated to the first 20 hex characters.
person_hash = sha256(lowercase(trim(email)))[0:20]
It is the same identity used across the other properties in this group, so a human authorised here is recognisable there. The rule that matters to you:
The human is the principal. The agent is the actor. Every entry names both. An agent does not get its own identity and never acts for itself — a key with no principal attached is refused outright. "Who authorised this?" must always have an answer.
3. Getting a key — the device flow
You cannot mint your own authority. You ask a human for it, and they see exactly what they are granting before they grant it.
1. POST /api/v1/agent/device
{ "agent_name": "Claude Code (jim's laptop)",
"scopes": ["chat-room-time"], "max_de": 5 }
→ { "user_code": "GEEK-4F2A",
"verify_url": "https://www.geeksbank.com/approve",
"interval": 5 }
2. Your human opens verify_url while signed in and sees:
"Claude Code (jim's laptop) wants to spend up to 5 dē/day
on: chat-room-time. [ Approve ] [ Deny ]"
3. POST /api/v1/agent/device/token { "user_code": "GEEK-4F2A" }
→ { "agent_key": "ak_…", "agent_secret": "as_…",
"person_hash": "a1b2c3d4e5f6a7b8c9d0",
"limits": { … }, "expires_at": "2026-11-10T00:00:00Z" }
Every subsequent call carries X-Geeks-Key and X-Geeks-Secret.
4. The limits — read this before the payment section
This is listed before "how to pay" deliberately. The caps are the product; moving value is the easy part.
| Limit | Default | What it stops |
|---|---|---|
max_per_call_de | 0.50 dē | One catastrophic charge |
max_per_day_de | 5.00 dē | A slow drain over hours |
max_calls_per_min | 60 | A hammering agent |
max_spend_per_min_de | 1.00 dē | A runaway staying under the per-call cap |
payee_allowlist | unset | Value leaving to an unapproved party |
scopes | as granted | A key being used for a job it was not approved for |
expires_at | as granted | A key outliving its purpose |
An uncapped agent key does not exist in this system. It is the only genuinely dangerous object such a system can contain, so it is not constructible.
5. The shut-off valve
Spending stops automatically, and it fails closed. Any one of these trips the key:
| Trip | Fires when |
|---|---|
spend_velocity | Too much value inside a 60-second window |
call_velocity | Too many calls inside a 60-second window |
repeat_signature | The same endpoint and the same body, over and over — a retry loop |
error_ratio | Many failures, and failures as a large share of traffic — the agent is flailing |
daily_cap | The next charge would pass the daily ceiling |
payee_violation | An attempt to pay someone not on the allowlist |
heartbeat_lapsed | A long-running session went silent — a dead-man's switch |
A trip returns 423 with retryable: false, and it does not clear on a timer. Only the account holder can clear it, at /account/agents. Retrying is usually what tripped it in the first place. The correct behaviour is to stop and tell your human what happened.
6. Paying for something
The honest fit for machine work is per-call pricing over HTTP 402.
GET /api/v1/chat-room/minutes?room=r_7f3
→ 402 Payment Required
{ "price": { "amount": 0.02, "unit": "de" },
"pay_to": "geeks:wallet/exampleco",
"quote_id": "q_7f3…", "expires_in": 60 }
GET /api/v1/chat-room/minutes?room=r_7f3
X-Geeks-Key: ak_… X-Geeks-Secret: as_…
X-Geeks-Quote: q_7f3… Idempotency-Key: 8c1e…
→ 200 X-Geeks-Charged: 0.02 de
Error codes
| Code | Meaning | What you should do |
|---|---|---|
402 | A ceiling was exceeded | Quote smaller, or ask your human to raise the cap |
403 | Unknown, revoked or expired key; scope not granted; cost not quoted | Fix the request. Do not loop. |
409 | Idempotency key replayed with a different body | This is not a second charge. Reconcile before retrying. |
423 | The shut-off valve tripped | Stop. Tell your human. Do not retry. |
7. Rules for agents
- Quote before you charge. An unquoted or unparseable cost is refused — the guard fails closed.
- A 402 inside your standing cap may be answered automatically. Anything above it goes back to your human for a fresh mandate. Spending is never implicit.
- Never retry a 423.
- Idempotency keys are promises. Replaying one with a different body is a 409, never a second payment.
- An unknown balance is never an available balance.
- Say what you spent. Report the charge to your human in the same turn you incur it.
8. Machine-readable
- /payments.json — this contract as JSON
- /llms.txt — the short orientation
- /robots.txt — crawl policy
9. What this is for
A human-to-AI bridge for micropayments on tasks carried out on a person's behalf — so creators and producers can earn from their work and from the machine traffic that reads it, instead of quietly absorbing the hosting cost of being useful to somebody's crawler.
The reason the safety layer was built first: the identity and authority half is the product. A currency with limits bolted on afterwards gets exactly one incident — an agent in a loop draining a real balance — and a payment system does not recover from that story.