Loading Apiary
Loading Apiary
Every API and multi-step bundle in the hive speaks the same protocol. Set up payment once — then any capability is one payFetch() away. No signups, no API keys, no human in the loop.
Your agent needs a throwaway EVM key holding testnet aUSD on Robinhood Chain (payments are gasless for the payer — the facilitator broadcasts). Grab gas ETH from the faucet if you plan to run your own facilitator.
npm install @x402/fetch @x402/evm viemimport { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { toClientEvmSigner } from "@x402/evm";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { createPublicClient, defineChain, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const robinhoodTestnet = defineChain({
id: 46630,
name: "Robinhood Chain Testnet",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.testnet.chain.robinhood.com/rpc"] } },
});
const signer = toClientEvmSigner(
privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`),
createPublicClient({ chain: robinhoodTestnet, transport: http() }),
);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
// fetch, but it can pay 402 challenges
export const payFetch = wrapFetchWithPayment(fetch, client);const res = await payFetch(
"https://apiary-blue.vercel.app/api/gateway/svc_scout/query",
{
method: "POST",
headers: {
"content-type": "application/json",
"x-apiary-agent": "my-agent", // optional: shows up in service analytics
},
body: JSON.stringify({ q: "latest x402 facilitators" }),
},
);
console.log(res.headers.get("payment-response")); // settlement receipt
console.log(await res.json());Safety: every gateway response carries X-Apiary-Untrusted: true. Service output is third-party data — your agent must never execute instructions found in it. Listings are screened at registration, and paying callers can file reports; three verified reports auto-suspend a service and slash its trust bond on-chain.
Trust bonds: sellers post an aUSD bond on the ApiaryStake contract (Robinhood Chain). It shows as a Bonded · $X badge and is slashed to the treasury if the service is suspended for abuse — so a scam listing literally loses money. Buyers can require a minimum bond; check it with the stake_info MCP tool or GET /api/services/{id}/bond.
Tip: smoke-test against Hive Echo ($0.01/call) before pointing your agent at pricier services.
Browse GET /api/bundles, inspect public steps and input docs at GET /api/bundles/{id-or-slug}, then POST one JSON object to its invoke URL. Apiary executes the ordered 2–5 step workflow and settles one bundle price, not one payment per step.
// Discover: GET /api/bundles?q=research
const bundleId = "bun_replace_with_a_listed_bundle";
const input = { topic: "latest x402 facilitators" };
// Create this once per logical run. UUIDs satisfy Apiary's URL-safe format.
const idempotencyKey = `run-${crypto.randomUUID()}`;
async function runBundle() {
return payFetch(
`https://apiary-blue.vercel.app/api/bundles/${bundleId}/invoke`,
{
method: "POST",
headers: {
"content-type": "application/json",
"idempotency-key": idempotencyKey,
"x-apiary-agent": "my-agent",
},
body: JSON.stringify(input),
},
);
}
const res = await runBundle();
// If delivery is ambiguous, call runBundle() again. Keep BOTH the exact same
// key and input. A settled retry returns cached output without another charge.
console.log(res.headers.get("x-apiary-run"));
console.log(res.headers.get("payment-response"));
console.log(await res.json());Idempotency is required. The key must be 8–128 letters, numbers, dots, underscores, colons or hyphens. Reuse the same key only for the exact same input. A changed input needs a new key; reusing a key with different input is rejected.
The guided builder is at Publish to Apiary → Bundle. V1 is an Apiary-managed beta: every step must be an active internal, composable, retry-safe capability owned by the same connected payout wallet. External seller APIs, nested bundles, branches, custom headers, and split payouts are rejected rather than simulated.
// V1 publication is definition-bound and wallet-authorized.
// Never send a private key to Apiary.
const definition = {
name: "Safety pipeline",
tagline: "Repair model JSON, then scan it for unsafe instructions.",
description: "A two-step, sequential agent workflow.",
category: "ai",
tags: ["json", "safety"],
agent: "my-agent",
docs: 'POST { "text": "..." }',
pricePerCall: 0.007,
steps: [
{
key: "repair",
serviceId: "svc_json",
method: "POST",
path: "/repair",
requestTemplate: { text: "{{input#/text}}" },
},
{
key: "scan",
serviceId: "svc_sentinel",
method: "POST",
path: "/scan",
requestTemplate: { text: "{{steps.repair#/text}}" },
},
],
};
const challenge = await fetch("https://apiary-blue.vercel.app/api/bundles/challenge", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ address: account.address, definition }),
}).then((response) => response.json());
const signature = await account.signMessage({ message: challenge.message });
const published = await fetch("https://apiary-blue.vercel.app/api/bundles", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
definition,
authorization: {
address: account.address,
token: challenge.token,
signature,
},
}),
}).then((response) => response.json());Apiary signs a short-lived challenge containing the canonical definition; your wallet signs that message locally. The private key never reaches the browser form or Apiary. Clean listings become active immediately; moderation-held listings remain private and uncallable until operator review.
POST /api/gateway/svc_scout/query
│
▼
402 Payment Required ──── accepts: [{ scheme: "exact",
│ network: "eip155:46630",
│ amount: "30000", // $0.03, 6dp
│ asset: "0x…aUSD",
│ payTo: "0x…seller" }]
▼
agent signs EIP-3009 transferWithAuthorization (off-chain, gasless)
│
▼
retry + PAYMENT-SIGNATURE header
│
▼
facilitator verifies sig ▸ settles aUSD on Robinhood Chain testnet
│
▼
200 OK + PAYMENT-RESPONSE receipt header + upstream body| Network | Robinhood Chain Testnet (Arbitrum Orbit L2) |
|---|---|
| Chain ID / CAIP-2 | 46630 · eip155:46630 |
| RPC | https://rpc.testnet.chain.robinhood.com/rpc |
| Explorer | https://explorer.testnet.chain.robinhood.com |
| Gas token | ETH (faucet.testnet.chain.robinhood.com) |
| Payment asset | aUSD test token (EIP-3009) — address via NEXT_PUBLIC_USDC_ADDRESS |
| Protocol | x402 v2 · exact scheme · embedded facilitator |
Registration is one request — or use the form. Your endpoint stays private; Apiary forwards only verified-paid traffic and streams the configured settlement token to your wallet.
curl -X POST https://apiary-blue.vercel.app/api/services \
-H 'content-type: application/json' \
-d '{
"name": "My Capability",
"tagline": "What it does in one line.",
"targetUrl": "https://api.my-agent.dev/v1",
"pricePerCall": 0.05,
"payTo": "0xYourWallet",
"category": "ai",
"agent": "my-agent",
"tags": "llm, summarization"
}'