# Polystrike API Documentation for LLMs Generated on: 2026-09-15T17:03:55.552Z --- FILE: SKILL.md (Agent API Guide) --- --- name: polystrike-agent-api description: Real-time tweet-count data, market metadata, and model signals for Polymarket using Polystrike data. license: MIT metadata: version: "1.2" subject: "Elon Musk" platform: "Polymarket" # The venue where trades are executed provider: "Polystrike" # The source of the API/Data --- # Polystrike Agent API > **Context**: This skill provides the tools and strategies for AI agents to trade on **Polymarket's** Elon Musk tweet count markets using **Polystrike's** low-latency data layer (measured p50 11.5s from post to counted; see §1.D). **Contact**: [@dizpers](https://x.com/dizpers) on X. ## 1. Scope & Capabilities This skill provides a **low-latency data layer** for Polymarket: tweet counts, velocity, sleep-state, and oracle/UI deltas, with a measured median of **11.5s** from a post going up to it being counted (full figures in §1.D). Use it to *monitor* the market accurately — know the real count before the UI refreshes and avoid pricing against a stale display. It is **not** a guaranteed or riskless trading edge (see the honesty note below). ### A. Market Metadata (Elon Musk & Ted Cruz) We provide the **Ground Truth** for Elon Musk and Ted Cruz tweet markets. - **Live Counters** (p50 11.5s from post to counted): Precise count of *qualified* tweets vs *settled* tweets. - **Tweet Stream**: Raw feed of every new tweet (including deleted ones) for sentiment analysis. - **State Tracking**: Monitoring of sleep/wake state for velocity modeling. **Why it matters**: Polymarket's UI varies by 30s-5m from reality. Without this metadata, you are pricing on stale counts. With it, you see count changes minutes before the UI reflects them — useful for not trading against a display that is behind the real count. ### B. Monitoring Signals (Counters & Deltas) - **`settlement_delta`**: flags when our real count is ahead of the settlement oracle. The oracle usually catches up, but a deleted tweet can reverse the gap — see Risk Warnings. - **`display_delta`**: tracks how stale the Polymarket UI count is. Note: the order book generally prices on the real/oracle count and ignores the lagging UI, so a display gap is **monitoring information, not a riskless edge** — verify prices before acting. ### C. Predictive Modeling & Signals (Pro Only) - **Forecast Outcomes**: Access Monte Carlo simulations (1000 runs) that account for sleep schedules and mean reversion. - **EV-Based Signals**: Receive `BUY` / `SELL` signals scored for Expected Value (EV), with Kelly Criterion bet sizing. These are model estimates, not guarantees — prediction markets carry risk. ### D. Data Freshness (measured on production, 2026-07-29) Every figure below is measured, not designed-for. Where a number is a median we say so. | What | Cadence / latency | |---|---| | **Tweet detection** — post published → counted in our canonical table | **p50 11.5s**, p90 12.6–15.1s, p99 28.2s, worst observed 631s | | X timeline poll | **1s** for `@elonmusk`, **5s** for other tracked accounts | | Engagement-metric refresh (likes/reposts) | full timeline re-read every **10 min** | | Deletion confirmation | absent from **2 consecutive** re-reads → confirmed in **~20 min** (deliberately conservative: X's timeline transiently omits posts) | | `real_counter` / deltas on `meta/*` | recomputed as each qualifying post lands (no extra response cache) | | Model recompute on `prediction/*` and `signals/*` | **60s** while an event is inside its final 24h, **300s** otherwise | | Polymarket CLOB order book (source of `market_price`) | **2s** poll loop across tracked tokens; it cycles many tokens, so effective per-token resolution is **~40s** | | XTracker settlement oracle (not ours) | roughly **5 min** | Four things worth knowing before you build against this: - **X's index is the floor, not our polling.** X's REST timeline needs ~10.8s at minimum to list a new post, and the latency is quantized. We already poll faster than X publishes, so polling harder does not move the median. - **Engagement metrics lag by design.** Likes and reposts are zero at the moment a post is first seen — the post is seconds old. The 10-minute full re-read fills in real numbers, so treat engagement as correct within one cycle, not immediately. - **We also run an X filtered stream.** Measured head-to-head over 4 days it detects at **p50 6.3s**, about **5.2s** faster than the poller. It is a measurement path today and does **not** feed the counters these endpoints serve; the poller remains the writer, and it is retained regardless because a push stream cannot observe a deletion. - **This speed is not an edge, and we will not sell it as one.** Our own zero-dollar paper court measured that when a count boundary breaks, the price collapse completes in roughly **2–3 seconds** — upstream of both our poller and our stream. We are explicitly not winning that race. These numbers tell you how current a number is, nothing more. **Honesty note**: Our own research found the UI-vs-oracle divergence is **not by itself a tradeable edge** — the Polymarket book prices on the real/xtracker count, so acting on the displayed lag is roughly breakeven. Use this data to stay correctly informed and avoid stale-price mistakes, not as a promise of profit. **Current Scope**: Elon Musk and Ted Cruz Tweet Count Markets. ## 2. Authentication The API has two tiers: 1. **Anonymous (Public)** - **No Key Required** - **Rate Limit**: 100 requests/hour (all endpoints, including `meta/*`, are rate-limited) - **Freshness**: counters are **delayed 30 minutes**; every response carries `freshness: delayed` and `freshness_delay_sec: 1800`. - **Access**: Metadata, all three counters and deltas, `seconds_remaining`, and per-bucket `market_price` on the prediction endpoint. Enough to follow a market. 2. **Data ($29/mo, $290/yr)** - **Requires Key**: `X-API-Key: ps_pro_...` - **Rate Limit**: 10,000 requests/hour - **Access**: Everything above **live (no delay)**, the WebSocket feed, the full post archive, counter history and bucket price history (`/api/v1/history/*`), bulk parquet (`/api/v1/bulk/*`), plus the model fields on `prediction/*`. - **Upgrade**: pay USDC on Polygon or Base, then submit the tx hash and your email at https://polystrike.xyz/#waitlist or `hello@polystrike.xyz`. Keys are issued by hand, usually within a few hours. 3. **Pay-per-call ($0.01/call)** - No key: retry a 402 with an `X-PAYMENT` header (x402, USDC on Base). Same live data as Data, one call at a time. - **Base URL**: `https://polystrike.xyz` - **OpenAPI Spec**: `https://polystrike.xyz/openapi.json` ## 3. Endpoints & Strategies ### 1. Market Metadata (The Ground Truth) **Endpoints**: - `GET /api/v1/meta/elon` - Elon Musk markets - `GET /api/v1/meta/cruz` - Ted Cruz markets **Tier**: **Public** (Free, rate-limited to 100 req/hr since 2026-07-23) **Goal**: Track oracle/UI deltas via the three counters. ```bash curl https://polystrike.xyz/api/v1/meta/elon curl https://polystrike.xyz/api/v1/meta/cruz ``` **Response**: ```json { "timestamp": 1770733363222, "data": [ { "event_id": 194167, "event_title": "Elon Musk # tweets Feb 3-10", "polymarket_xtracker_counter": 215, // Settlement (Oracle) "real_counter": 220, // Reality (Ground Truth) "polymarket_ui_counter": 215, // Display (Website) "settlement_delta": 5, // real - xtracker "display_delta": 5, // real - ui "internal_delta": 0 // ui - xtracker } ] } ``` **Key Fields**: - `image`: Event image URL from Polymarket. - `settlement_delta`: The gap between Reality and Oracle. If `> 0`, our count is ahead — the oracle usually catches up, but a deleted tweet can reverse the gap. - `display_delta`: The gap between Reality and UI. If `> 5`, the UI shows a stale count. Note: the order book often tracks the real count even when the UI lags — verify prices before assuming an edge. - `real_counter`: The actual number of qualified tweets sent by Elon. - `polymarket_xtracker_counter`: The number currently recognized by the UMA oracle/Polymarket settlement. --- ### 2. Tweet Stream (Sentiment & Velocity) **Endpoint**: `GET /api/v1/meta/elon/tweets` **Tier**: **Public** (Masked) / **Pro** (Full) **Goal**: Analyze raw tweet content or detect deletions. **Query Parameters (Pro Only)**: - `limit`: Number of tweets to return (max 100). - `offset`: Number of tweets to skip. > **Note**: Free users are fixed at the latest **15 tweets**. Query parameters are ignored. ```bash curl https://polystrike.xyz/api/v1/meta/elon/tweets ``` **Response (Public)**: ```json { "timestamp": 1770734408963, "data": [ { "tweet_id": "2021230513298473031", "text": "SpaceX is launching...", "created_ts": 1770733881000, "is_reply": false, "is_quote": false, "is_retweet": false, "is_counted": null // Pro users see true/false } ], "limit": 15, "offset": 0 } ``` **Key Fields**: - `text`: The raw content of the tweet. - `is_counted`: **Pro Only**. Returns `true` if the tweet counts towards the market resolution (filtering replies/retweets). Public users see `null`. - `created_ts`: Unix timestamp of the tweet (in milliseconds). --- ### 3. Prediction Model (Monte Carlo) **Endpoint**: `GET /api/v1/prediction/elon` **Tier**: **Public** (counters, `seconds_remaining`, per-bucket `market_price`) / **Pro** (model outputs) **Goal**: Forecast the final count using our sleep-aware model. > **Tier split (as of 2026-07-23)**: FREE returns the counters/deltas, `seconds_remaining`, and each bucket's `market_price`. The model outputs — the `p5`/`p50`/`p95` forecast, `model_prob`, `edge`, `signal`, `sleep_probability`, and the `velocity_counted_1h` / `velocity_all_1h` projection inputs — are **Pro only**, so a free consumer cannot reconstruct the projection. ```bash curl -H "X-API-Key: ps_pro_..." https://polystrike.xyz/api/v1/prediction/elon ``` **Response (Pro)**: ```json { "timestamp": 1770733363222, "data": [ { "event_id": 194167, "seconds_remaining": 43200, "forecast": { "p5": 224, // 5% chance count < 224 "p50": 242, // Median forecast "p95": 272 // 95% chance count < 272 }, "markets": [ { "title": "240-259", "model_prob": 0.45, "market_price": 0.35, "edge": 0.10, "signal": "BUY" } ] } ] } ``` **Key Fields**: - `forecast`: Probabilistic outcome range. `p5` is the floor, `p95` is the ceiling. - `model_prob`: The probability of the outcome falling in this bucket according to our simulation. - `market_price`: The current price on Polymarket (implied probability). - `signal`: Trading recommendation (`BUY`, `SELL`, `HOLD`). --- ### 4. EV-Based Signals **Endpoint**: `GET /api/v1/signals/elon` **Tier**: **Pro Only** **Goal**: Get a sorted list of actionable trading signals optimizing for Expected Value (EV). ```bash curl -H "X-API-Key: ps_pro_..." https://polystrike.xyz/api/v1/signals/elon ``` **Response**: ```json { "timestamp": 1771246739535, "data": [ { "event_id": 206602, "signals": [ { "bucket": "65-89", "action": "BUY", "model_prob": 1.0, "market_price": 0.945, "edge": 0.055, "ev": 0.058, "kelly_fraction": 0.058, "suggested_bet": 2.50, "confidence": "HIGH", "moneyness": 0.5, "time_confidence": "HIGH", "asymmetry_edge": 0, "reasons": [ "Strong signal: 100% prob, +5.8% EV" ] } ] } ] } ``` --- ### 5. Portfolio Analysis **Endpoint**: `GET /api/v1/portfolio/elon?wallet=0x...` **Tier**: **Pro Only** **Goal**: Manage positions against model predictions. ```bash curl -H "X-API-Key: ps_pro_..." "https://polystrike.xyz/api/v1/portfolio/elon?wallet=0xYourWalletAddress" ``` --- ## 4. Integration Examples ### Example: Arbitrage Bot (Python / Public Tier) ```python import aiohttp import asyncio async def check_arb(): async with aiohttp.ClientSession() as session: # 1. Fetch Metadata (Public Endpoint) async with session.get("https://polystrike.xyz/api/v1/meta/elon") as resp: data = await resp.json() for event in data["data"]: # 2. Check for Settlement Lag (oracle behind) if event["settlement_delta"] > 0: print(f"🚨 LAG: Oracle is behind by {event['settlement_delta']} tweets!") # Real count ahead — verify it is not deletion-driven before trading # 3. Check for UI Lag (stale display) if event["display_delta"] > 5: print(f"⚡ SPEED: UI is lagging by {event['display_delta']} tweets.") # Displayed count stale — check book prices vs real count ``` --- ## 5. Risk Warnings - **Deleted Tweets**: Tweets are counted as soon as they are detected (p50 11.5s). If Elon deletes a tweet, `real_counter` drops only once the deletion is *confirmed*: the post must be absent from two consecutive 10-minute reconciliation passes, so expect roughly **20 minutes**, not immediately. XTracker drops it within ~5 minutes, so `settlement_delta` is inflated by exactly that post until we catch up. - *Mitigation*: Wait for `settlement_delta >= 2` before going all-in. - **Model Variance**: Predictions >48h out have ±40% error bars. Trust the model signals (`p5`/`p95`) mainly in the final 24h. --- built with 🤖 by [Polystrike](https://polystrike.xyz) --- FILE: docs/api/cruz.md --- --- title: Ted Cruz Tweet Markets description: Documentation for Polystrike's Ted Cruz tweet-tracking data feed. --- Polystrike provides accurate and low-latency tracking for Polymarket's Ted Cruz tweet count markets. `@tedcruz` is polled every 5 seconds; X's own REST timeline index needs about 10.8 seconds at minimum to list a new post, so that index build sets the floor rather than our polling. ## Endpoints ### Metadata Overview `GET /meta/cruz` **Public** (no key required, rate-limited to 100 req/hr since 2026-07-23). Returns current counters and lag deltas for all active Cruz events. **Sample Response:** ```json { "timestamp": 1774250948000, "data": [ { "event_id": 262360, "event_title": "Ted Cruz # posts March 17 - March 24, 2026?", "start_ts": 1773964800000, "end_ts": 1774569600000, "polymarket_xtracker_counter": 67, "real_counter": 67, "polymarket_ui_counter": 67, "settlement_delta": 0, "display_delta": 0, "internal_delta": 0 } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `event_id` | number | Unique ID of the Polymarket event. | | `event_title` | string | Human-readable event title from Polymarket. | | `image` | string | Event image URL from Polymarket. | | `start_ts` / `end_ts` | number | Event window start/end times (UTC milliseconds). | | `polymarket_xtracker_counter` | number | Settlement oracle count. This is what Polymarket pays out on. | | `real_counter` | number | Polystrike's own count, advanced as posts land. Faster than the oracle; includes deleted tweet captures. | | `polymarket_ui_counter` | number | Count currently displayed on the Polymarket trading UI. | | `settlement_delta` | number | `real_counter − xtracker`. Positive = we're ahead of the oracle. | | `display_delta` | number | `real_counter − ui_counter`. Positive = UI is showing a stale number. | | `internal_delta` | number | `ui_counter − xtracker`. Positive = UI is ahead of the oracle. | ### Predictive Models `GET /prediction/cruz` **Public** (Limited) / **Pro** (Full). Tier split gated 2026-07-23. - **Public**: Counters and deltas, `seconds_remaining`, and per-bucket `market_price`. - **Pro**: Forecasts (p5/p50/p95), `model_prob`, `edge`, `signal`, `sleep_probability`, and the `velocity_counted_1h` / `velocity_all_1h` projection inputs. A free consumer cannot reconstruct the projection. **Sample Response (Pro):** ```json { "timestamp": 1774250948000, "data": [ { "event_id": 262360, "seconds_remaining": 115200, "sleep_probability": 0.092, "velocity_counted_1h": 2.1, "velocity_all_1h": 4.4, "forecast": { "p5": 75, "p50": 89, "p95": 105 }, "markets": [ { "title": "80-99", "model_prob": 0.62, "market_price": 0.32, "edge": 0.30, "signal": "STRONG_BUY" } ] } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `forecast.p5/p50/p95` | number | **Pro Only**. Monte Carlo forecast percentiles. | | `sleep_probability` | number | **Pro Only** (gated 2026-07-23). Probability Cruz is currently sleeping. | | `velocity_counted_1h` / `velocity_all_1h` | number | **Pro Only** (gated 2026-07-23). Counted / all tweets per hour over the last hour — the model's projection inputs. | | `markets.model_prob` | number | **Pro Only**. Our calculated win probability. | | `markets.market_price` | number | Current "Yes" price on Polymarket. Available on the free tier. | | `markets.edge` | number | **Pro Only**. `model_prob - market_price`. | | `markets.signal` | string | **Pro Only**. `STRONG_BUY`, `BUY`, `HOLD`, `SELL`. | ### EV-Based Signals `GET /signals/cruz` **Pro Only**. Returns trading signals scored for Expected Value (EV), with Kelly Criterion bet sizing. These are model estimates, not guaranteed profits. **Query Parameters:** | Parameter | Required | Description | |-----------|----------|-------------| | `bankroll` | No | Your bankroll in USD (1-1,000,000). Sizes `suggested_bet` via Kelly criterion. If omitted, a server default is used. | ``` GET /api/v1/signals/cruz?bankroll=100 ``` **Sample Response:** ```json { "timestamp": 1774250948000, "data": [ { "event_id": 262360, "event_title": "Ted Cruz # posts March 17 - March 24, 2026?", "signals": [ { "bucket": "80-99", "token_id": "0x1234...", "action": "BUY", "model_prob": 0.62, "market_price": 0.32, "edge": 0.30, "ev": 0.938, "kelly_fraction": 0.042, "suggested_bet": 4.20, "confidence": "HIGH", "moneyness": 0.95, "time_confidence": "MEDIUM", "asymmetry_edge": 0, "reasons": [ "Strong signal: 62% prob, +93.8% EV" ], "bankroll": 100.0 } ] } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `bucket` | string | Market outcome bucket (e.g., "80-99"). | | `token_id` | string | Polymarket CLOB token ID for trade execution. | | `action` | string | `BUY`, `HOLD`, or `SKIP`. | | `model_prob` | number | Model's calculated win probability (0-1). | | `market_price` | number | Current market price. | | `edge` | number | `model_prob - market_price`. Positive = undervalued. | | `ev` | number | Expected value per $1 bet. | | `kelly_fraction` | number | Optimal bet fraction per Kelly Criterion. | | `suggested_bet` | number | Dollar amount based on Kelly + your bankroll. | | `confidence` | string | `HIGH`, `MEDIUM`, or `LOW` based on multiple factors. | | `moneyness` | number | How deep p50 falls into bucket (0=edge, 1=center). | | `time_confidence` | string | `HIGH` (<24h), `MEDIUM` (24-48h), `LOW` (>72h). | | `asymmetry_edge` | number | XTracker - UI counter. Positive = UI lagging. | | `reasons` | array | Human-readable explanations for the signal. | ### Portfolio Analysis `GET /portfolio/cruz` **Pro Only**. Fetches your open Cruz tweet market positions directly from Polymarket, then overlays our model predictions to tell you where each position stands. **Query Parameters:** | Parameter | Required | Description | |-----------|----------|-------------| | `wallet` | Yes | Your Ethereum wallet address (e.g. `0xabc...123`) | **Sample Response:** ```json { "timestamp": 1774250948000, "data": [ { "wallet": "0xabc...123", "event": { "id": 262360, "title": "Ted Cruz # posts March 17 - March 24, 2026?", "end_ts": 1774569600000 }, "prediction": { "p5": 75, "p50": 89, "p95": 105, "real_counter": 67, "seconds_remaining": 115200, "velocity_counted_1h": 2.1 }, "positions": [ { "event_id": "262360", "bucket": "80-99", "tokens": 50.0, "avg_price": 0.30, "cost_basis": 15.00, "current_price": 0.32, "current_value": 16.00, "pnl": 1.00, "pnl_percent": 6.67, "analysis": { "win_probability": 0.62, "market_implied": 0.32, "edge": 0.30, "edge_percent": 93.75, "signal": "STRONG_BUY", "recommendation": "STRONG_HOLD" } } ], "portfolio": { "total_positions": 1, "total_cost": 15.00, "current_value": 16.00, "total_pnl": 1.00, "total_pnl_percent": 6.67 } } ] } ``` #### How It Works The endpoint has three steps: 1. **Fetches your open positions** from the Polymarket API using your wallet address 2. **Filters to active Cruz tweet markets** — positions in other market types are excluded 3. **Overlays model predictions** for each bucket you hold, computing edge and generating a signal If no active Cruz events are running, `positions` will be empty and a `message` field explains why. #### Field Descriptions — prediction | Field | Type | Description | |-------|------|-------------| | `p5` / `p50` / `p95` | number | Monte Carlo forecast percentiles for final tweet count. | | `real_counter` | number | Current real tweet count at time of prediction. | | `seconds_remaining` | number | Seconds until the event closes. | | `velocity_counted_1h` | number | Average counted tweets per hour over the last hour. Useful for projecting how much more is likely before close. | #### Field Descriptions — positions | Field | Type | Description | |-------|------|-------------| | `bucket` | string | The Polymarket outcome bucket you hold (e.g. `"80-99"`). | | `tokens` | number | Number of shares/tokens you hold. | | `avg_price` | number | Your average purchase price per token. | | `cost_basis` | number | Total amount paid for this position. | | `current_price` | number | Current market price per token. | | `current_value` | number | Current mark-to-market value. | | `pnl` | number | Unrealised profit/loss in USDC. | | `pnl_percent` | number | Unrealised PnL as a percentage. | #### Field Descriptions — analysis | Field | Type | Description | |-------|------|-------------| | `win_probability` | number | Model's estimated probability this bucket wins (0–1). | | `market_implied` | number | Current market price — the crowd's implied probability. | | `edge` | number | `win_probability − market_implied`. Positive = model sees more value than the market. | | `edge_percent` | number | Edge expressed as a percentage of the market price. | | `signal` | string | See signal table below. | | `recommendation` | string | See recommendation table below. | #### Signal Values The `signal` field is based on `edge_percent`: | Signal | Condition | Meaning | |--------|-----------|---------| | `STRONG_BUY` | `edge_percent > 30%` | Model sees strong undervaluation — consider adding | | `BUY` | `edge_percent > 10%` | Clear positive edge exists | | `HOLD` | `edge_percent > 0%` | Slight edge — worth keeping | | `AVOID` | `edge_percent > -10%` | Near fair value, slightly unfavourable | | `SELL` | `edge_percent ≤ -10%` | Model sees meaningful overvaluation — consider exiting | #### Recommendation Values The `recommendation` field is based on raw `edge` (not percentage): | Recommendation | Condition | Meaning | |----------------|-----------|---------| | `STRONG_HOLD` | `edge > 0.20` | High absolute edge — hold firmly | | `HOLD` | `edge > 0.05` | Positive edge — no reason to exit | | `MONITOR` | `edge > -0.05` | Near fair value — watch closely | | `CONSIDER_SELLING` | `edge ≤ -0.05` | Model favours exiting this position | :::tip `signal` and `recommendation` use different scales. `signal` is more sensitive (percentage-based) and useful for deciding whether to *add*. `recommendation` uses absolute edge and is better for deciding whether to *exit*. ::: #### Error Responses | Status | Condition | |--------|-----------| | `400` | Wallet address is not a valid Ethereum address (`0x` + 40 hex chars) | | `401` | Missing or invalid Data API key | | `503` | Could not reach the Polymarket API to fetch positions | ### Raw Tweet Stream `GET /meta/cruz/tweets` **Public** (Masked) / **Pro** (Full). - **Public**: Fixed at the latest **15 tweets**. `is_counted` is null. - **Pro**: Custom pagination using `limit` (max 100) and `offset`. `is_counted` (`true`/`false`) reveals which tweets count toward resolution. **Query Parameters (Pro Only):** - `limit`: Number of tweets to return (max 100). - `offset`: Number of tweets to skip. **Sample Response:** ```json { "timestamp": 1774250948000, "data": [ { "tweet_id": "1771234567890123456", "text": "Great meeting with constituents today...", "created_ts": 1774234718000, "is_reply": false, "is_quote": false, "is_retweet": false, "is_counted": true } ], "limit": 15, "offset": 0 } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `tweet_id` | string | Twitter status ID. | | `text` | string | Tweet content. | | `is_counted` | boolean\|null | **Pro Only**. Whether tweet counts for resolution. Null for public users. | | `is_reply` / `is_quote` / `is_retweet` | boolean | Tweet type flags. | | `limit` / `offset` | number | Pagination values used for the request. | ## Model Characteristics The Cruz prediction model uses the same Monte Carlo simulation approach as the Elon model, but with Cruz-specific parameters: - **Sleep Probability**: ~9.2% (calculated from Cruz's actual tweet gaps) - **Rolling Window**: 14-day lookback for velocity estimation - **Bias Correction**: Uses Cruz-specific historical event data (when sufficient data available) - **Independence**: Completely separate from Elon model - no cross-contamination :::note Cruz markets have less historical data than Elon markets. Model confidence will improve as more events complete and historical patterns emerge. ::: --- FILE: docs/api/crypto.md --- --- title: Crypto Price Markets description: Real-time price tracking for 15-minute prediction markets. --- Polystrike tracks high-frequency crypto price markets on Polymarket, ensuring you have the latest price data to capture volatility. ## Endpoints ### Market Metadata `GET /meta/crypto` > **Note**: This endpoint is currently in **Active Development**. It currently returns an empty list `[]` as we finalize the 15-minute price resolution engine. The schema below represents the **planned** response structure. Returns status and pricing for active 15-minute crypto outcome markets. **Planned Response Schema:** ```json { "timestamp": 1770789357226, "data": [ { "event_id": 12345, "event_title": "BTC price at 19:15 UTC?", "symbol": "BTC", "polymarket_price": 97500.00, "chainlink_price": 97495.20 } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `event_id` | number | Unique ID of the Polymarket event. | | `event_title` | string | Title containing the strike time and condition. | | `symbol` | string | Crypto asset symbol (e.g., `BTC`, `ETH`). | | `polymarket_price` | number | The strike price defined in the market title. | | `chainlink_price` | number | The current reference price from the Chainlink oracle (or null if unavailable). | ## Coming Soon: Phase 2 Integration We are currently optimizing our historical data feeds for Phase 2, which will include: - **Historical Volatility Index**: Customized for 15-minute windows. - **Settlement Predictors**: Analyzing order book depth and whale activity near market close. --- FILE: docs/api/elon.md --- --- title: Elon Musk Tweet Markets description: Documentation for Polystrike's core tweet-tracking data feed. --- Polystrike provides the most accurate and low-latency tracking for Polymarket's Elon Musk tweet count markets: `@elonmusk` is polled every second, and a new post is in the count a median of 11.5 seconds after it is posted (measured on production 2026-07-29; p90 12.6–15.1s, p99 28.2s). ## Endpoints ### Metadata Overview `GET /meta/elon` **Public** (no key required, rate-limited to 100 req/hr since 2026-07-23). Returns current counters and lag deltas for all active Elon events. **Sample Response:** ```json { "timestamp": 1771246725679, "data": [ { "event_id": 206602, "event_title": "Elon Musk # tweets February 14 - February 16, 2026?", "start_ts": 1771088400000, "end_ts": 1771261200000, "polymarket_xtracker_counter": 65, "real_counter": 68, "polymarket_ui_counter": 65, "settlement_delta": 3, "display_delta": 3, "internal_delta": 0 } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `event_id` | number | Unique ID of the Polymarket event. | | `event_title` | string | Human-readable event title from Polymarket. | | `image` | string | Event image URL from Polymarket. | | `start_ts` / `end_ts` | number | Event window start/end times (UTC milliseconds). | | `polymarket_xtracker_counter` | number | Settlement oracle count. This is what Polymarket pays out on. | | `real_counter` | number | Polystrike's own count, advanced as posts land (measured p50 11.5s from post to count). Faster than the oracle; includes deleted tweet captures. | | `polymarket_ui_counter` | number | Count currently displayed on the Polymarket trading UI. | | `settlement_delta` | number | `real_counter − xtracker`. Positive = we're ahead of the oracle. | | `display_delta` | number | `real_counter − ui_counter`. Positive = UI is showing a stale number. | | `internal_delta` | number | `ui_counter − xtracker`. Positive = UI is ahead of the oracle. | ### Predictive Models `GET /prediction/elon` **Public** (Limited) / **Pro** (Full). Tier split gated 2026-07-23. - **Public**: Counters and deltas, `seconds_remaining`, and per-bucket `market_price`. - **Pro**: Forecasts (p5/p50/p95), `model_prob`, `edge`, `signal`, `sleep_probability`, and the `velocity_counted_1h` / `velocity_all_1h` projection inputs. A free consumer cannot reconstruct the projection. **Sample Response (Pro):** ```json { "timestamp": 1771246734873, "data": [ { "event_id": 206602, "seconds_remaining": 14528, "sleep_probability": 0.016, "velocity_counted_1h": 1.5, "velocity_all_1h": 3.0, "forecast": { "p5": 68, "p50": 68, "p95": 69 }, "markets": [ { "title": "65-89", "model_prob": 1.0, "market_price": 0.945, "edge": 0.055, "signal": "SLIGHT_BUY" } ] } ] } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `forecast.p5/p50/p95` | number | **Pro Only**. Monte Carlo forecast percentiles. | | `sleep_probability` | number | **Pro Only** (gated 2026-07-23). Probability Elon is currently sleeping. | | `velocity_counted_1h` / `velocity_all_1h` | number | **Pro Only** (gated 2026-07-23). Counted / all tweets per hour over the last hour — the model's projection inputs. | | `markets.model_prob` | number | **Pro Only**. Our calculated win probability. | | `markets.market_price` | number | Current "Yes" price on Polymarket. Available on the free tier. | | `markets.edge` | number | **Pro Only**. `model_prob - market_price`. | | `markets.signal` | string | **Pro Only**. `STRONG_BUY`, `BUY`, `HOLD`, `SELL`. | ### EV-Based Signals `GET /signals/elon` **Pro Only**. Returns trading signals scored for Expected Value (EV), with Kelly Criterion bet sizing. These are model estimates, not guaranteed profits. **Query Parameters:** | Parameter | Required | Description | |-----------|----------|-------------| | `bankroll` | No | Your bankroll in USD (1-1,000,000). Sizes `suggested_bet` via Kelly criterion. If omitted, a server default is used. | ``` GET /api/v1/signals/elon?bankroll=100 ``` **Sample Response:** ```json { "timestamp": 1771246739535, "data": [ { "event_id": 206602, "signals": [ { "bucket": "65-89", "action": "BUY", "model_prob": 1.0, "market_price": 0.945, "edge": 0.055, "ev": 0.058, "kelly_fraction": 0.058, "suggested_bet": 5.80, "confidence": "HIGH", "moneyness": 0.5, "time_confidence": "HIGH", "asymmetry_edge": 0, "reasons": [ "Strong signal: 100% prob, +5.8% EV" ], "bankroll": 100.0 } ] } ] } ``` ### Portfolio Analysis `GET /portfolio/elon` **Pro Only**. Fetches your open Elon tweet market positions directly from Polymarket, then overlays our model predictions to tell you where each position stands. **Query Parameters:** | Parameter | Required | Description | |-----------|----------|-------------| | `wallet` | Yes | Your Ethereum wallet address (e.g. `0xabc...123`) | **Sample Response:** ```json { "timestamp": 1771246750000, "data": [ { "wallet": "0xabc...123", "event": { "id": 206602, "title": "Elon Musk # tweets February 14 - February 16, 2026?", "end_ts": 1771261200000 }, "prediction": { "p5": 68, "p50": 72, "p95": 78, "real_counter": 68, "seconds_remaining": 14528, "velocity_counted_1h": 4.2 }, "positions": [ { "event_id": "206602", "bucket": "65-89", "tokens": 50.0, "avg_price": 0.82, "cost_basis": 41.00, "current_price": 0.945, "current_value": 47.25, "pnl": 6.25, "pnl_percent": 15.24, "analysis": { "win_probability": 1.0, "market_implied": 0.945, "edge": 0.055, "edge_percent": 5.82, "signal": "BUY", "recommendation": "HOLD" } } ], "portfolio": { "total_positions": 1, "total_cost": 41.00, "current_value": 47.25, "total_pnl": 6.25, "total_pnl_percent": 15.24 } } ] } ``` #### How It Works The endpoint has three steps: 1. **Fetches your open positions** from the Polymarket API using your wallet address 2. **Filters to active Elon tweet markets** — positions in other market types are excluded 3. **Overlays model predictions** for each bucket you hold, computing edge and generating a signal If no active Elon events are running, `positions` will be empty and a `message` field explains why. #### Field Descriptions — prediction | Field | Type | Description | |-------|------|-------------| | `p5` / `p50` / `p95` | number | Monte Carlo forecast percentiles for final tweet count. | | `real_counter` | number | Current real tweet count at time of prediction. | | `seconds_remaining` | number | Seconds until the event closes. | | `velocity_counted_1h` | number | Average counted tweets per hour over the last hour. Useful for projecting how much more is likely before close. | #### Field Descriptions — positions | Field | Type | Description | |-------|------|-------------| | `bucket` | string | The Polymarket outcome bucket you hold (e.g. `"65-89"`). | | `tokens` | number | Number of shares/tokens you hold. | | `avg_price` | number | Your average purchase price per token. | | `cost_basis` | number | Total amount paid for this position. | | `current_price` | number | Current market price per token. | | `current_value` | number | Current mark-to-market value. | | `pnl` | number | Unrealised profit/loss in USDC. | | `pnl_percent` | number | Unrealised PnL as a percentage. | #### Field Descriptions — analysis | Field | Type | Description | |-------|------|-------------| | `win_probability` | number | Model's estimated probability this bucket wins (0–1). | | `market_implied` | number | Current market price — the crowd's implied probability. | | `edge` | number | `win_probability − market_implied`. Positive = model sees more value than the market. | | `edge_percent` | number | Edge expressed as a percentage of the market price. | | `signal` | string | See signal table below. | | `recommendation` | string | See recommendation table below. | #### Signal Values The `signal` field is based on `edge_percent`: | Signal | Condition | Meaning | |--------|-----------|---------| | `STRONG_BUY` | `edge_percent > 30%` | Model sees strong undervaluation — consider adding | | `BUY` | `edge_percent > 10%` | Clear positive edge exists | | `HOLD` | `edge_percent > 0%` | Slight edge — worth keeping | | `AVOID` | `edge_percent > -10%` | Near fair value, slightly unfavourable | | `SELL` | `edge_percent ≤ -10%` | Model sees meaningful overvaluation — consider exiting | #### Recommendation Values The `recommendation` field is based on raw `edge` (not percentage): | Recommendation | Condition | Meaning | |----------------|-----------|---------| | `STRONG_HOLD` | `edge > 0.20` | High absolute edge — hold firmly | | `HOLD` | `edge > 0.05` | Positive edge — no reason to exit | | `MONITOR` | `edge > -0.05` | Near fair value — watch closely | | `CONSIDER_SELLING` | `edge ≤ -0.05` | Model favours exiting this position | :::tip `signal` and `recommendation` use different scales. `signal` is more sensitive (percentage-based) and useful for deciding whether to *add*. `recommendation` uses absolute edge and is better for deciding whether to *exit*. ::: #### Error Responses | Status | Condition | |--------|-----------| | `400` | Wallet address is not a valid Ethereum address (`0x` + 40 hex chars) | | `401` | Missing or invalid Data API key | | `503` | Could not reach the Polymarket API to fetch positions | ### Raw Tweet Stream `GET /meta/elon/tweets` **Public** (Masked) / **Pro** (Full). - **Public**: Fixed at the latest **15 tweets**. `is_counted` is null. - **Pro**: Custom pagination using `limit` (max 100) and `offset`. `is_counted` (`true`/`false`) reveals which tweets count toward resolution. **Query Parameters (Pro Only):** - `limit`: Number of tweets to return (max 100). - `offset`: Number of tweets to skip. **Sample Response:** ```json { "timestamp": 1771246730263, "data": [ { "tweet_id": "2023331176019370170", "text": "Yes https://t.co/C7Eo7s...", "created_ts": 1771234718000, "is_reply": false, "is_quote": true, "is_retweet": false, "is_counted": true } ], "limit": 15, "offset": 0 } ``` #### Field Descriptions | Field | Type | Description | |-------|------|-------------| | `tweet_id` | string | Twitter status ID. | | `text` | string | Tweet content. | | `is_counted` | boolean\|null | **Pro Only**. Whether tweet counts for resolution. Null for public users. | | `is_reply` / `is_quote` / `is_retweet` | boolean | Tweet type flags. | | `limit` / `offset` | number | Pagination values used for the request. | --- FILE: docs/api/overview.md --- --- title: API Overview description: How to authenticate and interact with the Polystrike data engine. --- The Polystrike API is designed for low-latency access to prediction market metadata and signals. ## Infrastructure All endpoints are hosted on high-performance bare-metal servers to ensure maximum uptime and minimal response times. **Base URL:** `https://polystrike.xyz/api/v1` ## Data Freshness Measured on production, 2026-07-29. These are observed numbers, not design targets. | Data | Cadence / latency | |------|-------------------| | Tweet detection (post published → counted) | **p50 11.5s**, p90 12.6–15.1s, p99 28.2s, worst observed 631s | | X timeline poll | **1s** for `@elonmusk`, **5s** for other tracked accounts | | Engagement-metric refresh (likes/reposts) | full timeline re-read every **10 min** | | Deletion confirmation | absent from **2 consecutive** re-reads → **~20 min** | | `real_counter` and the deltas | recomputed as each qualifying post lands | | `prediction/*` and `signals/*` model outputs | **60s** inside an event's final 24h, **300s** otherwise | | `market_price` (Polymarket CLOB order book) | **2s** poll loop across tracked tokens; it cycles many tokens, so effective per-token resolution is **~40s** | | XTracker settlement oracle (not ours) | roughly **5 min** | Notes that matter when you build against this: - **X's index is the floor.** X's REST timeline needs ~10.8s at minimum to list a new post, and the latency is quantized. We already poll faster than X publishes, so polling harder does not move the median. - **Engagement metrics lag by one cycle.** Likes and reposts are zero when a post is first seen — it is seconds old. The 10-minute re-read fills in the real values. - **A filtered-stream push path exists but is not serving.** Measured head-to-head over 4 days it detects at p50 6.3s, ~5.2s faster than the poller. Today it runs as a measurement path and does not write the counters these endpoints read. The poller is retained either way: a push stream cannot observe a deletion. - **Latency is not edge.** Our own paper testing measured that when a count boundary breaks, the price collapse completes in roughly 2–3 seconds — upstream of both feeds. We are not winning that race and do not market these figures as if we were. ## Authentication Endpoints are either **Public** (no key needed) or **Data** (requires `X-API-Key` header). - **Public (Anonymous):** Free access to metadata/counters, delayed 30 minutes (`freshness: delayed`). Rate limited to 100 requests/hour. - **Data ($29/mo, $290/yr):** live counters, the WebSocket feed, full post archive, counter and price history, bulk parquet. Rate limited to 10,000 requests/hour. ### Access Methods **Direct HTTP API** (this documentation): ```bash curl -H "X-API-Key: ps_pro_..." https://polystrike.xyz/api/v1/prediction/elon ``` **OpenAPI Specification** (for automated discovery): ```bash curl https://polystrike.xyz/openapi.json ``` The OpenAPI spec provides machine-readable documentation of all endpoints, parameters, authentication schemes, and response types. Use it to: - Generate client libraries in any language - Integrate with AI agents and automated systems - Understand the API structure programmatically **MCP Server** (for Claude Desktop users): Natural language access through the Model Context Protocol. See [MCP Server Setup](/docs/guides/mcp-setup) for configuration. **To upgrade to Data:** pay USDC on Polygon or Base, then submit the tx hash and your email at [polystrike.xyz/#waitlist](https://polystrike.xyz/#waitlist) or `hello@polystrike.xyz`. Keys are issued by hand, usually within a few hours. ## Response Format All responses are standard JSON. Timestamps are **UTC Milliseconds**. ```json { "timestamp": 1770188662000, "data": [ ... ] } ``` ## Rate Limits | Tier | Limit | |---|---| | **Anonymous** | 100 req/hour (by IP) | | **Pro** | 10,000 req/hour (by Key) | ## Feature Comparison by Tier Below is the exact field visibility for each endpoint. ### GET /meta/elon — Public (No Key, Rate Limited) | Field | Anonymous | Pro | |-------|:---------:|:---:| | `event_id` | ✅ | ✅ | | `event_title` | ✅ | ✅ | | `start_ts` | ✅ | ✅ | | `end_ts` | ✅ | ✅ | | `polymarket_xtracker_counter` | ✅ | ✅ | | `real_counter` | ✅ | ✅ | | `polymarket_ui_counter` | ✅ | ✅ | | `settlement_delta` | ✅ | ✅ | | `display_delta` | ✅ | ✅ | | `internal_delta` | ✅ | ✅ | ### GET /meta/elon/tweets — Public (Rate Limited) | Field | Anonymous | Pro | |-------|:---------:|:---:| | `tweet_id` | ✅ | ✅ | | `text` | ✅ | ✅ | | `created_ts` | ✅ | ✅ | | `referenced_text` | ✅ | ✅ | | `referenced_author_id` | ✅ | ✅ | | `is_reply` | ✅ | ✅ | | `is_quote` | ✅ | ✅ | | `is_retweet` | ✅ | ✅ | | **`is_counted`** | **null** | ✅ | ### GET /prediction/elon — Public (Rate Limited) | Field | Anonymous | Pro | |-------|:---------:|:---:| | `event_id` | ✅ | ✅ | | `event_title` | ✅ | ✅ | | `polymarket_xtracker_counter` | ✅ | ✅ | | `polymarket_ui_counter` | ✅ | ✅ | | `real_counter` | ✅ | ✅ | | `settlement_delta` | ✅ | ✅ | | `display_delta` | ✅ | ✅ | | `internal_delta` | ✅ | ✅ | | `seconds_remaining` | ✅ | ✅ | | `markets[].title` | ✅ | ✅ | | `markets[].market_price` | ✅ | ✅ | | **`sleep_probability`** | ❌ | ✅ | | **`velocity_counted_1h`** | ❌ | ✅ | | **`velocity_all_1h`** | ❌ | ✅ | | **`markets[].model_prob`** | ❌ | ✅ | | **`forecast.p5`** | ❌ | ✅ | | **`forecast.p50`** | ❌ | ✅ | | **`forecast.p95`** | ❌ | ✅ | | **`markets[].edge`** | ❌ | ✅ | | **`markets[].signal`** | ❌ | ✅ | > **Changed 2026-07-23**: `sleep_probability` and the `velocity_counted_1h` / `velocity_all_1h` projection inputs moved to Pro (previously free), so a free consumer can no longer reconstruct the model's late-window projection. Free still gets all counters/deltas, `seconds_remaining`, and per-bucket `market_price`. ### GET /signals/elon — Pro Only (401 without key) Optional query parameter: `?bankroll=100` — sizes `suggested_bet` to your bankroll via Kelly criterion. | Field | Anonymous | Pro | |-------|:---------:|:---:| | `event_id` | ❌ 401 | ✅ | | `event_title` | ❌ 401 | ✅ | | `signals[].bucket` | ❌ 401 | ✅ | | `signals[].action` | ❌ 401 | ✅ | | `signals[].model_prob` | ❌ 401 | ✅ | | `signals[].market_price` | ❌ 401 | ✅ | | `signals[].edge` | ❌ 401 | ✅ | | `signals[].ev` | ❌ 401 | ✅ | | `signals[].kelly_fraction` | ❌ 401 | ✅ | | `signals[].suggested_bet` | ❌ 401 | ✅ (sized to `?bankroll` if provided) | | `signals[].confidence` | ❌ 401 | ✅ | | `signals[].moneyness` | ❌ 401 | ✅ | | `signals[].time_confidence` | ❌ 401 | ✅ | | `signals[].asymmetry_edge` | ❌ 401 | ✅ | | `signals[].reasons` | ❌ 401 | ✅ | | `signals[].bankroll` | ❌ 401 | ✅ | ### GET /portfolio/elon?wallet=0x... — Pro Only (401 without key) | Field | Anonymous | Pro | |-------|:---------:|:---:| | `wallet` | ❌ 401 | ✅ | | `event.id` | ❌ 401 | ✅ | | `event.title` | ❌ 401 | ✅ | | `event.end_ts` | ❌ 401 | ✅ | | `prediction.p5` / `p50` / `p95` | ❌ 401 | ✅ | | `prediction.real_counter` | ❌ 401 | ✅ | | `prediction.seconds_remaining` | ❌ 401 | ✅ | | `positions[].event_id` | ❌ 401 | ✅ | | `positions[].bucket` | ❌ 401 | ✅ | | `positions[].tokens` | ❌ 401 | ✅ | | `positions[].avg_price` | ❌ 401 | ✅ | | `positions[].cost_basis` | ❌ 401 | ✅ | | `positions[].current_price` | ❌ 401 | ✅ | | `positions[].current_value` | ❌ 401 | ✅ | | `positions[].pnl` | ❌ 401 | ✅ | | `positions[].pnl_percent` | ❌ 401 | ✅ | | `positions[].analysis.win_probability` | ❌ 401 | ✅ | | `positions[].analysis.market_implied` | ❌ 401 | ✅ | | `positions[].analysis.edge` | ❌ 401 | ✅ | | `positions[].analysis.edge_percent` | ❌ 401 | ✅ | | `positions[].analysis.signal` | ❌ 401 | ✅ | | `positions[].analysis.recommendation` | ❌ 401 | ✅ | | `portfolio.total_positions` | ❌ 401 | ✅ | | `portfolio.total_cost` | ❌ 401 | ✅ | | `portfolio.current_value` | ❌ 401 | ✅ | | `portfolio.total_pnl` | ❌ 401 | ✅ | | `portfolio.total_pnl_percent` | ❌ 401 | ✅ | --- FILE: docs/api/system.md --- --- title: System API description: Operational endpoints for health checks and waitlist management. --- ## Health Check `GET /health` Used by load balancers and monitoring systems to verify API availability. **Sample Response:** ```json { "timestamp": 1770789357608, "status": "ok" } ``` ## Waitlist Registration `POST /waitlist` Register an agent or human user for early access to upcoming features. ### Parameters | Field | Type | Required? | Description | |-------|------|-----------|-------------| | `type` | string | Yes | Must be `agent` or `human`. | | `case` | string | Yes | Description of your intended use case. | | `name` | string | If type=agent | Name of the bot/agent. | | `wallet` | string | If type=agent | Base wallet address for whitelist | | `email` | string | If type=human | Contact email address. | ### Example Request (Agent) ```bash curl -X POST https://polystrike.xyz/api/v1/waitlist \ -H "Content-Type: application/json" \ -d '{ "type": "agent", "name": "ArbBot-V1", "wallet": "0x123...", "case": "High-frequency arbitrage on Elon markets" }' ``` **Response:** ```json { "status": "registered", "position": 42 } ``` --- FILE: docs/guides/concepts.md --- --- title: Core Concepts description: Understand the problem Polystrike solves and the data model behind it. --- Polystrike is an oracle intelligence layer for Polymarket's Elon Musk tweet count markets. This page explains the core problem and how Polystrike keeps you correctly informed about the true count. ## The Problem: Two Counters, Both Wrong Polymarket shows traders two tweet counters: - **XTracker** (the settlement oracle): Updates every ~5 minutes. This is the number that actually determines who wins and loses. - **UI Counter**: Displayed on the Polymarket trading interface. Frequently freezes or lags behind XTracker. Most retail traders price their positions based on the UI counter. But the UI counter is often severely wrong — sometimes lagging by 5-10+ tweets. That lag is exactly what Polystrike surfaces — so you can see the true count instead of the stale display. (Note: the order book itself usually already tracks the real count, so a UI gap is monitoring information, not a free edge — see [Trading Strategies](/docs/guides/strategies).) ## The Solution: A Third Counter Polystrike maintains its own counter — the **real counter** — by querying Twitter every second for `@elonmusk` (every 5 seconds for other tracked accounts) and classifying each tweet against the exact settlement rules. | Counter | Source | Update Frequency | Settlement Authority | |---------|--------|-------------------|---------------------| | **UI Counter** | Polymarket frontend | Irregular, often frozen | None | | **XTracker** | Settlement oracle | Every ~5 minutes | Yes (determines payouts) | | **Real Counter** | Polystrike | As posts land — measured p50 11.5s from post to count | None (but most accurate) | Measured on production 2026-07-29: a new post is in the real counter a median of **11.5 seconds** after it is posted (p90 12.6–15.1s, p99 28.2s, worst observed 631s). The floor is X's own REST timeline index, which needs about 10.8 seconds at minimum to list a post — we already poll faster than X publishes, so polling harder does not move the median. Against a ~5-minute oracle cycle that means the real counter is usually ahead, and it also catches events the oracle never sees (deleted tweets). Being earlier is not the same as being profitable: the order book generally prices the real count, so treat this as accuracy, not edge. ## Deleted Tweets Elon Musk deletes tweets. If a tweet existed when XTracker last scraped, it counts toward settlement — even if it's deleted by the time you check Twitter manually. Polystrike captures tweets a median of 11.5 seconds after posting. If a tweet is later deleted we flag it with `is_deleted: true` **and drop it from the count** (`is_counted` goes to `false`), because the settlement oracle also removes deleted posts — a post that no longer exists must not be counted against a market that will not count it. Deletion runs on a slower clock than capture: a full timeline re-read every 10 minutes, which is also what refreshes engagement metrics, and a post must be absent from **two consecutive** re-reads before we believe it — so a confirmed deletion takes roughly 20 minutes. That is deliberate: X's timeline transiently omits posts that were never deleted, so a deletion needs to be right rather than fast. If the post reappears, it un-deletes and regains its count automatically. This means: - Our real counter may diverge from what you see on Twitter right now, in both directions - Right after a deletion our count is briefly **high** — we have not confirmed the removal yet, while the oracle may already have dropped it - A tweet we still show as counted is one we have not yet seen vanish, not a claim that it survived ## The is_counted Classification Not every Elon tweet counts toward Polymarket settlement. The rules are specific: | Tweet Type | Counts? | |-----------|---------| | Main feed post | Yes | | Quote post | Yes | | Repost (retweet) | Yes | | Main-feed reply | Yes | | Regular reply | No | | Community repost | No | XTracker doesn't expose this classification. Polystrike classifies every tweet in real time and exposes the `is_counted` field (Pro tier only). ## The Three Deltas Polystrike tracks three independent lag signals. Each measures a different gap between the counters: ### settlement_delta ``` settlement_delta = real_counter - xtracker_counter ``` **What it means**: How far ahead of the settlement oracle we are. A positive value means Polystrike has counted tweets that XTracker hasn't picked up yet — including deleted tweets. ### display_delta ``` display_delta = real_counter - ui_counter ``` **What it means**: How wrong the Polymarket UI is. When this is large, most traders are looking at a stale number and may be mispricing their positions. ### internal_delta ``` internal_delta = ui_counter - xtracker_counter ``` **What it means**: The gap between what Polymarket shows and what will actually settle. Can be positive (UI ahead of oracle) or negative (UI behind oracle). ## Monte Carlo Predictions Polystrike runs 1,000 Monte Carlo simulations per active event to produce bucket probability forecasts: - **p5**: 5th percentile (optimistic low bound) - **p50**: Median expected count - **p95**: 95th percentile (pessimistic high bound) The model is **sleep-aware** — it accounts for Elon's Texas timezone sleep schedule. Tweeting velocity drops to near-zero during sleep hours, which is deterministic, not random. ### Reliability Window - **Final 16 hours**: Most reliable. The model has enough data to project accurately. - **16-36 hours remaining**: Moderate reliability. Use with caution. - **More than 36 hours**: Early predictions carry 15-20% overestimation risk. The model tends to extrapolate current velocity too aggressively. ## Tiers | Feature | Free | Pro ($79/mo) | |---------|------|-------------| | Real-time counters & deltas | Yes | Yes | | Recent tweets (last 15) | Yes | Yes | | `is_counted` classification | Masked (null) | Yes | | Full tweet history + pagination | No | Yes | | Monte Carlo predictions | No | Yes | | Trading signals (EV, Kelly) | No | Yes | | Portfolio analysis | No | Yes | | Rate limit | 100 req/hr | 10,000 req/hr | --- FILE: docs/guides/example.md --- --- title: FAQ description: Frequently asked questions about Polystrike. --- ## Why is the real_counter higher than XTracker? Two reasons: 1. **Speed**: Polystrike queries Twitter every second for `@elonmusk` (every 5 seconds for other tracked accounts) and has a post counted a median of 11.5 seconds after it goes up. XTracker updates every ~5 minutes. So at any given moment, we've likely caught new tweets that XTracker hasn't processed yet. 2. **Deleted tweets**: If Elon posts and then deletes a tweet, our system captures it a median of 11.5 seconds after posting. If XTracker's next update runs *after* the deletion, it never sees that tweet — but it still counts if it existed during the window. The `settlement_delta` field tells you exactly how large this gap is. --- ## Does is_counted track the same rules as Polymarket? Yes. The classification is based on the public settlement rules: - Main feed posts → **counted** - Quote posts → **counted** - Reposts (retweets) → **counted** - Main-feed replies → **counted** - Regular replies → **not counted** - Community reposts → **not counted** `is_counted` is a Pro-only field. Free tier returns `null`. --- ## Why does display_delta go negative sometimes? The Polymarket UI sometimes *over-counts* — it shows a number higher than the real count. This can happen when the UI picks up a tweet that later gets deleted or that our system doesn't classify as counted. A negative `display_delta` means the UI is ahead of our real count. This is unusual but not impossible. --- ## When are predictions most reliable? The Monte Carlo model is most reliable in the **final 16 hours** of an event. At that point, the count trajectory and velocity are well established. Early in an event (more than 36 hours remaining), predictions tend to overestimate by 15-20% because the model extrapolates current velocity too aggressively before sleep patterns emerge. --- ## What does sleep_probability mean? Elon Musk is based in Texas (CT timezone). His sleep schedule is fairly consistent — there are specific overnight hours when his tweet velocity drops to near-zero. The `sleep_probability` field gives the current probability that he's asleep right now, based on historical patterns. When this is high, the velocity model reduces its projection accordingly. --- ## How do I get a Data API key? Pay $29/month (or $290/year) in USDC on Polygon or Base, then submit the tx hash and your email at [polystrike.xyz/#waitlist](https://polystrike.xyz/#waitlist) or `hello@polystrike.xyz`. Data includes live counters (the free tier is delayed 30 minutes), the WebSocket feed, the full post archive, counter and price history, and bulk parquet. --- ## What is x402 authentication? x402 is a micropayment protocol for AI agents. Instead of a monthly subscription, agents can pay per-request using an `x402` header. This is designed for autonomous agents that need to call the API without a pre-arranged subscription. Contact us for details. --- FILE: docs/guides/mcp-setup.md --- --- title: MCP Server Setup description: Connect Claude Desktop to Polystrike using the Model Context Protocol. No API key needed for the free tier. --- The Polystrike MCP server enables Claude Desktop to access tweet data, market metadata, and predictions through natural language. No local installation required — the server runs on our infrastructure. **The free tier needs no signup and no API key**: paste one config block and you're connected. An API key is only needed for the PRO tools (trading signals and portfolio analysis). ## What is MCP? Model Context Protocol (MCP) is an open standard that lets AI assistants like Claude connect to external data sources and tools. Instead of copying/pasting API responses, Claude can query Polystrike directly and reason about the data in real-time. **Benefits:** - Natural language queries: "What are the current Elon market predictions?" - Automatic data refresh: Claude always sees live data - Portfolio analysis: "Analyze my positions at 0x..." (PRO) - Trading signals: "Show me BUY signals with $100 bankroll" (PRO) ## Prerequisites - **Claude Desktop** (macOS, Windows, or Linux) - **Node.js** (for `npx`, which runs the `mcp-remote` bridge) That's it — no account and no API key for the free tier. ## Setup ### 1. Configure Claude Desktop Open your Claude Desktop configuration file: **macOS:** ```bash ~/Library/Application Support/Claude/claude_desktop_config.json ``` **Windows:** ```bash %APPDATA%\Claude\claude_desktop_config.json ``` **Linux:** ```bash ~/.config/Claude/claude_desktop_config.json ``` Add this configuration: ```json { "mcpServers": { "polystrike": { "command": "npx", "args": [ "-y", "mcp-remote", "https://polystrike.xyz/mcp" ] } } } ``` No API key, no placeholders to replace. :::note The `mcp-remote` package bridges Claude Desktop's stdio transport to our streamable-HTTP server at `https://polystrike.xyz/mcp`. It's automatically downloaded by `npx` — no manual installation needed. (The older `https://polystrike.xyz/mcp/sse` endpoint still works, but new setups should use `/mcp`.) ::: ### 2. Restart Claude Desktop **Important:** Completely quit Claude Desktop (Cmd+Q on macOS, not just close the window) and restart to load the configuration. ### 3. Test It Try these prompts in Claude: ``` Check Polystrike API health ``` ``` What are the current predictions for active Elon markets? ``` ``` Show me recent Elon tweets ``` If everything is working, Claude will respond with live data from Polystrike. ## Optional: PRO API Key Three tools — `get_trading_signals`, `analyze_portfolio`, and `get_rebalancing_recommendations` — require a PRO API key. If you only want market data and predictions, skip this section entirely. Get a key at [polystrike.xyz](https://polystrike.xyz), then add the `x-api-key` header to your config: ```json { "mcpServers": { "polystrike": { "command": "npx", "args": [ "-y", "mcp-remote", "https://polystrike.xyz/mcp", "--header", "x-api-key:${POLYSTRIKE_API_KEY}" ], "env": { "POLYSTRIKE_API_KEY": "your_api_key_here" } } } } ``` Replace `your_api_key_here` with your actual API key, then restart Claude Desktop again. A PRO key also raises your rate limit (see [Rate Limits](#rate-limits)). Example PRO prompt: ``` Get trading signals for Elon markets with $100 bankroll ``` ## Available Tools ### FREE Tier (No API Key Required) - **get_market_metadata** - Active Elon tweet markets - **get_crypto_metadata** - Crypto market information - **get_recent_tweets** - Recent tweets (15 limit) - **get_predictions** - Market predictions (limited) - **check_health** - API health status - **join_waitlist** - Registration ### PRO Tier (API Key Required) - **get_trading_signals** - EV-based signals with Kelly sizing - **analyze_portfolio** - Wallet position analysis - **get_rebalancing_recommendations** - Position rebalancing ## Troubleshooting ### Tools Not Appearing 1. Check Claude Desktop logs for errors 2. Verify JSON syntax in config file (use [jsonlint.com](https://jsonlint.com)) 3. Restart Claude Desktop completely (Cmd+Q, not just close window) ### Connection Errors Test server connectivity: ```bash curl https://polystrike.xyz/mcp/health ``` Expected response: ```json {"status":"ok","version":"1.0.0","server":"polystrike"} ``` If this fails, the server may be down. Check [status.polystrike.xyz](https://status.polystrike.xyz) or contact support. ### Authentication Errors (PRO tools only) The free-tier tools never require authentication — if you see auth errors on `get_trading_signals`, `analyze_portfolio`, or `get_rebalancing_recommendations`: - Verify your API key is correct (check for extra spaces) - Check API key tier (FREE vs PRO) - Ensure key is not expired - Try regenerating your key at [polystrike.xyz](https://polystrike.xyz) ### Tool Calls Timeout or Fail If Claude can see the tools but calls fail: 1. Check your internet connection 2. Verify the MCP server is responding: ```bash curl -X POST https://polystrike.xyz/mcp ``` Should return: `"Invalid Content-Type header"` (not 404) 3. Check Claude Desktop logs for specific error messages ## Rate Limits - **FREE Tier**: 100 requests/hour - **PRO Tier**: 10,000 requests/hour Rate limits are enforced server-side. If you hit the limit, Claude will receive an error message and you'll need to wait or upgrade. ## Why MCP vs Direct API? | Approach | Setup | Updates | Natural Language | |----------|-------|---------|------------------| | **MCP Server** | 2 lines config | Automatic | Yes | | **Direct API** | Manual curl/code | Manual | No | MCP is the recommended approach for Claude Desktop users. It's simpler, automatically updated, and enables natural language queries. ## Support - **Documentation**: [docs.polystrike.xyz](https://docs.polystrike.xyz) - **Issues**: [github.com/dizpers/polystrike/issues](https://github.com/dizpers/polystrike/issues) - **Contact**: `hello@polystrike.xyz` --- FILE: docs/guides/quickstart.md --- --- title: Quick Start description: Get your first Polystrike response in under a minute. --- No sign-up required. The core endpoint is public and free. ## 1. Get the live counters ```bash curl https://polystrike.xyz/api/v1/meta/elon ``` You'll get back something like this: ```json { "timestamp": 1771246725679, "data": [ { "event_id": 206602, "event_title": "Elon Musk # tweets February 14 - February 16, 2026?", "start_ts": 1771088400000, "end_ts": 1771261200000, "polymarket_xtracker_counter": 65, "real_counter": 68, "polymarket_ui_counter": 65, "settlement_delta": 3, "display_delta": 3, "internal_delta": 0 } ] } ``` **What you're seeing**: The real count is 68 but the settlement oracle (XTracker) only shows 65. That `settlement_delta` of 3 means Polystrike has found 3 tweets the oracle hasn't counted yet. The UI is also showing 65 — so traders on Polymarket are looking at a number that's 3 behind reality. The three delta fields are your monitoring signals: | Field | Formula | What a positive value means | |-------|---------|----------------------------| | `settlement_delta` | `real − xtracker` | Polystrike is ahead of the oracle | | `display_delta` | `real − ui` | The UI is showing a stale number | | `internal_delta` | `ui − xtracker` | The UI is ahead of or behind the oracle | ## 2. See the tweet feed ```bash curl https://polystrike.xyz/api/v1/meta/elon/tweets ``` Returns the 15 most recent tweets (free tier). Each tweet includes type flags (`is_reply`, `is_quote`, `is_retweet`) and a `is_counted` field that tells you whether it counts toward settlement. :::note `is_counted` is `null` on the free tier — it's only populated for Pro subscribers. This is the key field for understanding which tweets actually determine the outcome. ::: ## 3. Use with Claude Desktop (Recommended) If you use Claude Desktop, skip the manual API calls and connect via MCP instead: :::tip[Natural Language Access] The [MCP Server Setup](/docs/guides/mcp-setup) lets Claude query Polystrike directly through natural language. Just ask "What are the current Elon market predictions?" and Claude fetches live data automatically. **Setup time:** 2 minutes. **Installation:** Zero (runs on our servers). ::: ## 4. Upgrade to Data Data unlocks live counters (the free tier is delayed 30 minutes), the WebSocket feed, the full post archive, counter and price history, and bulk parquet. **$29/month or $290/year, USDC on Polygon or Base.** Submit the tx hash and your email at [polystrike.xyz/#waitlist](https://polystrike.xyz/#waitlist) or `hello@polystrike.xyz`; keys are issued by hand, usually within a few hours. Once you have a key, pass it as a header: ```bash curl -H "X-API-Key: ps_pro_..." \ https://polystrike.xyz/api/v1/prediction/elon ``` ## 5. For AI agents Fetch the machine-readable API definition: ```bash curl https://polystrike.xyz/SKILL.md ``` This single file contains the full API schema in a format optimized for LLM context injection. Your agent can discover, understand, and call the API autonomously from it. --- FILE: docs/guides/strategies.md --- --- title: Trading Strategies description: How to read Polystrike's three delta signals when monitoring Polymarket Elon tweet markets. --- Polystrike provides three independent lag signals that each measure a different gap between the counters. This guide explains what they tell you — and their limits. :::caution These are monitoring signals, not guaranteed profits. In our own backtesting the UI-vs-oracle divergence was **not by itself tradeable** — the order book prices on the real/oracle count, so acting on a display gap is roughly breakeven. Treat these signals as tools to stay informed and avoid stale-price mistakes, not as a promised edge. Prediction markets involve risk; always size positions appropriately and never risk more than you can afford to lose. ::: ## Strategy 1: Display Delta (stale UI) **Signal**: `display_delta` is large (e.g., > 5) **What's happening**: The Polymarket UI counter is frozen or lagging. Most traders are looking at a stale number. **What it tells you**: If the UI shows 240 tweets but the real count is 248, traders reading the UI may think the 240-259 bucket is safe when the count is closer to busting it. (The order book, though, usually already reflects the real count — so treat this as information, not a guaranteed mispricing.) **How to use it**: 1. Monitor `display_delta` via `GET /meta/elon` 2. When `display_delta > 5`, check which bucket the UI count suggests vs. where the real count is heading 3. If the real count is near a bucket boundary that the UI doesn't reflect, the market is likely mispriced **When it fails**: The UI can catch up suddenly, and other sophisticated traders may already be exploiting the same lag. In our own backtesting of large-divergence events, the order book usually tracked the real count even while the UI display lagged — so verify prices before assuming the market is blind. ## Strategy 2: Settlement Delta (oracle catch-up) **Signal**: `settlement_delta` is positive **What's happening**: Polystrike has counted tweets (including deleted ones) that XTracker hasn't picked up yet. **What it tells you**: The settlement oracle will eventually catch up to the real count. If that catch-up moves the count across a bucket boundary, the affected bucket's price may move — but note the book often prices this in ahead of the oracle, so it is not a guaranteed edge. **How to use it**: 1. Monitor `settlement_delta` via `GET /meta/elon` 2. Calculate where the count will land once XTracker updates 3. If the XTracker update would push the count into a different bucket, trade accordingly before the update **Important caveat**: Deleted tweets create a persistent gap. If `settlement_delta` is driven by deletions (tweets we captured but XTracker never saw), the oracle may never "catch up" for those specific tweets. Check the tweet feed for `is_deleted` flags to distinguish real lag from deletion-driven divergence. ## Strategy 3: Prediction-Based Positioning **Signal**: Monte Carlo predictions show high probability for a specific bucket **What's happening**: The model projects where the final count will land based on current velocity and sleep patterns. **What it tells you**: When the model assigns > 70% probability to a bucket but the Polymarket price for that bucket is only 50-60%, the model sees potential expected value (EV) — a hypothesis to check against the live book, not a guarantee. **How to use it**: 1. Call `GET /prediction/elon` (Pro tier) to get bucket probabilities 2. Compare `model_prob` to `market_price` for each bucket 3. The `edge` field gives you the raw difference: `model_prob - market_price` 4. The `signal` field provides a pre-computed recommendation (STRONG_BUY, BUY, HOLD, SELL) **When to trust the model**: - **Final 16 hours**: Highest reliability. The count trajectory is well-established. - **16-36 hours**: Moderate. Check the `sleep_probability` field — if Elon is likely asleep, the model can project confidently. - **More than 36 hours**: Low reliability. Early predictions overestimate by 15-20%. ## Position Sizing with Kelly Criterion The `/signals/elon` endpoint (Pro tier) provides EV-based signals with Kelly Criterion sizing. Pass `?bankroll=100` to get `suggested_bet` sized to your bankroll: | Field | What it tells you | |-------|-------------------| | `ev` | Expected value of a $1 bet. Positive = profitable in expectation. | | `kelly_fraction` | Optimal fraction of bankroll to bet (Kelly Criterion). | | `suggested_bet` | Dollar amount to bet, calculated as `kelly_fraction * bankroll`. Pass `?bankroll=` to customize. | | `confidence` | HIGH, MEDIUM, or LOW based on time remaining and model certainty. | | `moneyness` | How deep the p50 is inside the bucket. Higher = safer. | :::tip Kelly Criterion gives the mathematically optimal bet size, but most traders use "fractional Kelly" (betting 25-50% of the suggested amount) to reduce variance. ::: ## When NOT to Trade Polystrike signals also help you avoid bad trades: - **`confidence: LOW`**: Not enough data or too much time remaining. Wait. - **`moneyness` near 0**: The p50 is right at a bucket boundary. High risk of the count landing on either side. - **`ev` negative**: The market has already priced in the edge. No trade. - **`signal: SKIP`**: The system explicitly recommends no action. - **p5-p95 spans 3+ buckets**: Too much uncertainty to make a confident bet. --- FILE: docs/index.mdx --- --- title: Polystrike Docs description: Official documentation for the Polystrike API. template: splash hero: tagline: Oracle intelligence layer for Polymarket Elon & Cruz tweet markets. Real count. Deleted tweets. Triple lag signals. Monte Carlo predictions. image: file: ../../assets/houston.webp actions: - text: Get Started link: /docs/guides/quickstart/ icon: right-arrow - text: API Reference link: /docs/api/overview/ icon: external variant: minimal --- import { Card, CardGrid } from '@astrojs/starlight/components'; ## Quick Links [Get your first response](/docs/guides/quickstart) in under a minute. Free, no API key needed. Understand [the problem Polystrike solves](/docs/guides/concepts) — counter lag, deleted tweets, and settlement rules. [Connect Claude Desktop](/docs/guides/mcp-setup) to Polystrike. Natural language queries, live data, zero installation. Full endpoint reference for [tweet counts, predictions, and signals](/docs/api/elon). Full endpoint reference for [tweet counts, predictions, and signals](/docs/api/cruz). Learn to read the [three delta signals](/docs/guides/strategies) that track counter lag. --- FILE: docs/reference/example.md --- --- title: Error Codes description: HTTP error codes returned by the Polystrike API. --- All errors return a JSON body with a `detail` field explaining the issue. ```json { "detail": "Invalid API key" } ``` ## HTTP Status Codes | Code | Meaning | Common Cause | |------|---------|--------------| | `200` | OK | Request succeeded | | `400` | Bad Request | Missing required parameter, invalid wallet address | | `401` | Unauthorized | Missing or invalid `X-API-Key` on a Pro-only endpoint | | `422` | Unprocessable Entity | Parameter validation failed (e.g. `limit` out of range) | | `429` | Too Many Requests | Rate limit exceeded | | `500` | Internal Server Error | Upstream data source unavailable | | `503` | Service Unavailable | Server overloaded or in maintenance | --- ## Rate Limit Errors (429) When you exceed the rate limit, the response body will include: ```json { "detail": "Rate limit exceeded. Try again in 60 seconds." } ``` | Tier | Limit | |------|-------| | Free (Anonymous) | 100 requests / hour (per IP) | | Pro | 10,000 requests / hour (per API key) | Rate limits reset on a rolling 1-hour window. --- ## Authentication Errors (401) Endpoints that require a Pro key return `401` if: - The `X-API-Key` header is missing - The key is invalid or expired - The key doesn't have Pro tier access **Affected endpoints**: `/prediction/elon`, `/signals/elon`, `/portfolio/elon` --- ## Validation Errors (422) The `/meta/elon/tweets` endpoint accepts `limit` and `offset` query parameters for Pro users. Invalid values produce a `422`: ```bash # This will 422 — limit max is 100 curl -H "X-API-Key: ps_pro_..." \ "https://polystrike.xyz/api/v1/meta/elon/tweets?limit=500" ``` Valid ranges: - `limit`: 1–100 (Pro only; free tier is fixed at 15) - `offset`: 0 or any non-negative integer --- ## Empty Data (200) A `200` response with `"data": []` means there are no active Elon tweet markets right now. This is normal between events. Check back when a new market opens on Polymarket.