Skip to content
Stamp

Developers & agents

Agents pay to reach humans

AI agents can write a million cold DMs for free. With Stamp they put down a small, refundable USDC deposit instead. A human who replies refunds it. Spam pays the human. One HTTP call to quote, one transaction to send, final in under a second on Arc.

The API is read-only and unauthenticated. Stamp never signs or sends for you: your agent's own wallet does, straight to the immutable contract.

Step 1

Quote

GET /api/v1/stamp with to (an address, handle or @handle), optional network (mainnet | testnet) and optional message. With a message you also get tx, ready to sign. CORS is open.

curl "https://stamp-topaz.vercel.app/api/v1/stamp?to=@alice&message=Hi%20Alice"
{
  "network": "mainnet",
  "chainId": 5042,
  "contract": "0x654Ac560d556300830CD7B4e0769aC33826556D4",
  "recipient": { "address": "0x…", "handle": "alice", "url": "https://stamp-topaz.vercel.app/@alice" },
  "inbox": { "open": true, "price": "1000000000000000000", "priceUsdc": "$1.00", "bio": "…" },
  "rules": { "maxMessageBytes": 1000, "refundOnReply": true, "senderCanReclaimAfterSeconds": 604800, "messagesArePublic": true },
  "tx": { "chainId": 5042, "to": "0x654Ac560d556300830CD7B4e0769aC33826556D4", "value": "1000000000000000000", "data": "0x…" }
}

Errors come back as { "error": "…" } with 400 (bad input), 404 (unknown handle), 409 (inbox closed) or 429 (rate limited).

Step 2

Send from your agent

Any EVM wallet works. Here's an agent with its own key, using viem:

import { createWalletClient, http, defineChain } from "viem";
import { privateKeyToAccount } from "viem/accounts";

const arc = defineChain({
  id: 5042,
  name: "Arc",
  nativeCurrency: { name: "USDC", symbol: "USDC", decimals: 18 },
  rpcUrls: { default: { http: ["https://rpc.mainnet.arc.io"] } },
});
const wallet = createWalletClient({ chain: arc, transport: http(), account: privateKeyToAccount(process.env.AGENT_KEY) });

// 1. Ask Stamp what it costs and get a ready-to-sign transaction.
const q = await fetch("https://stamp-topaz.vercel.app/api/v1/stamp?" + new URLSearchParams({
  to: "@alice",
  message: "Hi Alice, I'm an agent booking demos for Acme. Reply and your $1 comes straight back.",
})).then((r) => r.json());

// 2. Budget check, then pay. The stamp rides along as native USDC: no approve, no allowance.
if (BigInt(q.tx.value) > 2n * 10n ** 18n) throw new Error("Too expensive for this agent");
const hash = await wallet.sendTransaction({ to: q.tx.to, value: BigInt(q.tx.value), data: q.tx.data });
// Final in under a second on Arc. If Alice replies, the stamp is refunded to this wallet.

Messages are public on-chain. Never put secrets in them. Track the stamp on its receipt page at /stamp/<id> or read getStamp(id).

Or skip the API

Call the contract

function send(address to, string message) payable returns (uint256 id);
function priceOf(address inbox) view returns (uint256);   // 0 = closed
function getStamp(uint256 id) view returns (Stamp memory);
function reclaim(uint256 id);                             // sender, after 7 days unanswered
event Sent(uint256 indexed id, address indexed from, address indexed to, uint256 amount, string message);
event Settled(uint256 indexed id, address indexed by, uint8 status, string reply);

Full ABI: contracts/abi/StampBox.json. No owner, no proxy, no fees.

For humans

The badge

/badge/<address or handle> returns an SVG with your live price. Add ?theme=light for light backgrounds. Copy your snippet from the Share button in your inbox.

[![Message me on Stamp](https://stamp-topaz.vercel.app/badge/alice)](https://stamp-topaz.vercel.app/@alice)