API Reference

Webhook Payload Reference

Every event type and field your endpoint will receive. Copy the examples below to build and test your integration before connecting it to PolySpy.

Overview

When you configure a webhook URL in your PolySpy account or on an individual strategy, PolySpy sends an HTTP POST request to your endpoint for every trading event. This lets you build custom bots, log trades to a database, trigger notifications in Slack or Discord, or route signals to your own execution engine — all without sharing your Polymarket credentials with PolySpy.

Webhooks fire in both paper mode and live mode. Check the execution.is_paper field to distinguish between them.

Delivery Details

MethodPOST
Content-Typeapplication/json
User-AgentPolySpy/1.0
Timeout10 seconds per attempt
Retries3 attempts with exponential backoff (2s, 4s)
Success codesAny 2xx status
DeliveryFire-and-forget — does not block strategy execution
DedupSame wallet + market within 1 hour is deduplicated

Signature Verification

If you configure a webhook secret, every request includes an X-PolySpy-Signature header containing an HMAC-SHA256 digest of the raw request body, prefixed with sha256=.

Header format
X-PolySpy-Signature: sha256=<hex-digest>
Example verification in Python
import hmac, hashlib

def verify_signature(body: bytes, secret: str, header: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)
Example verification in Node.js
const crypto = require("crypto");

function verifySignature(body, secret, header) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(body).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(header)
  );
}

Event Types

Every payload contains a top-level event, timestamp, and strategy_id field. The remaining fields depend on the event type.

EventDescription
signal.entryA new trading signal was detected and (optionally) executed.
signal.leaderboard_entryA top-ranked leaderboard trader entered a position.
signal.exitThe tracked wallet exited a position, triggering a sell.
execution.stop_lossA stop-loss was triggered and the position was closed.
execution.take_profitA take-profit was triggered and the position was closed.
execution.near_resolutionA market is approaching resolution and the position was closed.
execution.resolutionA market has resolved and the position was settled.
portfolio.summaryHourly summary of open positions and daily P&L.

Payload Examples

Click the copy button on any example to use it for testing your endpoint.

signal.entry

Fired when a fresh wallet, leaderboard, or watchlist signal is detected. Includes the triggering trade, wallet info, market details, and execution result (if a trade was placed).

{
  "event": "signal.entry",
  "timestamp": "2025-04-08T14:32:01.812345+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "source": "fresh_wallet",
  "trade": {
    "condition_id": "0xabc123def456...",
    "asset": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
    "proxy_wallet": "0x1234567890abcdef1234567890abcdef12345678",
    "side": "BUY",
    "outcome": "Yes",
    "size": 500,
    "price": 0.62,
    "size_usd": 310,
    "timestamp": 1712587921,
    "title": "Will BTC hit $100k by July 2025?",
    "event_slug": "will-btc-hit-100k-by-july-2025",
    "transaction_hash": "0xdeadbeef..."
  },
  "wallet": {
    "address": "0x1234567890abcdef1234567890abcdef12345678",
    "first_tx_timestamp": 1712584321,
    "age_hours": 1,
    "is_fresh": true
  },
  "market": {
    "token_id": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
    "condition_id": "0xabc123def456...",
    "question": "Will BTC hit $100k by July 2025?",
    "slug": "will-btc-hit-100k-by-july-2025",
    "event_slug": "will-btc-hit-100k-by-july-2025"
  },
  "execution": {
    "timestamp": 1712587922,
    "token_id": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
    "condition_id": "0xabc123def456...",
    "market_question": "Will BTC hit $100k by July 2025?",
    "side": "BUY",
    "size_usd": 25,
    "fill_price": 0.63,
    "is_paper": false,
    "strategy": "Fresh Whale Copy",
    "order_id": "0xorder123...",
    "status": "filled",
    "pnl": null,
    "error_message": null,
    "source": "fresh_wallet",
    "tracked_wallet": "0x1234567890abcdef1234567890abcdef12345678",
    "event_slug": "will-btc-hit-100k-by-july-2025"
  }
}

signal.leaderboard_entry

Fired when a top-ranked leaderboard trader enters a position. Includes their ranking, username, and P&L alongside the trade details.

{
  "event": "signal.leaderboard_entry",
  "timestamp": "2025-04-08T14:35:12.654321+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "source": "leaderboard",
  "trade": {
    "condition_id": "0xdef789abc012...",
    "asset": "98765432109876543210987654321098765432109876543210987654321098765432",
    "proxy_wallet": "0xabcdef1234567890abcdef1234567890abcdef12",
    "side": "BUY",
    "outcome": "No",
    "size": 2000,
    "price": 0.35,
    "size_usd": 700,
    "timestamp": 1712588112,
    "title": "Will ETH flip BTC by 2026?",
    "event_slug": "will-eth-flip-btc-by-2026",
    "transaction_hash": "0xcafebabe..."
  },
  "leaderboard_entries": [
    {
      "proxy_wallet": "0xabcdef1234567890abcdef1234567890abcdef12",
      "username": "whalemaster",
      "pnl": 142350.75,
      "rank": 3,
      "time_period": "all_time"
    }
  ],
  "execution": null
}

signal.exit

Fired when the original tracked wallet exits a position, triggering a matching sell on your side.

{
  "event": "signal.exit",
  "timestamp": "2025-04-08T18:45:30.123456+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "trade": {
    "condition_id": "0xabc123def456...",
    "asset": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
    "proxy_wallet": "0x1234567890abcdef1234567890abcdef12345678",
    "side": "SELL",
    "outcome": "Yes",
    "size": 500,
    "price": 0.78,
    "size_usd": 390,
    "timestamp": 1712603130,
    "title": "Will BTC hit $100k by July 2025?",
    "event_slug": "will-btc-hit-100k-by-july-2025",
    "transaction_hash": "0xfeedface..."
  },
  "execution": {
    "timestamp": 1712603131,
    "token_id": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
    "condition_id": "0xabc123def456...",
    "market_question": "Will BTC hit $100k by July 2025?",
    "side": "SELL",
    "size_usd": 25,
    "fill_price": 0.77,
    "is_paper": false,
    "strategy": "Fresh Whale Copy",
    "order_id": "0xorder456...",
    "status": "filled",
    "pnl": 5.56,
    "error_message": null,
    "source": "fresh_wallet",
    "tracked_wallet": "0x1234567890abcdef1234567890abcdef12345678",
    "event_slug": "will-btc-hit-100k-by-july-2025"
  }
}

execution.stop_loss

Fired when a position hits your configured stop-loss level. Includes the trigger type, P&L, and entry/exit prices.

{
  "event": "execution.stop_loss",
  "timestamp": "2025-04-08T20:12:45.987654+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "execution": {
    "timestamp": 1712608365,
    "token_id": "55555555555555555555555555555555555555555555555555555555555555555555",
    "condition_id": "0x555aaa...",
    "market_question": "Will SOL reach $200 by May?",
    "side": "SELL",
    "size_usd": 50,
    "fill_price": 0.41,
    "is_paper": false,
    "strategy": "Leaderboard Copy",
    "order_id": "0xorder789...",
    "status": "filled",
    "pnl": -9.5,
    "error_message": null,
    "source": "leaderboard",
    "tracked_wallet": "0xabcdef1234567890abcdef1234567890abcdef12",
    "event_slug": "will-sol-reach-200-by-may"
  },
  "trigger": "stop_loss",
  "pnl": -9.5,
  "pnl_percent": -19,
  "entry_price": 0.5,
  "exit_price": 0.41
}

execution.take_profit

Fired when a position hits your configured take-profit level. Same structure as stop_loss with a different trigger.

{
  "event": "execution.take_profit",
  "timestamp": "2025-04-08T22:05:10.111111+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "execution": {
    "timestamp": 1712615110,
    "token_id": "66666666666666666666666666666666666666666666666666666666666666666666",
    "condition_id": "0x666bbb...",
    "market_question": "Will the Fed cut rates in June?",
    "side": "SELL",
    "size_usd": 30,
    "fill_price": 0.82,
    "is_paper": true,
    "strategy": "Fresh Whale Copy",
    "order_id": null,
    "status": "filled",
    "pnl": 6,
    "error_message": null,
    "source": "fresh_wallet",
    "tracked_wallet": "0x9999888877776666555544443333222211110000",
    "event_slug": "will-the-fed-cut-rates-in-june"
  },
  "trigger": "take_profit",
  "pnl": 6,
  "pnl_percent": 24,
  "entry_price": 0.62,
  "exit_price": 0.82
}

execution.resolution

Fired when a Polymarket market resolves and your position is settled. Includes the final P&L and entry price.

{
  "event": "execution.resolution",
  "timestamp": "2025-04-09T00:00:01.000000+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "execution": {
    "timestamp": 1712620801,
    "token_id": "77777777777777777777777777777777777777777777777777777777777777777777",
    "condition_id": "0x777ccc...",
    "market_question": "Will it rain in NYC on April 8?",
    "side": "SELL",
    "size_usd": 15,
    "fill_price": 1,
    "is_paper": false,
    "strategy": "Watchlist Fade",
    "order_id": "0xorderaaa...",
    "status": "filled",
    "pnl": 7.5,
    "error_message": null,
    "source": "watchlist",
    "tracked_wallet": "0xaaaa0000bbbb1111cccc2222dddd3333eeee4444",
    "event_slug": "will-it-rain-in-nyc-on-april-8"
  },
  "pnl": 7.5,
  "entry_price": 0.5
}

portfolio.summary

Fired hourly with a snapshot of open positions, daily P&L, win rate, and trade count. The summary object fields may vary as we add more metrics.

{
  "event": "portfolio.summary",
  "timestamp": "2025-04-08T23:00:00.000000+00:00",
  "strategy_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "summary": {
    "open_positions": 4,
    "total_invested": 120,
    "unrealized_pnl": 8.75,
    "realized_pnl_today": 14.31,
    "win_rate": 0.67,
    "trades_today": 6
  }
}

Common Field Reference

Base fields (all events)

FieldTypeDescription
eventstringEvent type identifier
timestampstringISO 8601 UTC timestamp
strategy_idstringUUID of the strategy that generated this event

execution object

FieldTypeDescription
timestampintegerUnix epoch seconds of the execution
token_idstringPolymarket token ID (outcome share)
condition_idstringPolymarket condition ID (market)
market_questionstringHuman-readable market question
sidestring"BUY" or "SELL"
size_usdnumberTrade size in USD
fill_pricenumberPrice at which the order was filled (0-1)
is_paperbooleantrue if this was a simulated paper trade
strategystringStrategy name
order_idstring | nullPolymarket order ID (null for paper trades)
statusstring"filled", "partial", "error"
pnlnumber | nullRealized P&L if this is an exit
error_messagestring | nullError details if status is not filled
sourcestring"fresh_wallet", "leaderboard", "watchlist"
tracked_walletstringThe wallet address that triggered this trade
event_slugstringPolymarket event slug for linking

Quick Start

  1. Go to Settings and enter your webhook URL (and optional secret).
  2. PolySpy sends a test POST to verify your endpoint is reachable.
  3. Activate a strategy — events start flowing immediately in both paper and live mode.
  4. Optionally override the webhook URL on individual strategies to route signals to different endpoints.