Command line and console
Tereno has no CLI of its own, on purpose. It is an HTTP API that answers 402, so the tools you already have work: curl to look, an x402 client to pay, and the browser console when you do not want a terminal at all.
Everything an agent can do here, a person can do by hand. That is a deliberate property: an interface only a machine can exercise is one nobody can audit.
Looking, for free
Reading the catalogue, checking a price and resolving a receipt all cost nothing and need no wallet.
# Everything Tereno can answer, with live prices
curl -s https://www.tereno.xyz/api/v1/capabilities | jq '.capabilities[] | {id, summary}'
# What one call would cost, for a specific input
curl -s "https://www.tereno.xyz/api/v1/quotes?capability=contract.guard&address=0x4200000000000000000000000000000000000006" | jq
# Resolve a receipt somebody handed you
curl -s https://www.tereno.xyz/api/v1/receipts/<invocationId> | jq
# Resolve a portable evidence reference
curl -s https://www.tereno.xyz/api/v1/evidence/sha256:<artifactId> | jqReading a 402 by hand
Worth doing once, because it is the whole protocol. Ask for something paid without paying and decode the header:
curl -s -i "https://www.tereno.xyz/api/v1/capabilities/chain.snapshot/invoke" \
| grep -i '^payment-required:' \
| sed 's/^payment-required: //' | tr -d '\r' | base64 -d | jq '.accepts[0]'{
"scheme": "exact",
"network": "eip155:8453",
"amount": "20000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xfbF218ACCBb0D57fc4E8fc3E2A885C910c4C9e94",
"maxTimeoutSeconds": 300
}Nothing was charged and nothing was executed. You now know the exact price, chain and asset before committing anything.
Paying, from a script
Completing the handshake means signing an EIP-3009 USDC authorization. You can do it with any x402 client; the Tereno one wraps the quote, the signature and the retry into one call.
import { privateKeyToAccount } from "viem/accounts";
import { createTerenoClient } from "tereno-client";
const client = createTerenoClient({
baseUrl: "https://www.tereno.xyz",
account: privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`),
network: "eip155:8453",
maxPriceUsd: 0.02, // refuse anything dearer, before signing
});
const guarded = await client.invokeCapability({
capabilityId: "contract.guard",
address: unsignedTx.to,
});
if (guarded.data.verdict === "block") throw new Error("Tereno blocked this contract");maxPriceUsd is the guard worth setting first: it is enforced before a signature is produced, so a price change cannot spend more than you meant to spend.
Without a terminal
The browser console works too. Every free read is a plain fetch with no wallet, no signature and no headers, so the shape of an answer can be inspected from any page:
await (await fetch(
"https://www.tereno.xyz/api/v1/quotes?capability=chain.snapshot&wallet=0x0000000000000000000000000000000000000000"
)).json();Which interface to use
| If you are | Use | Why |
|---|---|---|
| Evaluating Tereno | curl, the browser console | Free, no wallet, no commitment. |
| Wiring an agent | MCP | One command, tools appear next to everything else the agent can do. |
| Writing a service | tereno-client | Quote, sign, retry and receipt in one call, with a price ceiling. |
| Building your own client | the OpenAPI spec | x402 is an open protocol; nothing here requires our client. |
Rate limits
Free reads are rate limited per IP and globally, as a circuit breaker against scraping rather than as a paywall. A limited request answers 429 with Retry-After. Paid calls are limited by what you are willing to pay for.
