> ## Documentation Index
> Fetch the complete documentation index at: https://docs.struct.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting Started

> Receive real-time notifications when events happen on Polymarket via webhooks.

## Overview

Webhooks let you subscribe to real-time events from Polymarket (like trades, PnL changes, volume milestones, and price spikes) delivered directly to your server as HTTP POST requests.

Instead of polling the API, webhooks push data to you the moment something happens. Deliveries are [event-driven](/webhooks/delivery), evaluated inline as on-chain activity is ingested rather than on a polling cycle.

## Base URL

All webhook management requests use the same base URL as the REST API:

```
https://api.struct.to
```

## Setting Up Your First Webhook

<Steps>
  <Step title="Create an account">
    Sign up at [struct.to/dashboard](https://struct.to/dashboard) and create an organisation.
  </Step>

  <Step title="Generate an API key">
    Navigate to the API Keys section in your dashboard and create a new key.
  </Step>

  <Step title="Prepare your endpoint">
    Set up an HTTP endpoint on your server that accepts POST requests and returns a `200` status code. Your endpoint must be publicly accessible.
  </Step>

  <Step title="Create a webhook subscription">
    Register your endpoint with the event you want to listen to. Each subscription targets a single event with its own filters — create one subscription per event:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.struct.to/v1/webhooks \
        -H "X-API-Key: YOUR_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "url": "https://your-server.com/webhooks",
          "event": "trader_whale_trade",
          "secret": "your_signing_secret",
          "filters": { "min_usd_value": 10000 }
        }'
      ```

      ```javascript JavaScript theme={null}
      const response = await fetch("https://api.struct.to/v1/webhooks", {
        method: "POST",
        headers: {
          "X-API-Key": "YOUR_API_KEY",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          url: "https://your-server.com/webhooks",
          event: "trader_whale_trade",
          secret: "your_signing_secret",
          filters: { min_usd_value: 10000 },
        }),
      });

      const data = await response.json();
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          "https://api.struct.to/v1/webhooks",
          headers={"X-API-Key": "YOUR_API_KEY"},
          json={
              "url": "https://your-server.com/webhooks",
              "event": "trader_whale_trade",
              "secret": "your_signing_secret",
              "filters": {"min_usd_value": 10000},
          },
      )

      data = response.json()
      ```
    </CodeGroup>
  </Step>

  <Step title="Test your webhook">
    Send a test payload to verify connectivity:

    ```bash theme={null}
    curl -X POST https://api.struct.to/v1/webhooks/{webhook_id}/test \
      -H "X-API-Key: YOUR_API_KEY"
    ```
  </Step>
</Steps>

## Available Events

### Trader Events

| Event                | Description                                                                              |
| -------------------- | ---------------------------------------------------------------------------------------- |
| `trader_first_trade` | Tracked trader executes their first-ever trade on Polymarket                             |
| `trader_new_market`  | Trader places their first trade in a specific market (fires once per trader+market pair) |
| `trader_new_trade`   | Every order-filled trade by a tracked trader                                             |
| `trader_trade_event` | Typed prediction-trade stream events for a tracked trader                                |
| `trader_whale_trade` | Trade exceeds the configured size and probability thresholds                             |
| `trader_global_pnl`  | Trader's global PnL (across all markets) crosses a configured threshold                  |
| `trader_market_pnl`  | Trader's per-market PnL crosses a configured threshold                                   |
| `trader_event_pnl`   | Trader's per-event PnL crosses a configured threshold                                    |

### Market & Event Metrics

| Event               | Description                                                                   |
| ------------------- | ----------------------------------------------------------------------------- |
| `condition_metrics` | Market's volume or transaction metrics cross a configured threshold           |
| `event_metrics`     | Event's aggregated volume or transaction metrics cross a configured threshold |
| `position_metrics`  | Position's volume or transaction metrics cross a configured threshold         |
| `tag_metrics`       | Tag's aggregated volume or transaction metrics cross a configured threshold   |

### Volume Milestones

| Event                       | Description                                               |
| --------------------------- | --------------------------------------------------------- |
| `market_volume_milestone`   | Market's trading volume crosses a USD milestone           |
| `event_volume_milestone`    | Event's aggregated trading volume crosses a USD milestone |
| `position_volume_milestone` | Position's trading volume crosses a USD milestone         |

### Spikes

| Event                   | Description                                                                                 |
| ----------------------- | ------------------------------------------------------------------------------------------- |
| `price_spike`           | Position's raw trade price (not enriched probability) spikes within a window                |
| `price_threshold`       | Outcome's price crosses a target level you set (edge-triggered, fires once per crossing)    |
| `market_volume_spike`   | Market's volume in a timeframe exceeds the configured baseline by the spike ratio           |
| `event_volume_spike`    | Event's aggregated volume in a timeframe exceeds the configured baseline by the spike ratio |
| `position_volume_spike` | Position's volume in a timeframe exceeds the configured baseline by the spike ratio         |

### Market Lifecycle

| Event             | Description                                                                                 |
| ----------------- | ------------------------------------------------------------------------------------------- |
| `close_to_bond`   | Trade occurs at a near-certain-outcome price                                                |
| `market_created`  | New prediction market is detected on-chain and enriched with metadata                       |
| `oracle_events`   | On-chain oracle activity: resolution, dispute, assertion, emergency, and related events     |
| `market_resolved` | Market reaches a terminal resolution, deduplicated to one delivery with the winning outcome |
| `market_disputed` | Proposed market resolution is challenged on-chain                                           |

### Asset Prices

| Event                       | Description                                                |
| --------------------------- | ---------------------------------------------------------- |
| `asset_price_tick`          | Every raw Chainlink price tick for a tracked crypto asset  |
| `asset_price_window_update` | Delivered twice per candle: once on open and once on close |

## Filtering

Webhooks support granular filters so you only receive the events you care about. Filters can be passed when creating or updating a webhook:

* **Wallet address**: track specific traders
* **Market / condition ID**: target specific markets
* **Event slug**: filter by event
* **USD thresholds**: minimum/maximum value bounds
* **Probability range**: 0.0 to 1.0
* **PnL bounds and volume minimums**

Every event also accepts `one_shot` to fire once and then delete the subscription automatically. See [Fire-and-Delete](/webhooks/fire-and-delete).

## Verifying Payloads

If you provide a `secret` when creating your webhook, each delivery includes an `X-Webhook-Signature` header (HMAC-SHA256 of the raw body) you can use to verify the payload originated from Struct.

<Warning>Always verify webhook signatures in production to prevent spoofed requests. See [Signature Verification](/webhooks/signature-verification) for the scheme and copy-paste verification code.</Warning>

## Managing Webhooks

You can list, update, pause, and delete your webhooks via the API:

| Method   | Endpoint                          | Description                                        |
| -------- | --------------------------------- | -------------------------------------------------- |
| `GET`    | `/v1/webhooks`                    | List all your webhook subscriptions                |
| `GET`    | `/v1/webhooks/events`             | List available event types                         |
| `GET`    | `/v1/webhooks/{id}`               | Get a specific webhook                             |
| `PUT`    | `/v1/webhooks/{id}`               | Update a webhook's URL, events, filters, or status |
| `DELETE` | `/v1/webhooks/{id}`               | Delete a webhook                                   |
| `POST`   | `/v1/webhooks/{id}/rotate-secret` | Rotate the signing secret                          |
| `POST`   | `/v1/webhooks/{id}/test`          | Send a test payload                                |
| `GET`    | `/v1/webhooks/{id}/logs`          | Inspect recent delivery logs (7-day retention)     |

## Limits

How many webhook subscriptions you can create depends on your plan: **10** on Free, **5,000** on Hobby, **25,000** on Startup, and **100,000** on Scale (Enterprise is unlimited). Rate limits on the management API also depend on your plan; see [Pricing & Ratelimits](/introduction/pricing) for details.

If you need higher limits, reach out to us at [support@struct.to](mailto:support@struct.to).
