> ## 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.

# Create webhook

> Create a new webhook subscription for real-time event notifications



## OpenAPI

````yaml https://api.struct.to/webhookopenapi.json post /webhooks
openapi: 3.1.0
info:
  title: Polymarket Webhook API
  description: ''
  license:
    name: ''
  version: 1.0.0
servers:
  - url: https://api.struct.to/v1
security: []
tags:
  - name: Webhooks
    description: Webhook subscription management (CRUD operations)
  - name: Webhook Callbacks
    description: Outgoing HTTP calls to your endpoints when subscribed events occur
paths:
  /webhooks:
    post:
      tags:
        - Webhooks
      summary: Create webhook
      description: Create a new webhook subscription for real-time event notifications
      operationId: create_webhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookRequestBody'
        required: true
      responses:
        '201':
          description: Webhook created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookResponse'
        '400':
          description: Invalid request (malformed URL, invalid filters, etc.)
        '401':
          description: Missing or invalid API key
        '402':
          description: Insufficient credits
        '429':
          description: Rate limit exceeded (max 100 webhooks per user)
      security:
        - api_key: []
components:
  schemas:
    CreateWebhookRequestBody:
      type: object
      description: Request body for creating a webhook
      required:
        - url
        - event
      properties:
        url:
          type: string
          description: Destination URL for webhook deliveries (must be HTTPS)
        event:
          $ref: '#/components/schemas/PolymarketWebhookEvent'
          description: Event to subscribe to
        secret:
          type:
            - string
            - 'null'
          description: Optional secret for HMAC signature verification
        filters:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/WebhookFiltersBody'
              description: Optional filters for event matching
        description:
          type:
            - string
            - 'null'
          description: Optional description/name
    WebhookResponse:
      type: object
      description: Webhook response (returned from API)
      required:
        - id
        - url
        - event
        - status
        - created_at
        - updated_at
        - has_secret
      properties:
        id:
          type: string
          description: Unique webhook ID
        url:
          type: string
          description: Destination URL
        event:
          $ref: '#/components/schemas/PolymarketWebhookEvent'
          description: Subscribed event
        filters:
          $ref: '#/components/schemas/PolymarketWebhookFilter'
          description: Active filters (omitted when no filters are set)
        status:
          type: string
          enum:
            - active
            - paused
            - disabled
            - suspended
          description: Current webhook status
        created_at:
          type: integer
          format: int64
          description: Created timestamp (ms)
        updated_at:
          type: integer
          format: int64
          description: Updated timestamp (ms)
        description:
          type:
            - string
            - 'null'
          description: Description/name
        has_secret:
          type: boolean
          description: Whether an HMAC secret is configured
        credits_used_24h:
          type: integer
          format: int64
          description: Credits consumed by this webhook in the last 24 hours
    PolymarketWebhookEvent:
      type: string
      description: Polymarket webhook event types
      enum:
        - trader_first_trade
        - trader_new_market
        - trader_whale_trade
        - trader_new_trade
        - trader_trade_event
        - trader_global_pnl
        - trader_market_pnl
        - trader_category_pnl
        - trader_position_resolved
        - trader_exit_markers
        - position_holder_metrics
        - condition_holder_metrics
        - event_holder_metrics
        - condition_metrics
        - event_metrics
        - tag_metrics
        - position_metrics
        - position_liquidity
        - market_liquidity
        - event_liquidity
        - market_volume_milestone
        - event_volume_milestone
        - position_volume_milestone
        - market_volume_spike
        - event_volume_spike
        - position_volume_spike
        - close_to_bond
        - market_created
        - asset_price_tick
        - asset_price_window_update
        - price_spike
        - probability_spike
        - oracle_events
        - price_threshold
        - market_resolved
        - market_disputed
    WebhookFiltersBody:
      type: object
      description: Webhook filters request body
      properties:
        wallet_addresses:
          type: array
          items:
            type: string
          description: >-
            Filter by wallet addresses (for first_trade / new_market /
            whale_trade). Max 500 entries.
        traders:
          type: array
          items:
            type: string
          description: Filter by trader addresses (for PnL webhooks). Max 500 entries.
        condition_ids:
          type: array
          items:
            type: string
          description: Filter by market/condition IDs. Max 500 entries.
        position_ids:
          type: array
          items:
            type: string
          description: >-
            Filter by position IDs (for position metrics / close_to_bond). Max
            500 entries.
        event_slugs:
          type: array
          items:
            type: string
          description: Filter by event slugs. Max 500 entries.
        tags:
          type: array
          items:
            type: string
          description: >-
            Filter by tags or category names (case-insensitive). Matches a
            market's tags or its

            category label — for market_created and all market-keyed events. Max
            500 entries.
        series_slugs:
          type: array
          items:
            type: string
          description: >-
            Filter by series slugs (case-insensitive). Matches a market's parent
            series — for all

            market-keyed events. Max 500 entries.
        outcomes:
          type: array
          items:
            type: string
          description: >-
            Filter by outcomes (e.g. "Yes", "No") — for position metrics /
            close_to_bond. Max 500 entries.
        position_outcome_indices:
          type: array
          items:
            type: integer
            format: int32
            minimum: 0
          description: >-
            Filter by position outcome index — for close_to_bond. Position 0 =
            Yes/Up, 1 = No. Max 500 entries.
        trade_types:
          type: array
          items:
            type: string
          description: >-
            Filter by trade type — for `trader_new_trade` and
            `trader_trade_event`. Max 500 entries.
        min_usd_value:
          type:
            - number
            - 'null'
          format: double
          description: Minimum USD trade size (for whale_trade / first_trade)
        min_price:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Minimum price threshold (0.0 - 1.0). Accepts the legacy
            `min_probability` key.
        max_price:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Maximum price threshold (0.0 - 1.0). Accepts the legacy
            `max_probability` key.
        min_realized_pnl_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum realized PnL (USD) — for global_pnl / market_pnl / event_pnl
        max_realized_pnl_usd:
          type:
            - number
            - 'null'
          format: double
          description: Maximum realized PnL (USD) — for global_pnl / market_pnl / event_pnl
        min_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum total volume (USD) — for global_pnl / event_pnl / metrics
        max_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Maximum total volume (USD) — for metrics webhooks
        min_buy_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum buy volume (USD) — for market_pnl / position metrics
        min_sell_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum sell volume (USD) — for position metrics
        min_win_rate:
          type:
            - number
            - 'null'
          format: double
          description: Minimum win rate (0.0 - 100.0) — for global_pnl
        min_markets_traded:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum markets traded — for global_pnl / event_pnl
        min_net_shares:
          type:
            - number
            - 'null'
          format: double
          description: Minimum net shares held — for position-level filters
        max_net_shares:
          type:
            - number
            - 'null'
          format: double
          description: Maximum net shares held — for position-level filters
        min_fees:
          type:
            - number
            - 'null'
          format: double
          description: Minimum fees (USD) — for metrics webhooks
        min_txns:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum transaction count — for metrics webhooks
        min_unique_traders:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum unique traders — for metrics webhooks
        min_price_change_pct:
          type:
            - number
            - 'null'
          format: double
          description: Minimum price change percentage — for position metrics
        min_probability_change_pct:
          type:
            - number
            - 'null'
          format: double
          description: Minimum probability change percentage (legacy spike filter field)
        timeframes:
          type: array
          items:
            $ref: '#/components/schemas/WebhookTimeframe'
          description: >-
            Timeframes to filter by (e.g. ["1h", "24h", "7d"]) — **required**
            for volume_milestone

            webhooks (market/event/position), optional for metrics webhooks.

            Valid values: "1m", "5m", "30m", "1h", "6h", "24h", "7d", "30d".
        milestone_amounts:
          type: array
          items:
            type: integer
            format: int64
          description: >-
            Milestone amounts to trigger on (USD) — for volume_milestone
            webhooks. Max 500 entries.
        spike_ratio:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Spike ratio multiplier (must be > 1.0) — for volume_spike. E.g. 2.0
            for 2x baseline
        spike_direction:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/SpikeDirection'
              description: Direction filter for spike webhooks — "up", "down", or "both"
        window_secs:
          type:
            - integer
            - 'null'
          format: int64
          description: >-
            Observation window in seconds (max 600) — for price_spike,
            volume_spike
          minimum: 0
        exclude_shortterm_markets:
          type: boolean
          description: When true, suppress webhooks for short-term "updown" markets
        asset_symbols:
          type: array
          items:
            $ref: '#/components/schemas/WebhookAssetSymbol'
          description: >-
            Filter by crypto asset symbol — for `asset_price_tick` and
            `asset_price_window_update`.

            Valid values: "BTC", "ETH", "SOL", "XRP", "DOGE", "BNB", "HYPE".
            Empty = all assets (send everything).
        one_shot:
          type: boolean
          description: >-
            Fire-and-delete: delete the subscription after its first successful

            delivery. Works on any webhook event. (`price_threshold`
            additionally

            requires `position_ids` or `condition_ids`.)
        fire_if_already_past:
          type: boolean
          description: >-
            For `price_threshold` — fire immediately if the first observed price
            is

            already past the target. Default `false` (wait for an actual
            crossing).
    PolymarketWebhookFilter:
      type: object
      description: >-
        Polymarket-specific webhook filters


        Different webhook handlers use different subsets of these fields.

        The trade-driven events `price_spike` and

        `close_to_bond` additionally accept `tags` (matches a market's tags OR
        its

        category) and `series_slugs` (matches the market's parent series); these
        are

        resolved from the tags/series the crawler enriches onto each trade.

        - first_trade: wallet_addresses, min_usd_value, min_price, max_price,
        condition_ids, event_slugs, tags

        - new_market: wallet_addresses, condition_ids, event_slugs,
        min_usd_value, min_price, max_price

        - whale_trade: min_usd_value (required), min_price, max_price,
        condition_ids, event_slugs

        - global_pnl: traders, min_realized_pnl_usd, max_realized_pnl_usd,
        min_volume_usd, min_win_rate, min_markets_traded

        - market_pnl: traders, min_realized_pnl_usd, max_realized_pnl_usd,
        min_buy_usd, condition_ids, event_slugs

        - event_pnl: traders, min_realized_pnl_usd, max_realized_pnl_usd,
        min_volume_usd, event_slugs, min_markets_traded

        - condition_metrics: condition_ids, min_volume_usd, max_volume_usd,
        min_fees, min_txns, timeframes

        - event_metrics: event_slugs, min_volume_usd, max_volume_usd, min_fees,
        min_txns, timeframes

        - tag_metrics: tags, min_volume_usd, max_volume_usd, min_fees, min_txns,
        timeframes

        - position_metrics: position_ids, condition_ids, outcomes,
        min_volume_usd, max_volume_usd, min_buy_usd, min_sell_volume_usd,
        min_fees, min_txns, min_price_change_pct, min_probability_change_pct,
        timeframes

        - volume_milestone: condition_ids, timeframes, milestone_amounts

        - close_to_bond: min_price (high zone threshold), max_price (low zone
        threshold), condition_ids, tags, series_slugs, position_ids, outcomes,
        position_outcome_indices, event_slugs, exclude_shortterm_markets

        - market_created: event_slugs, tags, exclude_shortterm_markets

        - price_spike: condition_ids, event_slugs, tags, series_slugs, outcomes,
        min_price_change_pct, spike_direction, window_secs,
        exclude_shortterm_markets

        - trader_new_trade: wallet_addresses, min_usd_value, min_price,
        max_price, condition_ids, event_slugs, trade_types,
        exclude_shortterm_markets

        - trader_trade_event: wallet_addresses, min_usd_value, min_price,
        max_price, condition_ids, event_slugs, trade_types,
        exclude_shortterm_markets

        - trader_first_trade: wallet_addresses, min_usd_value, min_price,
        max_price, exclude_shortterm_markets

        - trader_new_market: wallet_addresses, condition_ids, event_slugs,
        min_usd_value, min_price, max_price, exclude_shortterm_markets

        - trader_whale_trade: min_usd_value (required), min_price, max_price,
        condition_ids, event_slugs, exclude_shortterm_markets

        - trader_event_pnl: traders, min_realized_pnl_usd, max_realized_pnl_usd,
        min_volume_usd, event_slugs, min_markets_traded,
        exclude_shortterm_markets

        - trader_market_pnl: traders, min_realized_pnl_usd,
        max_realized_pnl_usd, min_buy_usd, condition_ids, event_slugs,
        exclude_shortterm_markets


        Implements Hash + Eq manually (f64 fields use bit representation)
      properties:
        wallet_addresses:
          type: array
          items:
            type: string
          description: >-
            Filter by wallet addresses (for first_trade, normalized to
            lowercase). Max 500 entries.

            Wallet addresses to match.
        traders:
          type: array
          items:
            type: string
          description: >-
            Filter by trader addresses (for PnL webhooks, normalized to
            lowercase). Max 500 entries.

            Trader wallet addresses to match.
        condition_ids:
          type: array
          items:
            type: string
          description: |-
            Filter by market/condition IDs. Max 500 entries.
            Market condition IDs to match.
        min_usd_value:
          type:
            - number
            - 'null'
          format: double
          description: Filter by minimum USD value (for trades)
        event_slugs:
          type: array
          items:
            type: string
          description: |-
            Filter by event slugs. Max 500 entries.
            Event slugs to match.
        tags:
          type: array
          items:
            type: string
          description: >-
            Filter by tags or category names (case-insensitive). Matches a
            market's

            tags or its category label. Max 500 entries.

            Tags to match.
        series_slugs:
          type: array
          items:
            type: string
          description: |-
            Filter by series slugs (case-insensitive). Matches a market's parent
            series. Max 500 entries.
            Series slugs to match.
        min_price:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Minimum trade price threshold (0.0 - 1.0). Accepts the legacy
            `min_probability` key.
        max_price:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Maximum trade price threshold (0.0 - 1.0). Accepts the legacy
            `max_probability` key.
        min_realized_pnl_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum realized PnL (USD) - for PnL webhooks
        max_realized_pnl_usd:
          type:
            - number
            - 'null'
          format: double
          description: Maximum realized PnL (USD) - for PnL webhooks
        min_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum volume (USD) - for PnL and metrics webhooks
        max_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Maximum volume (USD) - for metrics webhooks
        min_liquidity_usd:
          type:
            - number
            - 'null'
          format: double
          description: |-
            Minimum order-book liquidity (USD) - for liquidity webhooks.
            Fires when liquidity crosses up through this value.
        max_liquidity_usd:
          type:
            - number
            - 'null'
          format: double
          description: |-
            Maximum order-book liquidity (USD) - for liquidity webhooks.
            Fires when liquidity crosses down through this value.
        min_buy_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum buy volume (USD) - for PnL and metrics webhooks
        min_win_rate:
          type:
            - number
            - 'null'
          format: double
          description: Minimum win rate (0.0 - 100.0) - for global PnL webhooks
        min_markets_traded:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum markets traded - for PnL webhooks
        min_net_shares:
          type:
            - number
            - 'null'
          format: double
          description: Minimum net shares - for position PnL webhooks
        max_net_shares:
          type:
            - number
            - 'null'
          format: double
          description: Maximum net shares - for position PnL webhooks
        position_ids:
          type: array
          items:
            type: string
          description: |-
            Filter by position IDs - for position PnL webhooks. Max 500 entries.
            Outcome token IDs to match.
        outcomes:
          type: array
          items:
            type: string
          description: >-
            Filter by outcomes (e.g., "Yes", "No") - for position PnL webhooks.
            Max 500 entries.

            Outcome names to match.
        position_outcome_indices:
          type: array
          items:
            type: integer
            format: int32
            minimum: 0
          description: >-
            Filter by position outcome index — for close_to_bond. Position 0
            usually represents Yes/Up, 1 = No.

            When non-empty, only trades whose outcome_index is in this list will
            match. Max 500 entries.

            Outcome indices to match.
        trade_types:
          type: array
          items:
            type: string
          description: >-
            Filter by trade type (e.g. "OrderFilled", "Redemption", "Merge",
            "Split"). Empty = default behavior per handler.

            Trade types to match.
        min_fees:
          type:
            - number
            - 'null'
          format: double
          description: Minimum fees - for metrics webhooks
        min_txns:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum transaction count - for metrics webhooks
        min_unique_traders:
          type:
            - integer
            - 'null'
          format: int64
          description: Minimum unique traders - for metrics webhooks
        min_sell_volume_usd:
          type:
            - number
            - 'null'
          format: double
          description: Minimum sell volume (USD) - for position metrics webhooks
        min_price_change_pct:
          type:
            - number
            - 'null'
          format: double
          description: Minimum price change percentage - for position metrics webhooks
        min_probability_change_pct:
          type:
            - number
            - 'null'
          format: double
          description: >-
            Minimum probability change percentage - for position metrics
            webhooks
        timeframes:
          type: array
          items:
            $ref: '#/components/schemas/WebhookTimeframe'
          description: >-
            Timeframes to track - for metrics webhooks (1m, 5m, 30m, 1h, 6h,
            24h, 7d, 30d).

            Metric timeframes to match.
        milestone_amounts:
          type: array
          items:
            type: integer
            format: int64
          description: >-
            Milestone amounts to track - for volume milestone webhooks (e.g.,
            10000, 100000, 1000000). Max 500 entries.

            Milestone amounts to match.
        spike_ratio:
          type:
            - number
            - 'null'
          format: double
          description: |-
            Spike ratio multiplier (must be > 1.0) - for volume spike webhooks
            Example: 2.0 for 2x, 5.0 for 5x, 10.0 for 10x
        exclude_shortterm_markets:
          type: boolean
          description: >-
            When `true`, exclude all short-term "updown" markets (event slugs
            containing "updown").

            These are short-duration crypto price markets (e.g.,
            "btc-updown-5m-…", "eth-updown-1h-…").

            Supported by: close_to_bond, market_created, price_spike,

            trader_first_trade, trader_new_market, trader_whale_trade,
            trader_event_pnl, trader_market_pnl,

            event_metrics, event_volume_milestone, event_volume_spike.
        asset_symbols:
          type: array
          items:
            $ref: '#/components/schemas/WebhookAssetSymbol'
          description: >-
            Filter by crypto asset symbol — for `asset_price_tick` and
            `asset_price_window_update` webhooks.

            Valid values: "BTC", "ETH", "SOL", "XRP", "DOGE", "BNB", "HYPE".
            Empty = all assets.

            Asset symbols to match.
        spike_direction:
          oneOf:
            - type: 'null'
            - $ref: '#/components/schemas/SpikeDirection'
              description: >-
                Direction filter for `price_spike` — only fire for spikes in a
                specific direction.

                Omit or set to `null` to receive spikes in both directions.
        window_secs:
          type:
            - integer
            - 'null'
          format: int64
          description: >-
            Observation window in seconds for `price_spike`.


            When set, the first trade seen for a position opens a window of this
            duration.

            The opening price becomes the baseline, and every subsequent trade
            within the

            window is compared to it. When the window expires the next trade
            starts a new

            window. If omitted, the baseline accumulates indefinitely until a
            spike fires.


            Example: `60` to detect spikes that happen within 60 seconds.
          minimum: 0
        oracle_event_types:
          type: array
          items:
            type: string
          description: >-
            Filter for `oracle_events` by event name (case-insensitive).

            Valid values: `AssertionMade`, `AssertionDisputed`,
            `AssertionSettled`,

            `RequestPrice`, `ProposePrice`, `DisputePrice`, `Settle`,

            `QuestionResolved`, `QuestionEmergencyResolved`, `QuestionReset`,

            `QuestionInitialized`, `QuestionPaused`, `QuestionUnpaused`,

            `QuestionFlagged`, `QuestionUnflagged`, `ConditionResolution`,

            `NegRiskOutcomeReported`. Empty = all types.

            Oracle event types to match.
        one_shot:
          type: boolean
          description: >-
            Fire-and-delete: when `true`, the subscription is deleted after its
            first

            successful delivery. Works on any webhook event. (`price_threshold`

            additionally requires `position_ids` or `condition_ids`.)
        fire_if_already_past:
          type: boolean
          description: >-
            For `price_threshold` — when `true`, fire immediately if the first
            observed

            price is already past the target (no prior baseline). Default
            `false`.
    WebhookTimeframe:
      type: string
      description: >-
        Timeframe values accepted by webhook metric, milestone, spike, and
        asset-price filters.
      enum:
        - 1m
        - 5m
        - 15m
        - 30m
        - 1h
        - 4h
        - 6h
        - 1d
        - 24h
        - 7d
        - 30d
        - lifetime
    SpikeDirection:
      type: string
      description: Direction filter for spike webhooks.
      enum:
        - up
        - down
        - both
    WebhookAssetSymbol:
      type: string
      description: >-
        Crypto asset symbols accepted by `asset_price_tick` and
        `asset_price_window_update` filters.
      enum:
        - BTC
        - ETH
        - SOL
        - XRP
        - DOGE
        - BNB
        - HYPE

````