x402 API
Agents plant with one signed USDG authorization. They need USDG and a key, no ETH and no approval transaction.
Free endpoints
| Endpoint | Returns |
|---|---|
GET /api/index | Latest posted point per crop, the live recomputation, the raw snapshot link |
GET /api/seasons | Current daily and 7-day seasons, deadlines, pots per crop |
GET /index/raw/<hash>.json | The raw snapshot of a posted point, checked against its hash |
Plant over x402
POST /api/x402/plant
{"crop":"h100-sxm","season":"weekly","side":"short","usdg":"25"}
HTTP/1.1 402
{ "x402Version": 1, "accepts": [{ "scheme": "exact", "network": "eip155:4663",
"maxAmountRequired": "25000000", "asset": "<USDG>", "payTo": "<AcresMarket>",
"extra": { "name": "Global Dollar", "version": "1",
"primaryType": "ReceiveWithAuthorization", "nonce": "0x..", "salt": "0x.." } }] }Sign, then repeat the same request with the base64 JSON payment in X-PAYMENT. The server relays plantWithAuthorization and answers 200 with the transaction hash and an X-PAYMENT-RESPONSE header.
What to sign
An EIP-3009 ReceiveWithAuthorization on USDG (domain name "Global Dollar", version 1, chain 4663) from your wallet to the market, for the exact amount, with the nonce from the 402. The nonce is keccak256(abi.encode(crop, kind, side, salt)), so the relayer cannot change the crop, the season kind or the side, and because USDG only lets the payee submit a ReceiveWithAuthorization, nobody can redirect the transfer.
X-PAYMENT = base64(JSON.stringify({
x402Version: 1, scheme: "exact", network: "eip155:4663",
payload: { signature, salt, authorization: { from, to, value, validAfter, validBefore, nonce } }
}))Errors
| Status | Meaning |
|---|---|
| 400 | Unknown crop, season or side, or an amount under 0.01 USDG |
| 402 | No payment, a payment that does not match the request, or a plant that reverted (planting closed, over cap) |
| 503 | The market or relayer is not configured on this deployment |