# Hanzo for agents: free to start, pay as you go — Hanzo AI

> Sign up free with a wallet. Get an API key free. A small free allowance to try it. Top up in USDC or USDT over the API to raise your limits and pay as you go. No human required.

For agents

# Hanzo for agents: free to start, pay as you go

Sign up free with a wallet. Get an API key free. A small free allowance to try it. Top up in USDC or USDT over the API to raise your limits and pay as you go. No human required.

[Sign up headless](#headless)[Read the docs](https://docs.hanzo.ai/docs/agents)

Headless

- Sign up with a wallet01
- Get a key02
- Make a first call03
- Top up in USDC or USDT04
- Pay as you go05

Sign a one-time challenge from hanzo.id. A first-seen wallet gets its own account and organization.

POST /v1/account/keys with that token. It is shown once.

POST /v1/chat/completions. GET /v1/billing/tier says what the free allowance has left.

POST /v1/billing/crypto/deposit returns the address to send to; the balance is credited when the chain confirms.

Each call is billed from your balance at its model’s rate in GET /v1/pricing.

## The five steps, as one script

Every step is one request. This file makes them all, as it was run against production.

```
// No human required: sign up with a wallet, get a key, call the API, top up in USDC or USDT. // A first-seen wallet gets its own Hanzo account and organization, with a small free allowance to try it. // npm i @hanzo/ai viem · node agent.ts (Node 22.18+; set HANZO_WALLET_KEY to use your own wallet) import { Hanzo } from '@hanzo/ai' import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts' import { createHash, randomBytes } from 'node:crypto' const ID = 'https://hanzo.id' const API = 'https://api.hanzo.ai' const CLIENT = 'hanzo-ai' // Your agent's own wallet, or a fresh one. The key never leaves this process. const account = privateKeyToAccount((process.env.HANZO_WALLET_KEY as `0x${string}`) ?? generatePrivateKey()) // 1. Sign up with a wallet: get a challenge, sign it, verify (POST /v1/iam/web3/verify), exchange for a token. const nonce = await fetch(`${ID}/v1/iam/web3/nonce?chain=evm&address=${account.address}`).then((r) => r.json()) const message = [`${nonce.data.domain} wants you to sign in with your Ethereum account:`, account.address, '', ...(nonce.data.statement ? [nonce.data.statement, ''] : []), `URI: ${nonce.data.uri}`, `Version: ${nonce.data.version}`, `Nonce: ${nonce.data.nonce}`, `Issued At: ${nonce.data.issuedAt}`].join('\n') const signature = await account.signMessage({ message }) // Verify the signed challenge: a first-seen wallet gets an account and an organization of its own. const verifier = randomBytes(32).toString('base64url') const challenge = createHash('sha256').update(verifier).digest('base64url') const { data: code } = await fetch(`${ID}/v1/iam/web3/verify`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientId: CLIENT, chain: 'evm', scheme: 'secp256k1-eip191', address: account.address, message, signature, type: 'code', redirectUri: 'http://localhost:3000/callback', scope: 'openid profile email', codeChallenge: challenge, codeChallengeMethod: 'S256' }), }).then((r) => r.json()) const token = await fetch(`${ID}/v1/iam/oauth/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'authorization_code', client_id: CLIENT, code, code_verifier: verifier, redirect_uri: 'http://localhost:3000/callback' }), }).then((r) => r.json()) // 2. Get an API key (POST /v1/account/keys) that outlives the token. Shown once. const hanzo = new Hanzo({ apiKey: token.access_token, baseURL: API }) const { key } = await hanzo.account.keys.create({ name: 'agent', type: 'secret' }) // 3. Use AI (POST /v1/chat/completions) with the Hanzo SDK — OpenAI-compatible, one line. const client = new Hanzo({ apiKey: key, baseURL: API }) const chat = await client.chat.completions.create({ model: 'zen-free', messages: [{ role: 'user', content: 'Reply with the single word: ready' }], }) console.log('chat', chat.choices[0]?.message?.content, 'free left today:', chat.headers?.get?.('x-ratelimit-remaining')) // Or make a Kai decision — typed, calibrated, zero output tokens. const decision = await client.decisions.create({ model: 'kai', state: { ticket: 'The export button throws a 500 error since this morning.' }, questions: { team: { type: 'choice', instructions: 'Which team should handle this ticket?', criteria: { billing: 'charges, invoices, refunds', tech: 'bugs, errors, outages', other: 'anything else' } } }, }) console.log('decision', decision.answers, 'input tokens:', decision.usage.input_tokens, 'latency:', decision.latency_ms + 'ms') // 4. Top up in USDC or Card (POST /v1/billing/crypto/deposit · GET /v1/billing/crypto/options · GET /v1/billing/tier). const deposit = await client.billing.crypto.deposit({ chain: 'base', token: 'usdc', amountCents: 500 }) console.log('send to', deposit.depositAddress, 'then poll', `${API}/v1/billing/crypto/deposit/${deposit.id}`) console.log('HANZO_API_KEY=' + key.slice(0, 12) + '… (store the whole key; it is shown once)')
```

Keep the wallet key and the API key in your secret store: the wallet is the account, and the API key is shown once. A deposit address lasts 24 hours and is credited when the chain confirms; send only the token and chain it names.

## Paste this into your agent

What Hanzo is, the base URL, how to discover the API and the headless path, in one block an agent keeps in its context.

Agent promptCopy

```
Hanzo (https://hanzo.ai) is the AI operating system for business: one API for every model, Kai decisions and agents, with one key. Building business software since 2014. Techstars '17. Sign up free with a wallet. Get an API key free. A small free allowance to try it. Top up in USDC or USDT over the API to raise your limits and pay as you go. No human required. Base URL: https://api.hanzo.ai/v1 (chat completions in the OpenAI shape). Discover: GET https://api.hanzo.ai/v1 lists every capability, GET https://api.hanzo.ai/v1/ its operations, and https://api.hanzo.ai/v1/openapi.json is the whole spec. No key needed for any of the three. 1. Sign up with a wallet: GET https://hanzo.id/v1/iam/web3/nonce?chain=evm&address=, sign the CAIP-122 message it describes with EIP-191 personal_sign, POST https://hanzo.id/v1/iam/web3/verify (clientId "hanzo-ai", chain "evm", scheme "secp256k1-eip191", type "code" with a PKCE challenge), then exchange the code at https://hanzo.id/v1/iam/oauth/token. A first-seen wallet gets its own account and organization. A Solana wallet asks with chain=solana, writes "Solana account" in the message, and sends chain "solana", scheme "ed25519" and its signature as base64, never base58. 2. Get a key: POST https://api.hanzo.ai/v1/account/keys {"name":"agent","type":"secret"} with that token. The key is shown once. 3. Read your allowance: GET https://api.hanzo.ai/v1/billing/tier with the key says your plan, what it allows and what is left; GET https://api.hanzo.ai/v1/billing/plans lists every plan and price. 4. Top up: GET https://api.hanzo.ai/v1/billing/crypto/options, then POST https://api.hanzo.ai/v1/billing/crypto/deposit {"chain":"base","token":"usdc","amountCents":2000}. Send that token on that chain to the address it returns, and GET https://api.hanzo.ai/v1/billing/crypto/deposit/ until it says succeeded. 5. Call: POST https://api.hanzo.ai/v1/chat/completions {"model":"zen-free","messages":[{"role":"user","content":"Hello"}]} with Authorization: Bearer . The whole path as one TypeScript file: https://hanzo.ai/agents#headless. Every request spelled out: https://docs.hanzo.ai/docs/agents. Talk to people at Hanzo: https://cal.com/hanzo. Skills index: https://hanzoskills.com/llms.txt (install with `npx skills add https://hanzoskills.com/hanzo.md`). Hanzo Improvement Proposals: https://hips.hanzo.ai/llms.txt.
```

[Agents SDK](https://hanzo.ai/agents/sdk)[llms.txt](https://hanzo.ai/llms.txt)[Book a call](https://cal.com/hanzo)

## Questions

What is free?

Signing up, the API key and a small free allowance to try it. GET /v1/billing/tier, with your key, says what your account allows and what is left, and every answer carries X-RateLimit-Remaining. A person on the Free plan gets 50 free requests a day; the request after the last answers 429 until the next UTC midnight.

What does it cost after that?

You pay as you go from the balance you top up: each call is billed at its model’s rate in GET /v1/pricing, and GET /v1/billing/plans lists every plan for people with its price.

Can an agent sign up without a person?

Yes. With a wallet it needs no inbox and no person: it signs a one-time challenge from hanzo.id, a first-seen wallet gets its own account and organization, and it mints a key with the token it gets back. The whole flow is the script above. An agent with an inbox can sign up by email code instead, and one with neither has its person approve a device code once.

How does an agent pay?

Over the API in stablecoins: GET /v1/billing/crypto/options lists the chains (today Base, Ethereum and Solana) and the tokens (USDC and USDT) the rail accepts, POST /v1/billing/crypto/deposit returns the address to send to, and GET /v1/billing/crypto/deposit/{id} says when it is credited. Cards, Apple Pay and Google Pay go through the checkout at hanzo.ai/pay, which needs a browser.

How do I keep an agent from overspending?

Give each agent its own key with a monthly budget in cents and a rate in requests a minute: past the budget a call answers 402, past the rate 429. A session can carry its own cap, set with POST /v1/agent/sessions/{id}/budget, and a session that reaches it pauses until the cap is raised.

Which tools can my agent use?

The Hanzo MCP server, @hanzo/mcp, runs over stdio from one npx line in Claude Code, Codex, Cursor and Zed. It carries the Kai decision tools beside files, shell, git, code search and the browser.
