Overview
Predexon’s market matching API helps you discover equivalent or related markets across different prediction market platforms. This is invaluable for:
- Arbitrage detection: Find price discrepancies for the same event
- Portfolio diversification: Spread risk across platforms
- Research: Compare market efficiency across platforms
- Liquidity analysis: Find the best platform for a given market
How Matching Works
Our matching algorithm uses a knowledge graph built from:
- Event metadata and descriptions
- Resolution criteria
- Time constraints
- Semantic similarity
Match Types
| Type | Description | Similarity Score |
|---|
| Exact | Same underlying event with identical resolution criteria — will always resolve identically | >= 0.95 |
| Related | Similar events or correlated outcomes (same entity different outcome, or same event different candidate) | 0.90 - 0.95 |
The similarity field may be null for matches created before January 4th, 2025.
Finding Matches
From Polymarket to Kalshi
import requests
BASE_URL = "https://api.predexon.com"
response = requests.get(
f"{BASE_URL}/v1/matching-markets",
params={"polymarket_market_slug": "will-the-carolina-hurricanes-win-the-metropolitan-division-123"}
)
data = response.json()
print(f"Query: {data['query']['title']}")
print(f"Total matches: {data['summary']['total_matches']}")
for match in data['matches']['KALSHI']['exact']:
print(f" Exact: {match['title']}")
print(f" Ticker: {match['market_ticker']}")
print(f" Explanation: {match['explanation']}")
print(f" Similarity: {match['similarity']}")
for match in data['matches']['KALSHI']['related']:
print(f" Related: {match['title']}")
print(f" Explanation: {match['explanation']}")
From Kalshi to Polymarket
response = requests.get(
f"{BASE_URL}/v1/matching-markets",
params={"kalshi_market_ticker": "KXNHLMETROPOLITAN-26-CAR"}
)
data = response.json()
for match in data['matches']['POLYMARKET']['exact']:
print(f" {match['title']}")
print(f" Slug: {match['market_slug']}")
print(f" Explanation: {match['explanation']}")
print(f" Similarity: {match['similarity']}")
Response Structure
{
"query": {
"platform": "KALSHI",
"market_ticker": "KXNHLMETROPOLITAN-26-CAR",
"title": "Will Carolina Hurricanes win the NHL Metropolitan Division?",
"yes_subtitle": "Carolina Hurricanes",
"status": "active"
},
"matches": {
"POLYMARKET": {
"exact": [
{
"market_slug": "will-the-carolina-hurricanes-win-the-metropolitan-division-123",
"title": "Will the Carolina Hurricanes win the Metropolitan Division?",
"status": "active",
"explanation": "Same entity (Carolina Hurricanes), same outcome (win the 2025–26 NHL Metropolitan Division), same timeframe (2025–26 regular season) — will always resolve identically.",
"similarity": 0.97
}
],
"related": [
{
"market_slug": "will-the-carolina-hurricanes-win-the-2026-nhl-stanley-cup",
"title": "Will the Carolina Hurricanes win the 2026 NHL Stanley Cup?",
"status": "active",
"explanation": "Same entity (Carolina Hurricanes) but different outcome/event (win the 2026 Stanley Cup vs win the 2025–26 Metropolitan Division).",
"similarity": 0.94
},
{
"market_slug": "will-the-new-jersey-devils-win-the-metropolitan-division-424",
"title": "Will the New Jersey Devils win the Metropolitan Division?",
"status": "active",
"explanation": "Same event (which team wins the 2025–26 Metropolitan Division) but different candidate/team (New Jersey Devils vs Carolina Hurricanes) — competitive and thus correlated.",
"similarity": 0.92
}
]
}
},
"summary": {
"total_matches": 3,
"exact_matches": 1,
"related_matches": 2,
"platforms": ["POLYMARKET"]
}
}
Batch Matching
For efficiency, query multiple markets at once:
response = requests.get(
f"{BASE_URL}/v1/matching-markets/batch",
params={
"polymarket_market_slugs": [
"will-donald-trump-win-the-2024-us-presidential-election",
"will-fed-cut-rates-january",
"will-btc-hit-100k"
]
}
)
data = response.json()
for slug, result in data['markets'].items():
print(f"\n{slug}:")
print(f" Matches: {result['summary']['total_matches']}")
Arbitrage Detection Example
def find_arbitrage_opportunities():
"""Find markets with significant price differences across platforms."""
# Get top Polymarket markets
pm_response = requests.get(
f"{BASE_URL}/v1/polymarket/markets",
params={"status": "open", "sort": "volume", "limit": 50}
)
opportunities = []
for market in pm_response.json()["markets"]:
# Find Kalshi matches
match_response = requests.get(
f"{BASE_URL}/v1/matching-markets",
params={"polymarket_market_slug": market["market_slug"]}
)
matches = match_response.json()
if matches["summary"]["exact_matches"] > 0:
pm_price = market["outcomes"][0]["price"] # Yes price
# Compare with Kalshi prices (would need Kalshi price API)
for kalshi_match in matches["matches"]["KALSHI"]["exact"]:
# Calculate price difference
# Note: You'd need to fetch Kalshi prices separately
opportunities.append({
"polymarket_slug": market["market_slug"],
"polymarket_price": pm_price,
"kalshi_ticker": kalshi_match["market_ticker"],
"title": market["title"]
})
return opportunities
Use Cases
Portfolio Hedging
def find_hedging_options(polymarket_slug: str):
"""Find related markets that could hedge a position."""
response = requests.get(
f"{BASE_URL}/v1/matching-markets",
params={"polymarket_market_slug": polymarket_slug}
)
matches = response.json()
# Related matches might offer hedging opportunities
hedges = []
for match in matches["matches"]["KALSHI"]["related"]:
hedges.append({
"ticker": match["market_ticker"],
"title": match["title"],
"explanation": match["explanation"],
"similarity": match["similarity"]
})
return hedges
Market Coverage Analysis
def analyze_market_coverage(category: str):
"""Analyze which markets exist on both platforms."""
# Get Polymarket markets in category
pm_response = requests.get(
f"{BASE_URL}/v1/polymarket/markets",
params={"status": "open", "tags": [category], "limit": 100}
)
coverage = {
"polymarket_only": 0,
"both_platforms": 0,
"markets": []
}
for market in pm_response.json()["markets"]:
match_response = requests.get(
f"{BASE_URL}/v1/matching-markets",
params={"polymarket_market_slug": market["market_slug"]}
)
if match_response.json()["summary"]["exact_matches"] > 0:
coverage["both_platforms"] += 1
else:
coverage["polymarket_only"] += 1
return coverage
Best Practices
Use batch endpoints for multiple lookups
Instead of making individual requests for each market, use the batch endpoint to reduce latency and API calls.
Market matches don’t change frequently. Cache results for at least 1 hour to reduce API usage.
Handle missing matches gracefully
Not all markets have cross-platform equivalents. Your code should handle empty match results.
Next Steps
Matching API
Full API reference