Back to agents docs
Quickstart · TypeScript
Wire a TS agent into Orrery
Native fetch + the official Anthropic SDK. Same shape as the Python quickstart; agents pay USDC per request via x402 (preview mode is free during marketplace review).
Install
npm install @anthropic-ai/sdk
Minimal agent (~30 lines)
briefing.tsimport Anthropic from "@anthropic-ai/sdk";
const ORRERY = "https://orrery.me/api/x402/v1";
const client = new Anthropic(); // reads ANTHROPIC_API_KEY
async function fetchJson<T>(url: string): Promise<T> {
const r = await fetch(url);
if (!r.ok) throw new Error(`${r.status} ${url}`);
return (await r.json()).data as T;
}
// 1. Today's brief.
const brief = await fetchJson<{
headline: string;
biggest_moves: { slug: string; question: string; delta_24h: number }[];
}>(`${ORRERY}/brief/today`);
// 2. Why did the top mover move?
const top = brief.biggest_moves[0];
const why = await fetchJson<{ factors: { type: string; summary: string }[] }>(
`${ORRERY}/markets/${top.slug}/why`,
);
// 3. Resolution-risk before treating it as news.
const risk = await fetchJson<{ risk_level: string; what_to_verify: string[] }>(
`${ORRERY}/markets/${top.slug}/resolution-risk`,
);
// Hand it to Claude. Orrery already structured the data, so the
// system prompt can be tight: stay grounded, don't predict.
const msg = await client.messages.create({
model: "claude-opus-4-7",
max_tokens: 600,
thinking: { type: "adaptive" },
system:
"You summarise prediction-market intelligence for a daily briefing. " +
"Stay grounded in the supplied JSON; never predict outcomes; flag " +
"resolution risk when present.",
messages: [{
role: "user",
content:
`Today's brief headline: ${brief.headline}\n\n` +
`Top mover: ${JSON.stringify(top)}\n\n` +
`Why it moved: ${JSON.stringify(why.factors)}\n\n` +
`Resolution-risk: ${JSON.stringify(risk)}\n\n` +
"Write a 4-sentence briefing for a busy reader.",
}],
});
console.log(msg.content[0].type === "text" ? msg.content[0].text : "");Replaying with X-PAYMENT
async function fetchWithPayment(url: string, payer: X402Payer) {
const r = await fetch(url);
if (r.status !== 402) return (await r.json()).data;
const challenge = (await r.json()).accepts[0];
const proof = await payer.settle({
amount: challenge.amount,
asset: challenge.asset, // "USDC"
network: challenge.network, // "base"
});
const r2 = await fetch(url, { headers: { "X-PAYMENT": proof } });
if (!r2.ok) throw new Error(`${r2.status} after payment`);
return (await r2.json()).data;
}During v1 preview the 402 branch never fires; calls just return 200 with payment_status: "preview". Wire the payer once and the same code keeps working after enforcement is enabled.
Next steps
- • Cache responses client-side using each endpoint's
meta.cache_secondshint to keep your usage in budget. - • For a Discord bot, fetch
/signals/resolution_riskevery 10 minutes and re-broadcast new fires only. - • Python quickstart · Raw HTTP / cURL