Real-time liquidity anomaly scanner for all active Polymarket prediction markets.
Every 60 seconds, the scanner inspects every order book on Polymarket, detects thin books / depth surges / mean-reversion setups, and returns actionable trade recommendations that AI agents can consume as direct if-conditions in their trading logic.
x402 paywall — micropayments on Base mainnet (USDC).
Cloudflare Cron (every 60 s)
│
├─ 1. Fetch all active markets ← Gamma API (paginated)
├─ 2. Fetch order books in 10-chunks ← CLOB API
├─ 3. Diff against previous depths ← KV read (prev_depths)
├─ 4. Score & classify anomalies
├─ 5. Single KV PUT → SCAN_KV
└─ 6. R2 PUT (lightweight snapshot) → SCAN_R2
│ │
HTTP GET /scan/liquidity-anomaly ──────────┘ │
(x402 $0.018 → KV read → filter → respond) │
│
HTTP GET /scan/history ───────────────────────┘
(x402 $0.005 → R2 list+get → filter → respond)
The Cron trigger runs the full pipeline and writes the result to Cloudflare KV as a single JSON blob. The HTTP endpoint is a pure KV read — no computation at request time, no cold starts, sub-millisecond latency.
Stack: Cloudflare Workers + Cron Triggers + KV + R2 + Service Bindings
| Endpoint | Price | Description |
|---|---|---|
GET /scan/liquidity-anomaly |
$0.018 USDC/req | Latest scan snapshot (real-time) |
GET /scan/history |
$0.005 USDC/req | Time-series history (up to 24h) |
Requires an X-Payment header with a valid x402 payment proof ($0.018 USDC on Base).
| Parameter | Type | Default | Description |
|---|---|---|---|
min_score |
float | 0.7 |
Minimum opportunity score (0–1). Use 0.8 for high-confidence signals. |
limit |
integer | 10 |
Number of opportunities to return (1–20). |
direction |
string | both |
Filter by anomaly type: thin, surge, or both. |
{
"scanned_at": "2025-06-15T12:00:05.123Z",
"last_update_id": "1718452805123",
"total_markets_scanned": 342,
"cache_age_seconds": 18,
"opportunities": [
{
"conditionId": "0xabc123...",
"title": "Will Bitcoin reach $100k by July 2025?",
"opportunity_type": "thin_book",
"opportunity_score": 0.92,
"trade_recommendation": {
"action": "AVOID_ENTRY",
"confidence": 0.92,
"reason": "spread_too_wide",
"expected_condition": "spread_widen",
"time_to_decay_seconds": 45,
"urgency_level": "medium"
},
"current_spread": 0.0823,
"depth_delta_60s": -1250.50,
"liquidity_usd": 3200.00,
"is_scaling_up": false,
"polymarket_url": "https://polymarket.com/event/bitcoin-100k-july"
}
]
}Requires an X-Payment header with a valid x402 payment proof ($0.005 USDC on Base).
Returns time-series scan snapshots stored in R2. Each Cron cycle (every 60 s) writes a lightweight snapshot, enabling trend analysis and historical anomaly tracking.
| Parameter | Type | Default | Description |
|---|---|---|---|
hours |
integer | 1 |
How many hours of history to retrieve (1–24). |
limit |
integer | 10 |
Maximum number of scan snapshots to return (1–60). |
min_score |
float | 0 |
Minimum opportunity score filter (0–1). |
{
"period_hours": 1,
"data_points": 3,
"scans": [
{
"scanned_at": "2025-06-15T12:00:05.123Z",
"total_markets_scanned": 342,
"opportunity_count": 5,
"top_opportunities": [
{
"conditionId": "0xabc123...",
"title": "Will Bitcoin reach $100k by July 2025?",
"opportunity_type": "thin_book",
"opportunity_score": 0.92,
"trade_recommendation": {
"action": "AVOID_ENTRY",
"confidence": 0.92,
"reason": "spread_too_wide",
"expected_condition": "spread_widen",
"time_to_decay_seconds": 45,
"urgency_level": "medium"
},
"current_spread": 0.0823,
"depth_delta_60s": -1250.50,
"liquidity_usd": 3200.00,
"is_scaling_up": false,
"polymarket_url": "https://polymarket.com/event/bitcoin-100k-july"
}
]
},
{
"scanned_at": "2025-06-15T11:59:04.456Z",
"total_markets_scanned": 342,
"opportunity_count": 3,
"top_opportunities": []
}
]
}- Trend detection: Track how a market's liquidity evolves over the past hour before entering a position.
- Backtesting signals: Compare anomaly scores across multiple scan cycles to validate signal persistence.
- Alert correlation: Cross-reference anomaly timestamps with external events (news, whale trades).
Each opportunity includes a trade_recommendation object designed to be consumed directly as control flow in agent trading logic.
| Value | Meaning | Agent behavior |
|---|---|---|
AVOID_ENTRY |
Order book is thin, spread is wide | Do not enter a position |
MONITOR |
Liquidity is flowing in (surge detected) | Watch for stabilization |
CONSIDER_ENTRY |
Mean reversion setup detected | Entry may be favorable |
| Field | Description |
|---|---|
confidence |
0–1, same value as opportunity_score |
reason |
Why: spread_too_wide / liquidity_inflow / mean_reversion_setup |
expected_condition |
What comes next: spread_widen / liquidity_inflow / mean_reversion |
time_to_decay_seconds |
Estimated seconds before the anomaly dissipates |
urgency_level |
high (< 30 s), medium (< 90 s), low (≥ 90 s) |
opportunity_score = min(1.0, (|depth_delta_60s| / prev_depth) * 2)
depth_delta_60s= current total order book depth − previous depth (from KV)prev_depth= total depth recorded on the previous Cron cycle (60 s ago)- Score is clamped to
[0, 1] - A 50% depth change in 60 seconds yields a score of
1.0
| Score | Signal strength | Suggested action |
|---|---|---|
| > 0.9 | Extreme anomaly | Immediate attention required |
| 0.8 – 0.9 | Strong signal | Act within time_to_decay |
| 0.7 – 0.8 | Moderate signal | Monitor, recheck in 60 s |
| < 0.7 | Noise (filtered out) | Ignore |
import { x402 } from "x402-next";
const client = x402({
network: "base",
// wallet or payment provider config
});
const res = await client.get(
"https://polymarket-scan-api.tatsu77.workers.dev/scan/liquidity-anomaly",
{ params: { min_score: 0.8, limit: 5, direction: "both" } }
);
for (const opp of res.data.opportunities) {
const { action } = opp.trade_recommendation;
if (action === "AVOID_ENTRY") {
console.log(`SKIP ${opp.title} — spread too wide`);
} else if (action === "CONSIDER_ENTRY") {
console.log(`ENTRY CANDIDATE ${opp.title} — score ${opp.opportunity_score}`);
// Step 2: deep dive with polymarket-liquidity-api
}
}- Step 1 — Scan (this API):
GET /scan/liquidity-anomaly?min_score=0.7→ Get a list of markets with liquidity anomalies and trade recommendations. - Step 2 — Deep dive (
polymarket-liquidity-api): For any interestingconditionId, call the companion API to get the full order book snapshot, detailed spread analysis, and depth-at-price data.
| Path | Description |
|---|---|
GET / |
Service metadata (JSON) |
GET /.well-known/x402 |
x402 payment metadata |
GET /openapi.json |
OpenAPI 3.0 spec |
GET /llms.txt |
LLM-optimized API documentation |
POST /mcp |
MCP Streamable HTTP (discovery-only) |
| Variable | Where | Description |
|---|---|---|
PAY_TO_ADDRESS |
wrangler.toml or .dev.vars |
USDC receive address for x402 payments |
SCAN_KV |
KV namespace binding | Cloudflare KV for scan result storage |
SCAN_R2 |
R2 bucket binding | Cloudflare R2 for time-series scan history |
LIQUIDITY_API |
Service binding | Reference to polymarket-liquidity-api worker |
npm install
npm run dev # wrangler dev (local)
npm run deploy # wrangler deploy (production)
npm run typecheck # tsc --noEmitISC