# Orrery — Full Technical Reference for LLMs and Agents > Decision terminal for prediction markets (orrery.me). Polymarket-first, multi-venue planned. Live, public, no signup. This document is the comprehensive machine-readable reference. The shorter human-friendly version lives at `/llms.txt`. The OpenAPI spec lives at `/openapi.yaml` and `/.well-known/openapi.yaml`. The agent discovery manifest lives at `/.well-known/ai-plugin.json`. --- ## 1. Identity and positioning Orrery is a public, read-only intelligence terminal that aggregates, normalises, and explains live data from Polymarket. Its design centre is a daily workflow: - morning Daily Brief with biggest moves, unusual volume, signals, resolution risk; - intraday alerts on user-defined rules; - per-market terminal pages explaining *why* probabilities moved. Orrery is not affiliated with Polymarket and does not facilitate trading. It does not provide investment, legal, or tax advice. --- ## 2. Routes Surface area as of 2026-05-17. | Path | Type | Purpose | |---|---|---| | `/` | Page | Home Command Center: Since-last-visit, Pulse, Biggest Moves, Smart Money Flow, Divergences, Events Today, Watchlist, Brief teaser. | | `/scanner` | Page | Dense markets table with search grammar, URL-synced sort, resolution countdown. | | `/markets/[slug]` | Dynamic page | Per-market terminal: chart, recent trades, holders, signals, AI "Why it moved", resolution risk, related markets, timeline. | | `/markets/category/[slug]` | Dynamic page | Category-filtered scanner with category-specific framing. | | `/signals` | Page | Full signal feed with Evidence / Backtest / Action tiers. | | `/opportunities` | Page | Edge-scored markets with capacity, horizon, recommended next step. | | `/whales` | Page | $10k+ trade feed from the Data API. | | `/smart-money` | Page | Top-volume signal feed with per-signal breakdown. | | `/wallets` | Page | Quality-scored top traders. | | `/wallets/[address]` | Dynamic page | Wallet PnL, win rate, specialisation, activity. | | `/portfolio` | Page | Read-only multi-wallet aggregation. | | `/watchlist` | Page | Tracked markets with since-last-visit deltas. | | `/alerts` | Page | User-defined rules. | | `/copilot` | Page | Free-text AI research grounded in live snapshot. | | `/backtest` | Page | Historical signal performance. | | `/pricing` | Page | Commercial packaging for the paid x402 agent API: use cases, pricing ladder, Python/TypeScript/cURL snippets. | | `/receipts` | Page | Public market receipts plus aggregate x402 usage ledger: attempts, 402 challenges, settled calls, and top paid endpoints. | | `/blog` | Page | Evergreen prediction-market research guides. | | `/blog/[slug]` | Static page | Pillar articles on signals, resolution risk, whale tracking, and agent APIs. | | `/blog/[slug]/markdown` | Text | Low-noise Markdown twin of each blog article for LLM grounding. | | `/blog/rss.xml` | Feed | RSS 2.0 feed of evergreen research guides. | | `/brief` | Page | Daily brief landing + email subscription. | | `/brief/personal` | Page | Browser-local personal brief from watchlist, alerts, and tracked wallets. No account, no upload, noindex. | | `/brief/archive` | Page | Index of past briefs. | | `/brief/archive/[date]` | Dynamic page | A specific day's brief. | | `/brief/rss.xml` | Feed | RSS 2.0 of recent briefs. | | `/status` | Page | Live HTTP probes of every upstream. | | `/docs/agents/demos` | Page | Copy/paste x402 use-case demos for monitoring, resolution risk, move explanations, watchlists, and attention queues. | | `/docs/agents/sdk` | Page | Installable TypeScript and Python SDK package docs for x402 agents, plus local verification commands. | | `/rooms` | Page | Per-market discussion preview. | | `/disclaimer`, `/terms`, `/privacy`, `/contact` | Page | Legal + contact. | | `/openapi.yaml`, `/.well-known/openapi.yaml` | YAML | Machine-readable API spec. | | `/.well-known/ai-plugin.json` | JSON | Agent discovery manifest. | | `/.well-known/security.txt` | Text | Security contact. | | `/llms.txt`, `/llms-full.txt` | Text | This document and its summary. | | `/knowledge-graph.jsonld` | JSON-LD | Static knowledge graph (FAQ + entities). | | `/sitemap.xml` | XML | Includes top markets + all static routes. | | `/robots.txt` | Text | Allows all major search engines and AI crawlers. | --- ## 2a. Evergreen blog corpus Orrery's `/blog` surface is designed for durable search and answer-engine retrieval. Every post has: - canonical HTML at `/blog/{slug}`; - Article + FAQ JSON-LD on first render; - Markdown twin at `/blog/{slug}/markdown`; - sitemap entry for both HTML and Markdown; - internal links into live product pages and methodology. Current pillar posts: | Path | Primary intent | |---|---| | `/blog/prediction-market-signals` | "prediction market signals", "Polymarket signals" | | `/blog/polymarket-resolution-risk` | "Polymarket resolution risk", "Polymarket resolution rules" | | `/blog/polymarket-whale-tracking` | "Polymarket whale tracker", "smart money Polymarket" | | `/blog/prediction-market-api-for-ai-agents` | "prediction market API", "x402 API", "AI agent market data" | | `/blog/best-polymarket-analytics-tools` | "best Polymarket analytics tools", "prediction market dashboard" | | `/blog/how-to-track-polymarket-whales` | "how to track Polymarket whales", "wallet tracking" | | `/blog/how-polymarket-markets-resolve` | "how Polymarket markets resolve", "settlement rules" | | `/blog/prediction-market-api-for-agents` | "prediction market API for agents", "agentic market data" | | `/blog/polymarket-signals-explained` | "Polymarket signals explained", "signal families" | | `/blog/polymarket-vs-kalshi-data` | "Polymarket vs Kalshi data", "prediction market data" | | `/blog/election-prediction-markets` | "election prediction markets", "political market odds" | | `/blog/crypto-prediction-markets` | "crypto prediction markets", "Bitcoin prediction markets" | | `/blog/what-is-x402` | "what is x402", "HTTP 402 payments" | | `/blog/build-ai-agent-prediction-markets` | "build AI agent prediction markets", "x402 agent API" | --- ## 3. Public APIs All endpoints are CORS-enabled (`Access-Control-Allow-Origin: *`). ### `GET /api/markets?slugs=a,b,c` Batch market lookup. Returns `{ markets: OrreryMarket[], fetchedAt: ISO8601 }`. Up to 50 slugs per request. Cached `s-maxage=30, stale-while-revalidate=60`. ### `GET /api/search?q=` Live market full-text search. Returns up to 20 results matching question / category / slug. Used by the command palette. ### `GET /api/wallets?address=<0x…>` Returns `{ address, positions, activity, pseudonym, fetchedAt }`. Address must be a valid Ethereum address. Cached `s-maxage=60`. ### `POST /api/explain` Streaming "why did it move?" explanation. Body shape: ```json { "slug": "string", "question": "string", "category": "string", "price": 0.0, "priceChange1h": 0.0, "priceChange24h": 0.0, "priceChange1w": 0.0, "volume24h": 0.0, "liquidity": 0.0, "spread": 0.0, "endDate": "ISO8601 | null", "umaResolutionStatus": "string | null", "trades": [ { "side": "BUY|SELL", "outcome": "Yes|No", "usdValue": 0, "price": 0, "timestamp": 0, "pseudonym": "string|null" } ] } ``` Returns `text/plain` chunked stream. Header `x-orrery-explain-source: claude-sonnet-4-6 | heuristic` exposes the generation backend. When the backend can't reach Claude, the route falls back to a deterministic summary from the supplied metrics. ### `POST /api/copilot` Streaming free-text Q&A. Body: `{ question: string }`. Server fetches a fresh data snapshot (top 60 markets + active signals + summary) and provides it to the model as the user message. System prompt enforces: - ground every claim in the supplied data; - cite specific market questions and numbers; - never predict future direction; - refuse "insider info" requests; - redirect off-topic questions. ### `POST /api/brief/subscribe` Subscribe an email to the Daily Brief. Body: `{ email, source }`. ### `POST /api/brief/deliver` Cron-triggered delivery. Auth via `Authorization: Bearer ${CRON_SECRET}`. When `RESEND_API_KEY` is set, sends to all subscribers; otherwise returns a dry-run response. ### `POST /api/waitlist` Generic waitlist capture for non-brief features. Body: `{ email, source }`. --- ## 3a. Paid agent API (x402) The paid agent surface lives under `/api/x402/v1/...`. Discovery files: - `/pricing` — commercial packaging, use cases, pricing ladder, snippets. - `/docs/agents` — human docs for x402, MCP, CLI, Python, TypeScript, cURL. - `/docs/agents/demos` — use-case playbooks with cURL, Python, and TypeScript examples. - `/docs/agents/sdk` — typed TypeScript and Python SDK package docs. - `/api/v1/manifest` — free machine-readable manifest with endpoint jobs. - `/.well-known/x402-services.json` — service catalog with prices. - `/x402-openapi.yaml` — OpenAPI 3.1 spec. Production paid endpoints require x402 settlement. Requests without a valid `X-PAYMENT` proof return HTTP 402 with a JSON challenge. Verified calls return `payment_status: "settled"`. Free health/catalog/manifest routes remain open. Aggregate usage telemetry lives at `/api/status/x402-usage` and is summarized on `/receipts`. It stores counters only: attempts, preview/missing/settled/ rate-limited states, quoted USDC, settled USDC, last-seen timestamp, and per-endpoint totals. It does not persist payer addresses, payment proofs, IPs, request bodies, or user identifiers. --- ## 4. Data shapes ### `OrreryMarket` ```ts { id: string; slug: string; question: string; price: number; // YES probability, 0..1 priceChange1h: number; // probability delta, raw (not pp) priceChange24h: number; priceChange1w: number; volume: number; // lifetime USD volume24h: number; liquidity: number; spread: number | null; // probability points (e.g. 0.02 = 2¢) category: string; // 11 buckets — see §6 categorySlug: string; endDate: string | null; // ISO 8601 closed: boolean; icon: string | null; image: string | null; yesTokenId: string | null; noTokenId: string | null; conditionId: string | null; description: string | null; resolutionSource: string | null; umaResolutionStatus: string | null; negRisk: boolean; momentumScore: number; // 0..100 heuristic updatedAt: string | null; } ``` ### `OrreryTrade` ```ts { address: string; pseudonym: string; side: "BUY" | "SELL"; size: number; price: number; // 0..1 usdValue: number; outcome: string; outcomeIndex: number; timestamp: number; // unix seconds slug: string; title: string; icon: string | null; txHash: string; conditionId: string; } ``` ### `Signal` ```ts { kind: "flow" | "momentum" | "divergence" | "resolution_risk" | "news_lag"; title: string; message: string; slug: string; question: string; category: string; confidence: number; // 0..1, present-time evidence factors: string[]; } ``` ### `SignalCalibration` ```ts { evidence: "low" | "medium" | "high"; evidenceScore: number; // 0..100 edge: "strong" | "mixed" | "weak" | "forward-only"; edgeNote: string; action: "watch_only" | "inspect_timeline" | "create_alert" | "verify_source" | "ignore"; actionLabel: string; } ``` ### `Opportunity` ```ts { market: OrreryMarket; signals: { signal: Signal, market: OrreryMarket }[]; edgeScore: number; // 0..100 confidence: number; // 0..100 capacityEstimate: number; // USD before ~1pp move timeHorizonHours: number; factors: string[]; workflow: "watch-closely" | "verify-source" | "create-alert" | "inspect-timeline" | "compare-venues" | "ignore"; } ``` ### `WalletScore` ```ts { address: string; pseudonym: string | null; openPositions: number; openNotional: number; unrealizedPnl: number; realizedPnl: number; totalPnl: number; roiEstimate: number; tradeCount: number; avgTradeUsd: number; firstSeenAt: number | null; lastSeenAt: number | null; winRate: number | null; winRateSample: number; topCategory: string | null; categoryConcentration: number; qualityScore: number; // 0..100 labels: string[]; // e.g. "whale", "profitable specialist" } ``` --- ## 5. Signal taxonomy | Kind | Trigger | Backtest tier (live) | |---|---|---| | `momentum` | 24h \|move\| ≥ 3pp + 1h aligned with 24h + liquidity > 25k | mixed | | `divergence` | \|1h\| ≥ 1pp moving against 24h, liquidity > 50k | mixed | | `flow` | 3+ aligned trades in 30min, ≥ $5k clustered, distinct wallets | forward-only | | `resolution_risk` | <72h to expiry OR UMA non-resolved OR spread > 6¢ near expiry | forward-only | | `news_lag` | Reserved — needs news ingestion | forward-only | Each signal carries a 0..1 evidence score plus 1–4 explicit factor strings. --- ## 6. Categories Orrery's classifier maps each market to one of 11 buckets: **Crypto · AI · Macro · Geopolitics · Politics · Sports · Weather · Entertainment · Science · Business · Tech**. The classifier first uses Gamma's tag/category if specific, otherwise applies keyword rules in priority order (specific before broader: AI before Tech, Geopolitics before Politics). --- ## 7. Resolution source types Extractor output: **`exchange_price`** (Binance/Coinbase/CoinGecko spot) · **`official_government`** (US gov, White House, agency) · **`sports_official_result`** · **`court_record`** · **`company_filing`** (10-K/Q, SEC filings) · **`news_consensus`** (Reuters, AP, WSJ, NYT) · **`social_media_post`** · **`ambiguous`** (catch-all with low confidence) · **`unknown`**. Each extracted source carries a `confidence: low | medium | high`. --- ## 8. Architecture Frontend: Next.js 15 App Router, React 19, Tailwind 4, TypeScript strict. All data fetched server-side from Polymarket's public APIs with 30–300s revalidation. No separate backend service. Deployed on Vercel. Watchlist, Alerts, Portfolio, Preferences are stored in `localStorage` with `useSyncExternalStore` for reactive client-side state. Plausible analytics — cookieless, no personal data. --- ## 9. Optional integrations (env-keyed) | Env var | Activates | |---|---| | `ANTHROPIC_API_KEY` | Real AI responses on `/api/explain` and `/api/copilot` (claude-sonnet-4-6 with prompt caching). | | `RESEND_API_KEY` + `BRIEF_FROM` + `CRON_SECRET` | Email delivery of the Daily Brief. | | `KV_REST_API_URL` + `KV_REST_API_TOKEN` | Persistent subscriber storage. | Without any keys the site renders fully — every feature degrades to a deterministic heuristic. --- ## 10. Update cadence Most server-rendered pages revalidate every 30–60 seconds. The Daily Brief page revalidates every 5 minutes. Sitemap revalidates hourly. The status page is `force-dynamic` (live probe on every load). --- ## 11. Bot policy `/robots.txt` explicitly allows: GPTBot, ChatGPT-User, Claude-Web, Applebot-Extended, PerplexityBot, Google-Extended, plus the default `User-agent: *`. We welcome AI crawlers and agent integrations — the public APIs above are the supported interface. --- ## 12. Contact | Topic | Email | |---|---| | General | hello@orrery.me | | Privacy / data deletion | privacy@orrery.me | | Press / partnerships | press@orrery.me | | Security | security@orrery.me |