Loading the homepage. The live ledger figures are still coming in.
Loading the homepage. The live ledger figures are still coming in.
Loading the documentation.
X402 V2 / SCHEME EXACT / NETWORK eip155:196 / ASSET USD₮0
There is no account and no API key. The payment is the credential. HIVESMIND operates purely on-chain, exclusively through the OKX Marketplace.
CHALLENGE PAYMENT-REQUIRED / PAYMENT PAYMENT-SIGNATURE
5 ROUTES / 0.011 TO 0.049 USD₮0
Every route answers 402 until it is paid. Four of them also accept a JSON body that tailors the analysis. The fifth reads the settlement ledger and takes query parameters instead.
| Route | Service | Methods | Price USD₮0 |
|---|---|---|---|
| /api/goods/market-map | Opportunity Scanner | GET, POST | 0.011 |
| /api/goods/agent-digest | Business Autopilot | GET, POST | 0.019 |
| /api/goods/builder-pack | Revenue Leak Detector | GET, POST | 0.027 |
| /api/goods/templates | Agent Deal Memo | GET, POST | 0.036 |
| /api/goods/survival-report | Traction Proof Report | GET, POST | 0.049 |
EIP-3009 / EXACT AMOUNT / VALIDITY WINDOW 300S
Ask, get a price, sign an authorization for that exact amount, ask again with the signature attached. The artifact comes back in the same response as the receipt.
# 1. Ask. An unpaid call answers 402 with a PAYMENT-REQUIRED header (base64 JSON).
curl -i https://hivesmind.xyz/api/goods/market-map
# 2. Read accepts[0]: scheme "exact", network "eip155:196", the USD₮0 asset,
# the amount in atomic units, payTo (treasury), maxTimeoutSeconds 300,
# and the asset EIP-712 domain in extra.
# 3. Sign an EIP-3009 transferWithAuthorization for that exact amount
# (validity window 300s or less, unique bytes32 nonce), then resubmit.
# Packaged helper: node scripts/buy.mjs market-map --pay
curl https://hivesmind.xyz/api/goods/market-map \
-H "PAYMENT-SIGNATURE: <base64 x402 v2 payload>"
# 4. For a tailored analysis, POST a schema-validated JSON body instead.
# The body is hashed into the payment binding, so a different body is a
# different purchase and cannot be replayed against another request.
curl -X POST https://hivesmind.xyz/api/goods/builder-pack \
-H "content-type: application/json" \
-H "PAYMENT-SIGNATURE: <base64 x402 v2 payload>" \
-d '{"listingTitle":"generic AI assistant","currentSales":0}'Each challenge carries the request contract at accepts[0].outputSchema.input: a JSON Schema for the body, a worked example, and the method. An agent can read that, fill it in, and buy a tailored analysis on the first round trip without reading this page. Every field is optional, so an empty body still returns the baseline artifact.
| Service | Contract | Fields published in the 402 |
|---|---|---|
| market-map | POST json | agentName, currentCapabilities, preferredBuyerTypes, technicalConstraints, currentOffers, targetPriceRange, evidenceAvailable |
| agent-digest | POST json | agentName, currentOffers, weeklyAvailableHours, focusAreas, knownConstraints |
| builder-pack | POST json | listingTitle, description, targetCustomer, currentPriceAtomic, currentSales, callsOrImpressions, conversionNote, paymentErrors, currentProof, competitorExamples |
| templates | POST json | sellerAgent, buyerAgent, commercialObjective, serviceExchanged, priceAtomic, integrationSurface |
| survival-report | POST json | agentId, agentName, serviceName, serviceEndpoint, txHashes, receipts, teamWallets, testWallets, notes |
This is the exact object published as the example for Opportunity Scanner. Send it as the POST body, or edit it first. What you supply measurably changes the artifact you get back.
{
"agentName": "quill-research-bot",
"currentCapabilities": [
"web scraping",
"dataset indexing",
"summarization"
],
"preferredBuyerTypes": [
"hackathon builders",
"analytics agents"
],
"targetPriceRange": {
"minAtomic": "10000",
"maxAtomic": "50000"
},
"evidenceAvailable": [
"one settled transaction hash"
]
}Decode the challenge header and read the contract out of it. This is not documentation. It is the response.
curl -sD - -o /dev/null https://hivesmind.xyz/api/goods/market-map \
| sed -n 's/^payment-required: //Ip' | tr -d '\r' | base64 -d \
| jq '.accepts[0].outputSchema.input'HTTP 202 / RETRY AFTER 3S
When settlement is still confirming, the server answers 202 instead of a fresh challenge. The order is already reserved and the artifact is owed to you. Retry with the same authorization: it never charges twice and never creates a second order.
{
"ok": false,
"paymentPending": true,
"message": "Payment accepted and your order is reserved. Settlement is still confirming on X Layer, so the artifact is not attached to THIS response yet. Nothing further is charged: collect it by retrying with the recovery token below.",
"collect": {
"how": "Retry the same request with the DELIVERY-TOKEN header (or Authorization: Bearer) set to recovery.token.",
"alsoAvailableAt": "/api/orders/<orderId>",
"retryAfterSeconds": 3,
"chargedAgain": false
},
"orderId": "<order id>",
"transaction": "<transaction hash>",
"status": "pending",
"retryAfterSeconds": 3,
"recovery": {
"token": "<private token, shown once>",
"expiresAt": "<ISO 8601>",
"required": true
}
}The recovery token is private and shown once. Use it to poll the order until settlement confirms. If you lose it, prove the wallet with a signature at /api/orders/recover.
curl https://hivesmind.xyz/api/orders/<orderId> \
-H "authorization: Bearer <recovery.token>"Non-challenge errors use one envelope: { "ok": false, "error": { "code", "message", "requestId" } }. The requestId is the same id in our logs, so a support question has an exact answer.
| HTTP | Code | What it means |
|---|---|---|
| 402 | challenge body | Payment is missing or invalid. The error field names the exact reason. Retry with a corrected authorization. |
| 400 | malformed_payment_signature | The header failed structural validation. issues[] names the failing field paths. |
| 400 | invalid_query | Unknown or duplicated query parameters. Allowed: vessel (slug), days (1 to 99). |
| 400 | invalid_input | The POST body did not match the published input schema. |
| 400 | malformed_json | The POST body is not valid JSON. |
| 402 | challenge_mismatch | Payment settled for a different good, query, or input body than the one requested. |
| 402 | verify_failed, settle_failed | The facilitator rejected verification or settlement. The reason is included. |
| 413 | body_too_large | The POST body exceeds 16 KiB. |
| 415 | unsupported_media_type | POST requires content-type: application/json. |
| 429 | rate_limited | Too many requests. A retry-after header is included. |
| 500 | facilitator_unreachable, ledger_fault, internal_error | A server-side fault. The body stays safe and the full detail goes to the server logs under the requestId. |
Every delivery is signed with Ed25519 over a canonical JSON payload: keys sorted lexicographically, no whitespace. The response echoes the exact object that was signed as receipt.signedPayload, so you never have to guess which envelope fields to strip. Verify it offline with the published key, or post it to the open endpoint.
# The public key, the algorithm, and the canonicalization spec:
curl https://hivesmind.xyz/api/receipts/verify
# Verify a delivered receipt. signedPayload is echoed back verbatim in the
# delivery response, so this is a copy, not a reconstruction.
curl -X POST https://hivesmind.xyz/api/receipts/verify \
-H "content-type: application/json" \
-d '{"payload": <receipt.signedPayload>, "signature": "<receipt.signature>"}'
# { "ok": true, "valid": true }The whole path, including the tailored body built from the challenge and the pending branch.
const challenge = await fetch(url).then(async (res) => {
if (res.status !== 402) throw new Error(`unexpected ${res.status}`);
return res.json(); // the PAYMENT-REQUIRED header carries the same object
});
// The 402 tells you what body to send. Build it from the challenge itself.
const contract = challenge.accepts[0].outputSchema?.input;
const body = JSON.stringify(contract?.example ?? {});
const authorization = await signEip3009({ // your wallet, or the OKX Agentic Wallet
to: challenge.accepts[0].payTo,
value: challenge.accepts[0].amount,
validAfter: 0n,
validBefore: BigInt(Math.floor(Date.now() / 1000) + 300),
nonce: crypto.getRandomValues(new Uint8Array(32)),
});
const paid = await fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
'PAYMENT-SIGNATURE': btoa(
JSON.stringify({
x402Version: 2,
accepted: challenge.accepts[0],
payload: { signature: authorization.signature, authorization: authorization.fields },
}),
),
},
body,
});
if (paid.status === 202) {
// Reserved, not charged twice. Collect with the recovery token from the body.
}
const { content, receipt } = await paid.json();GET /api/health
Liveness probe.
GET /api/readiness
Config, ledger, facilitator, and signer checks. Booleans only, never secrets.
GET, POST /api/receipts/verify
Public key and canonicalization spec, and receipt verification.
GET /api/orders/:id
Token-only retrieval of a paid order and its stored artifact.
POST /api/orders/recover
Wallet-signature recovery when a delivery or recovery token is lost.