Scanner API Documentation

The scanner console app communicates with this web app via the following API endpoints.

GET /api/scanner/settings

Returns current scanner settings. Call this at the start of each scan loop.

Response:
{
  "mode": "Research",
  "buyAllYesMaxSum": 1.02,
  "sellAllYesMinSum": 0.98,
  "minDisplayProfit": -0.05,
  "scanIntervalSeconds": 30,
  "apiThrottleMs": 200,
  "maxRetries": 5,
  "broadcastIntervalSeries": 50,
  "blockedStrikeTypes": ["greater", "less", ...],
  "winnerPatterns": ["will win", "will be elected", ...],
  "minVolume": 100,
  "minOpenInterest": 50,
  "maxResultsDisplay": 100
}
POST /api/scanner/classify

Classify a market group for mutual exclusivity. Call for each event group with 2+ legs.

Request:
{
  "markets": [
    {
      "eventTicker": "KXSENATE-AZ-26",
      "ticker": "KXSENATE-AZ-26-DEM",
      "title": "Arizona Senate",
      "subtitle": "Democrat wins",
      "strikeType": "custom",
      "yesBid": 0.45,
      "yesAsk": 0.47,
      "liquidity": 5000,
      "hasCustomStrike": true,
      "customStrikeValue": "Democrat"
    },
    ...
  ],
  "eventTicker": "KXSENATE-AZ-26"
}
Response:
{
  "eventTicker": "KXSENATE-AZ-26",
  "isMutuallyExclusive": true,
  "buyAllYesAllowed": true,
  "sellAllYesAllowed": true,
  "classificationReason": "APPROVED: Winner language detected - 3 contracts",
  "marketType": "MutuallyExclusiveWinner"
}
POST /api/scanner/progress

Report scan progress. Forwarded to all connected SignalR clients.

Request:
{
  "seriesProcessed": 150,
  "totalSeries": 7403,
  "marketsProcessed": 4500,
  "eventsProcessed": 1200,
  "opportunitiesFound": 3,
  "currentSeries": "KXSENATE",
  "isScanning": true,
  "lastUpdate": "2024-01-15T12:00:00Z"
}
POST /api/scanner/event

Report a processed event. Forwarded to SignalR clients for real-time display.

Request:
{
  "series": "KXSENATE",
  "event": "KXSENATE-AZ-26",
  "legCount": 3,
  "sumBids": 0.98,
  "sumAsks": 1.02,
  "profit": -0.02,
  "tradeType": "BUY-ALL-YES",
  "isArbitrage": false,
  "isMutuallyExclusive": true,
  "buyAllYesAllowed": true,
  "sellAllYesAllowed": true,
  "classificationReason": "APPROVED: Winner language detected",
  "timestamp": "2024-01-15T12:00:00Z"
}
POST /api/scanner/results

Post arbitrage results. Call periodically during scan and at end. Forwarded to SignalR clients.

Request:
[
  {
    "event": "KXSENATE-AZ-26",
    "series": "KXSENATE",
    "profit": 0.0312,
    "edgePercent": 3.12,
    "totalLiquidity": 15000,
    "legCount": 3,
    "tradeType": "BUY-ALL-YES",
    "detectedAt": "2024-01-15T12:00:00Z",
    "score": 0.125,
    "isMutuallyExclusive": true,
    "marketType": "MutuallyExclusiveWinner",
    "classificationReason": "APPROVED: Winner language detected",
    "category": 1
  },
  ...
]
GET /api/scanner/health

Health check endpoint.

Response:
{
  "status": "ok",
  "timestamp": "2024-01-15T12:00:00Z",
  "mode": "Research"
}

Scanner Console App Configuration

Configure the scanner's appsettings.json with the web app URL:

{
  "WebApi": {
    "BaseUrl": "https://localhost:7257"
  }
}
An unhandled error has occurred. Reload 🗙