{"version":"0.1","events":[{"type":"arb_flagged","description":"An arbitrage opportunity was detected across books.","trigger":"arb_scanner finds a pair of opposing-side odds whose implied probabilities sum < 1.0."},{"type":"ev_alert","description":"A +EV pick was identified (sharp book disagrees with soft books).","trigger":"ev_finder compares pinnacle no-vig fair line vs soft-book line; emits when edge > threshold."},{"type":"line_move","description":"A tracked line crossed a configured threshold.","trigger":"Customer-configured threshold breach on a tracked event/market."},{"type":"live_arb","description":"An in-play arbitrage opportunity (faster decay than pre-match arbs).","trigger":"inplay_scanner finds an arb on a currently-live event."},{"type":"odds_drop","description":"A book moved a price significantly from its recent average.","trigger":"Price drop > 10% from rolling 5-min average on a tracked market."},{"type":"new_event","description":"A new event was added to the catalogue.","trigger":"Daily catalogue refresh discovered an event not previously tracked."},{"type":"test","description":"Fired manually via POST /v1/webhooks/{id}/test for integration testing.","trigger":"Customer-initiated test event."}],"signing":{"algorithm":"HMAC-SHA256","header_name":"X-Parlay-Signature","header_format":"t=<unix_timestamp>,v1=<hex_hmac>","verification_pseudocode":"hmac_sha256(secret=webhook_secret, message=raw_body) == unhexlify(v1_value). Also verify abs(now - t) < 300 to reject replay attacks beyond a 5-minute window.","rotate_secret_endpoint":"POST /v1/webhooks/{webhook_id}/rotate-secret","secret_format":"whsec_<43 chars base64url>"},"retry_policy":{"max_attempts":3,"backoff":["immediate","+30s","+5min"],"consecutive_failures_to_disable":5,"on_auto_disable":"Email sent to account owner; is_active flips to false; webhook stops receiving deliveries until re-enabled via PATCH /v1/webhooks/{id}.","delivery_timeout_seconds":10},"tier_gate":{"minimum_tier":"pro","tiers_allowed":["pro","scale","business","enterprise"],"tiers_blocked":["free","starter"],"rationale":"Webhooks require background delivery + retry infrastructure; reserved for paying tiers."},"management":{"list_url":"GET /v1/webhooks","create_url":"POST /v1/webhooks","get_one_url":"GET /v1/webhooks/{webhook_id}","update_url":"PATCH /v1/webhooks/{webhook_id}","delete_url":"DELETE /v1/webhooks/{webhook_id}","rotate_secret_url":"POST /v1/webhooks/{webhook_id}/rotate-secret","test_url":"POST /v1/webhooks/{webhook_id}/test","deliveries_url":"GET /v1/webhooks/{webhook_id}/deliveries"},"delivery":{"method":"POST","content_type":"application/json","headers_we_send":["Content-Type: application/json","User-Agent: ParlayAPI-Webhook/1.0","X-Parlay-Signature: t=<ts>,v1=<hmac>","X-Parlay-Event-Type: <event_type>","X-Parlay-Webhook-Id: <int>","X-Parlay-Delivery-Attempt: <int 1-3>"],"body_shape_example":{"event_type":"ev_alert","event_id":"evt_abc123","ts":1778850000,"data":{"...":"event-specific payload"}}},"filtering":{"sport_filter":"When creating a webhook, set sport_filter=[\"baseball_mlb\",\"basketball_nba\"] to receive only events for those sports. Omit to receive everything."},"related":{"api_info_url":"/v1/meta/api-info","credit_costs_url":"/v1/meta/credit-costs","pricing_url":"/v1/pricing","docs_url":"/docs/webhooks","openapi_url":"/openapi.json"},"industry_pattern":"Modeled after Stripe/Twilio/GitHub webhook conventions: HMAC-SHA256 signing, timestamped header to prevent replay, automatic retry with exponential backoff, auto-disable on persistent failure. Standard webhook receiver libraries (svix, stripe-event-webhook) work out of the box."}