# 0xinsider Agent Instructions

You have access to the 0xinsider API — the data and intelligence layer for Polymarket and Kalshi.
Every wallet is graded, every large trade is scored, every outlier is flagged.
This gives you real-time data on trader behavior, whale trades, smart money flow,
and insider detection across both exchanges.
When responses include trust metadata, treat source/freshness/reconciliation/completeness as part of the value. Do not convert stale, partial, unavailable, or missing provider-owned facts into zeros or empty success states.

Base URL: https://api.0xinsider.com
Auth: Authorization: Bearer oxi_sk_live_...
Rate limit: 100 req/min per user. Respect Retry-After on both 429 rate_limited and 503 rate_limit_unavailable responses.
Mutation retries: reuse the same Idempotency-Key only when repeating the exact same authenticated POST body on /api/billing/* or /api/keys* routes.
Transport: normal API requests time out after 30s with HTTP 408 and an empty body; successful browser preflights cache for 24h via Access-Control-Max-Age: 86400.
TypeScript client source: web/src/lib/api-client. It is drift-tested against OpenAPI and is source/example code, not a published npm package yet.
Docs: https://0xinsider.com/llms-full.txt

---

## What you can do

You answer questions about prediction markets using real data, not guesses.
Every response should be grounded in what the API returns.

### Core capabilities

1. **Evaluate traders** — Look up any wallet address or known username. Get their grade (S-F),
   P&L, win rate, ML-detected strategy, and per-category strengths.

2. **Track whale trades** — See every $5K+ trade in real-time. Filter by
   trader grade or category. Each trade has a signal score (0-1).

3. **Analyze markets** — For any market, see which direction smart money
   favors, who the top holders are, and how much volume is flowing.

4. **Find top traders** — Leaderboard ranked by grade, P&L, volume, or
   win rate. Use /trending/wallets for the public weekly realized-P&L discovery page.

5. **Discover markets** — Browse whale-active titled markets grouped by event.

6. **Search markets** — Find any prediction market by keyword.

7. **Detect insider activity** — Suspicious trading patterns: coordinated
   wallets, pre-resolution accumulation, unusual timing. Unique data.

---

## Decision tree: which endpoint to call

User asks about a TRADER (address or username):
  → GET /api/v1/trader/{address} (path accepts a wallet address or username)
  → POST /api/v1/traders/batch when comparing 2-25 traders in one workflow
  → Add ?expand=strategy if they ask about strategy (?expand[]=strategy also accepted)
  → Add ?expand=categories if they ask about category performance
  → Add ?expand=quant_metrics if they ask about risk metrics (Sharpe, drawdown)
  → GET /api/v1/trader/{address}/export if they ask about dataset export coverage or readiness

User asks about a MARKET (what's happening on X):
  → GET /api/v1/markets/search?q={keyword} to find the condition_id
  → GET /api/v1/market/{condition_id}/snapshot for one provider-first market card with freshness
  → GET /api/v1/market/{condition_id}/intel for smart money analysis
  → POST /api/v1/markets/intel/batch when comparing 2-25 condition_id values
  → Optionally GET /api/v1/insider-radar to check for suspicious activity

User asks which MARKETS deserve attention right now:
  → GET /api/v1/markets/explore
  → Use ?sort=trending, ?category=, ?platform=, and ?q= to narrow the board

User asks about WHALE TRADES (big moves, what's happening now):
  → GET /api/v1/whale-trades
  → Use ?min_grade=S or ?min_grade=A to focus on top traders
  → Use ?category=crypto (or politics, sports, etc.) to filter

User asks about HISTORICAL WHALE ACTIVITY (replay, backtest, missed window):
  → GET /api/v1/whale-trades/history
  → Use ?condition_id=, ?trader=, ?category=, ?platform=, ?from=, and ?to= to scope replay
  → Metadata says local_replay/best_effort; do not describe it as complete provider history

User asks about CURRENT POSITIONS (what are sharp wallets holding right now):
  → GET /api/v1/positions
  → Use ?min_grade=S or ?min_grade=A to focus on top traders
  → Use ?min_size=10000 to focus on meaningful size
  → Use ?side=yes or ?side=no to filter by outcome side
  → Orthogonal to /api/v1/whale-trades — that shows fills, this shows state

User asks about TOP TRADERS (who's the best, leaderboard):
  → GET /api/v1/leaderboard
  → Use ?category= to find category specialists
  → Use ?strategy= to find strategy specialists
  → Link users to /trending/wallets when they want who is winning this week

User asks about SUSPICIOUS ACTIVITY (insider trading, manipulation):
  → GET /api/v1/insider-radar?min_suspicion=60
  → Higher min_suspicion = more confident flags

User asks if the API is UP, reachable, or safe to start polling:
  → GET /api/v1/health
  → No auth required

User wants machine-to-machine alert delivery:
  → POST /api/v1/webhooks to create a pending signed webhook destination
  → POST /api/v1/webhooks/{id}/verify with the one-time verification token before expecting deliveries
  → Use only public event types: whale_trades_inserted, live_sports_updated, whale_trader_synced, large_positions_updated

User asks for REPORT snapshots:
  → GET /api/v1/reports/daily?date=YYYY-MM-DD for a daily snapshot
  → GET /api/v1/reports/weekly?week=YYYY-WW or ?from=YYYY-MM-DD&to=YYYY-MM-DD for a weekly snapshot
  → GET /api/v1/reports/monthly?month=YYYY-MM for a monthly snapshot
  → Check snapshot.status and completeness.status before treating the range as final

User asks a COMPLEX question (e.g., 'what's the best trade right now'):
  → Chain multiple calls:
    1. GET /api/v1/whale-trades?min_grade=S&limit=20
    2. GET /api/v1/leaderboard?limit=10
    3. Cross-reference: which markets have multiple top traders on the same side?
    4. GET /api/v1/insider-radar to check for red flags

---

## Endpoint Reference

### GET /api/v1/trader/{address}
Trader intelligence for a wallet address or username. Returns grade (S-F), P&L, win rate, strategy, categories.
Params: expand or expand[] (strategy, categories, quant_metrics)
Unknown traders return sync_status: unknown — poll again in 30s.

### POST /api/v1/traders/batch
Batch trader intelligence for 1-25 wallet addresses or usernames.
JSON body: { traders: string[], expand?: (strategy|categories|quant_metrics)[] }.
Preserves request order and duplicates. Each result has index, input, status, and either data or error.
Costs one batch item unit per requested trader and exposes X-Request-Cost plus X-Batch-RateLimit-* headers.

### GET /api/v1/trader/{address}/position-timeline
Per-market chronological fill timeline for one trader. HOT and WARM tier only (404 otherwise).
Required query: condition_id. Optional: limit (1-100, default 20), cursor.
Each event carries running_amount and running_avg_price computed server-side in SQL.
running_avg_price is a buy-weighted entry basis (matches Polymarket /positions avgPrice) — sells do not change it.
Use when: reconstructing a trader's exact position-over-time in one market, or comparing their entry basis to current price.

### GET /api/v1/trader/{address}/export
Metadata-only export snapshot for one trader. Does not stream or create a raw dataset export.
Returns source_range, completeness, volume reconciliation, estimated rows, and large_export_policy.
Provider lifetime volume and local export activity volume are separate fields; do not treat them as the same unit.
Use when: checking export readiness, coverage, or expected export size before requesting a full internal export.

### GET /api/v1/traders/{id}/position-timeline
Id-keyed alias of /trader/{address}/position-timeline. Takes the integer traders.id in the path instead of a wallet address.
Response body is byte-identical for the same underlying trader — same 404 rules, same query params, same cursor semantics.
Use when: a worker task or agent client already holds a numeric traders.id and wants to skip the wallet round-trip.

### GET /api/v1/whale-trades
Recent large trades with signal scoring.
Params: min_size (default 5000), category, min_grade (S/A/B/C/D/F), limit (1-100), cursor
Category uses provider-backed market_canonical identity.
min_grade=A means S or A; filters apply before cursor pagination.
Signal score 0-1: higher = more significant trade.
Cursor-paginated. Newest first.

### GET /api/v1/whale-trades/history
Historical replay of whale trades from local whale_alerts rows.
Params: condition_id, trader, category, min_grade (S/A/B/C/D/F), platform (polymarket/kalshi/all), from, to, min_size (default 5000), limit (1-100), cursor
Ordered by traded_at desc, id desc. Cursor prefix: wth_. URL-encode next_cursor when replaying it as a query parameter.
All filters are pushed into SQL before LIMIT. No offset pagination.
meta.source.kind is local_replay; meta.source.table is whale_alerts; meta.source.provider_fetch_at_request_time is false.
meta.completeness.status is best_effort because provider backfill completeness can vary by market and time window.
Use when: backtesting whale activity, replaying missed windows, or reconstructing historical trader/market activity.
Not live/current data; use /api/v1/whale-trades for the recent large-trades feed.

### GET /api/v1/positions
Current positions-board feed from the wallet_positions mirror.
Params: min_size (default 100), category, min_grade (S/A/B/C/D/F), side (yes/no), limit (1-100), cursor
Ordered by current_value_usd DESC with deterministic tiebreakers (wallet, condition_id, outcome_index).
Pre-reconcile rows (NULL current_value_usd) are excluded from V1.
min_grade is allowlist-expansion: A matches S and A; B matches S, A, B; etc.
Polymarket-only in Slice 5; platform field stays in the response for forward compat.
Cursor-paginated. Response shape mirrors /api/v1/whale-trades envelope.

### GET /api/v1/market/{condition_id}/intel
Smart money flow for a specific market.
Params: timeframe (1h, 4h, 24h, 7d)
Returns: net_flow_usd, direction (YES/NO), top trader positions, whale count.
Use markets/search first to get the condition_id. Do not pass the prefixed market.id (mkt_...).

### POST /api/v1/markets/intel/batch
Batch smart-money flow for 1-25 raw condition_id values.
JSON body: { condition_ids: string[], timeframe?: 1h|4h|24h|7d }.
Preserves request order and duplicates. Each result has index, input, status, and either market_intel data or error.
Costs one batch item unit per requested condition_id. Prefixed mkt_... IDs are per-item errors.

### GET /api/v1/market/{condition_id}/snapshot
Provider-first market card snapshot.
Returns: market identity, provider outcome labels, cached top-of-book when available, liquidity, live sports context, and freshness statuses.
Freshness: market_data fresh/stale/unavailable; top_of_book available/unavailable; live_sports fresh/stale/not_live/unavailable.
Missing provider values stay null or unavailable. Do not derive teams, sides, category, or market identity from title or slug.

### GET /api/v1/leaderboard
Top traders ranked by score.
Params: category, strategy, limit (1-100), cursor
Conditional GET: returns ETag; send If-None-Match to receive 304 Not Modified when unchanged.
Strategy types: accumulator, algo_trader, arbitrageur, directional, event_driven,
  market_maker, momentum, scalper, speculator, swing_trader

### GET /api/v1/markets/search
Search markets by keyword.
Params: q (required, 1-512 chars before trim, non-empty after trim), category, status (active/closed/all), limit (1-100), cursor
Returns representative market matches with condition_id — use this with /market/{condition_id}/intel.

### GET /api/v1/markets/explore
Browse whale-active titled markets for discovery surfaces.
Params: category, status (active/closed/all), platform (polymarket/kalshi/all), sort (trending/whales/volume/newest), q, limit (1-48), cursor
Conditional GET: returns ETag; send If-None-Match to receive 304 Not Modified when unchanged.
Returns grouped event rows or standalone markets, plus live category/platform facets. Categories are provider-native (Polymarket Gamma, Kalshi). Facet entries are {value, label, count} — no parent/child taxonomy. total is present on the first page and omitted on cursor pages. Use url_slug for first-party market pages.

### GET /api/v1/insider-radar
Suspicious trading patterns.
Params: min_suspicion (0-100), severity (flag/watch), limit (1-100), cursor
Scores break down WHY it's suspicious (timing, edge, size, fresh_wallet).
No other platform exposes this data.

### GET /api/v1/events/feed/since
Replay durable public whale-trade intelligence events after an opaque cursor backed by whale_alerts.id.
Params: cursor, limit (1-100, default 50)
Event types: whale_trades_inserted.
Browser-only sports/trader-sync/large-position events and private alert, following, radar, and position patch events are excluded until they have a durable public outbox.
Store next_cursor and pass it on the next request. Cursors are valid across backend replicas because they map to whale_alerts.id.
No provider fetch happens at request time; source.kind is local_durable_replay and each event includes source/freshness metadata.

### GET /api/v1/webhooks
List signed builder webhook destinations owned by the authenticated API key user.
Event types: whale_trades_inserted, live_sports_updated, whale_trader_synced, large_positions_updated.
Webhook URLs must be public HTTPS URLs. Localhost, private IPs, .local, .internal, URL credentials, and non-HTTPS schemes are rejected.
Signatures use timestamped HMAC-SHA256 in the 0xinsider-signature header over `${timestamp}.${rawBody}`. Reject signatures older than 5 minutes.
Delivery retries use stable idempotency keys and dead-letter after 8 failed attempts.

### POST /api/v1/webhooks
Create a pending signed builder webhook destination with name, public HTTPS url, and event_types.

### GET /api/v1/webhooks/{id}
Read one webhook destination owned by the authenticated API key user.

### PATCH /api/v1/webhooks/{id}
Update webhook name, url, event_types, or enabled state.

### DELETE /api/v1/webhooks/{id}
Delete one webhook destination.

### POST /api/v1/webhooks/{id}/verify
Verify a pending webhook destination with its one-time token before expecting deliveries.

### POST /api/v1/webhooks/{id}/rotate-secret
Rotate the signing secret for one webhook destination.

### GET /api/v1/reports/daily
Daily report snapshot for a UTC date.
Required query: date=YYYY-MM-DD.
Returns source_range, snapshot.status, completeness.status, reconciliation.volume_kind, and report totals.
Report volume is local whale-alert activity volume, not provider lifetime trader volume.

### GET /api/v1/reports/weekly
Weekly report snapshot for an ISO week or explicit UTC date range.
Queries: week=YYYY-WW or from=YYYY-MM-DD&to=YYYY-MM-DD.
Check snapshot.status before treating the range as final.

### GET /api/v1/reports/monthly
Monthly report snapshot for a UTC month.
Required query: month=YYYY-MM.
Returns the same report_snapshot shape as daily and weekly.

### GET /api/v1/health
Unauthenticated health check for uptime probes and connectivity validation.
Returns: status, db, cache, and aggregate subsystems.background_jobs checked/count/status fields.
Rate limit: 60 req/min per IP.
Conditional GET: returns ETag; send If-None-Match to receive 304 Not Modified when unchanged.
Background job health is public-safe aggregate only; no Redis keys, job names, raw errors, provider payloads, wallet addresses, or condition IDs.
Use this before authenticated polling if you only need a liveness signal.

### GET /api/v1/mcp
Remote Model Context Protocol endpoint (MCP Streamable HTTP transport, protocolVersion 2025-11-25).
Also accepts POST for JSON-RPC 2.0 requests: initialize, notifications/initialized, ping, tools/list, tools/call.
Auth via Authorization: Bearer. ?token= remains a legacy URL-only compatibility path; prefer headers or the stdio package because URL secrets are easier to leak through logs and history.
Call initialize first; the server mints an Mcp-Session-Id header that you echo on every follow-up request.
Exposes the same 9 tools as the @0xinsider/mcp stdio package: get_leaderboard, get_trader, get_whale_trades, get_market_intel, get_insider_radar, get_positions, get_position_timeline, search_markets, explore_markets.
GET opens an optional server-to-client SSE stream; all method calls flow over POST.

### POST /api/v1/mcp
Remote MCP JSON-RPC 2.0 endpoint for initialize, notifications/initialized, ping, tools/list, and tools/call.
Same auth, rate limits, billing, and Mcp-Session-Id requirements as GET /api/v1/mcp.

---

## Response format

Single: { object: 'trader', data: {...}, meta: { request_id, cached, cache_age_s } }
List: { object: 'list', data: [...], has_more, next_cursor, meta: {...} }
Event replay: { object: 'event_replay', data: [...], has_more, next_cursor, meta: { replay, retention, completeness } }
Error: { object: 'error', error: { code, message, doc_url, param }, meta: {...} }

IDs are prefixed: trd_ (trader), mkt_ (market), wt_ (whale trade), rf_ (radar flag)
Money values truncated to 2 decimals. Rates/prices to 4 decimals.

---

## Best practices

- Always check has_more and use next_cursor for pagination. Never use offset.
- Use min_grade=S or min_grade=A to focus on high-quality signals.
- Use expand only when needed — each expansion adds latency. The expand[] alias is also supported.
- For polling bots, prefer /api/v1/events/feed/since to learn what changed, then fetch the relevant read endpoint.
- For whale-trade polling, use /api/v1/events/feed/since plus /api/v1/whale-trades cursors/IDs to avoid duplicate processing.
- Signal scores near 1.0 indicate high-conviction trades worth investigating.
- Cross-reference: if multiple S-grade traders are on the same side of a market, that's a strong signal.
- Check insider-radar before making recommendations — flagged markets may have manipulation risk.
- Use /api/v1/health for liveness checks instead of spending authenticated requests on reachability tests.
- Treat 503 rate_limit_unavailable as a retryable auth-gate dependency outage; back off for the Retry-After window instead of hammering other authenticated endpoints.
- Treat HTTP 408 as a retryable transport timeout, not as a structured JSON API error response.
- Grades: S (exceptional), A (strong), B (above average), C (average), D (below average), F (poor).
- When a trader has sync_status: unknown, the system is importing their data. Try again in 30-60 seconds.

## What NOT to do

- Don't fabricate data. If the API returns null or empty, say so.
- Don't call expand=strategy on every request — it adds 200ms. Only when the user asks about strategy.
- Don't ignore signal_score. A $50K trade from an F-grade trader (signal: 0.1) is noise. A $10K trade from an S-grade trader (signal: 0.9) is signal.
- Don't treat whale trades as recommendations. They're intelligence, not advice.
- Don't poll faster than every 15 seconds for whale trades. The cache is 15s.


## Remote MCP endpoint

- POST/GET https://0xinsider.com/api/v1/mcp — MCP Streamable HTTP transport, protocolVersion 2025-11-25.
- Auth: Authorization: Bearer. Same key + same rate limits as the REST endpoints. ?token= is legacy compatibility for URL-only clients; prefer headers or the stdio package.
- Call `initialize` first; the server mints an Mcp-Session-Id header that you echo on every follow-up request.
- 9 tools exposed (identical shape to the @0xinsider/mcp stdio package): get_leaderboard, get_trader, get_whale_trades, get_market_intel, get_insider_radar, get_positions, get_position_timeline, search_markets, explore_markets.
- Origin header, when sent, must match the 0xinsider/localhost allowlist or the server returns HTTP 403.
- For Node environments the stdio package (`npx -y @0xinsider/mcp init`) remains supported and is equivalent.

Full API reference: https://0xinsider.com/llms-full.txt
OpenAPI spec: https://0xinsider.com/api/v1/openapi.json
Docs: https://docs.0xinsider.com
