> ## Documentation Index
> Fetch the complete documentation index at: https://tonic-ai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Polymarket Surveillance Signals

> Configure Polymarket surveillance for insider-like decision support with baselines, signals, and alerts

Polymarket surveillance provides insider-like decision support: baselines, signals, and alerts derived from the Polymarket Data API. Access requires a Pro (or higher) subscription when `SURVEILLANCE_REQUIRES_PRO` is enabled.

***

## 1. Signals ↔ Endpoints

| Signal                               | PolymarketAPIClient method                        | Endpoint / params                                     | Derivation note                                                              |
| ------------------------------------ | ------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------- |
| `trade_count`                        | `fetch_trades`                                    | `GET /trades` (`market`, `asset_id`, `limit`)         | Count per wallet from `maker`/`taker`/`user`                                 |
| `first_seen_ts` (wallet)             | `fetch_activity`                                  | `GET /activity` (`user`, `market`, `limit`)           | Min timestamp; or from baseline `entity_type=wallet`, `metric=first_seen_ts` |
| `volume`                             | `fetch_live_volume`                               | `GET /markets/{id}/volume` or `/volume`               | Stored in baseline `entity_type=market`, `metric=volume`                     |
| `open_interest`                      | `fetch_open_interest`                             | `GET /markets/{id}/open-interest` or `/open-interest` | Stored in baseline `entity_type=market`, `metric=open_interest`              |
| `leaderboard_rank`                   | `fetch_leaderboard`                               | `GET /leaderboard` or `GET /analytics/leaderboard`    | Optional; `limit` for top N                                                  |
| `holders_count`                      | `fetch_holders`                                   | `GET /holders` (`token_id`, `limit`)                  | Per outcome token                                                            |
| `outsized_bet` (derived)             | `fetch_trades` + baselines                        | —                                                     | Trade count vs baseline volume; alert when threshold exceeded                |
| `new_wallet_anomaly` (derived)       | `fetch_activity` + `get_wallet_first_activity_ts` | —                                                     | New wallet with large activity                                               |
| `low_activity_market_move` (derived) | `fetch_trades` + `fetch_live_volume`              | —                                                     | Price move with low historical volume                                        |

***

## 2. Baseline schema

| Column        | Type        | Description                                                             |
| ------------- | ----------- | ----------------------------------------------------------------------- |
| `entity_type` | String(50)  | `"wallet"`, `"market"`, `"condition"`                                   |
| `entity_id`   | String(255) | Wallet address, market id, or condition id                              |
| `window`      | String(50)  | `"1d"`, `"7d"`, `"30d"`                                                 |
| `metric`      | String(100) | `"volume"`, `"trade_count"`, `"first_seen_ts"`, `"open_interest"`, etc. |
| `value`       | JSONB       | Numeric or object (e.g. timestamp, aggregate)                           |
| `computed_at` | DateTime    | When the baseline was last updated                                      |

Unique on `(entity_type, entity_id, window, metric)` for upsert.

***

## 3. Alert schema

| Column          | Type                        | Description                                                                  |
| --------------- | --------------------------- | ---------------------------------------------------------------------------- |
| `alert_type`    | String(100)                 | `"outsized_bet"`, `"new_wallet_anomaly"`, `"low_activity_market_move"`, etc. |
| `severity`      | String(20)                  | `"low"`, `"medium"`, `"high"`, `"critical"`                                  |
| `condition_id`  | String(255), nullable       | Related condition/market                                                     |
| `proxy_wallet`  | String(66), nullable        | Wallet involved                                                              |
| `event_id`      | String(255), nullable       | Related event                                                                |
| `signal_values` | JSONB, nullable             | Snapshot of signals that fired                                               |
| `message`       | Text                        | Human-readable description                                                   |
| `created_at`    | DateTime                    | When the alert was created                                                   |
| `reviewed_at`   | DateTime, nullable          | When it was reviewed                                                         |
| `reviewed_by`   | Integer, FK users, nullable | Reviewer user id                                                             |
| `resolution`    | String(50), nullable        | `"dismissed"`, `"escalated"`, `"false_positive"`                             |

***

## 4. Config

| Variable                                     | Description                                                               | Default                           |
| -------------------------------------------- | ------------------------------------------------------------------------- | --------------------------------- |
| `POLYMARKET_DATA_API_URL`                    | Data API base (trades, activity, leaderboard, volume, open-interest)      | `https://data-api.polymarket.com` |
| `POLYMARKET_SURVEILLANCE_ENABLED`            | Enable detection cycle (baselines, alerts)                                | `false`                           |
| `SURVEILLANCE_REQUIRES_PRO`                  | Require Pro (or higher) for surveillance routes                           | `true`                            |
| `REVENUECAT_ENTITLEMENT_MARKET_INTELLIGENCE` | Entitlement for surveillance; if unset, uses `REVENUECAT_ENTITLEMENT_PRO` | —                                 |

***

## 5. Usage

### Running the detection cycle

* **Cron / scheduled:** Call `POST /api/polymarket/surveillance/run-cycle` (requires Pro and `POLYMARKET_SURVEILLANCE_ENABLED=true`). Response: `{ "skipped" }` or `{ "baselines_updated", "alerts_created" }`.
* **Admin / UI:** Use the same endpoint from an admin or scheduled job. The `PolymarketSurveillanceService.run_detection_cycle(markets=...)` can be passed an optional list of market ids.

### Listing and reviewing alerts

* **List:** `GET /api/polymarket/surveillance/alerts?severity=...&reviewed=...&limit=50&offset=0`
* **Review:** `POST /api/polymarket/surveillance/alerts/{id}/review` with body `{ "resolution": "dismissed" | "escalated" | "false_positive" }`

The **Surveillance** section in the Polymarket Market Dashboard shows the `SurveillanceAlertsPanel`: it lists alerts, supports severity/reviewed filters, and a "Review" action with resolution dropdown. On 403 (subscription required), the panel shows an "Upgrade to Pro" CTA instead of the alerts table.
