Overview
Predexon 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 is LLM-based , using a knowledge graph built from:
Event metadata and descriptions
Resolution criteria
Time constraints
Semantic similarity
LLM-Based Matching Limitations : Because market matching relies on large language models (LLMs), there is a small percentage of markets where hallucinations may occur, resulting in invalid or incorrect market matches. Always verify matches before making trading decisions, especially for high-stakes arbitrage opportunities.
Match Types
Type Description Similarity Score Exact Same underlying event with equivalent or near-equivalent resolution criteria >= 95 Related Similar events or correlated outcomes (same entity different outcome, or same event different candidate) 80 - 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 } /v2/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 } /v2/matching-markets" ,
params = { "kalshi_market_ticker" : "KXPERFORMGRAMMYS-26-CHA" }
)
data = response.json()
for match in data[ 'matches' ][ 'POLYMARKET' ][ 'exact' ]:
print ( f " { match[ 'title' ] } " )
print ( f " Condition ID: { match[ 'condition_id' ] } " )
print ( f " Slug: { match[ 'market_slug' ] } " )
print ( f " Explanation: { match[ 'explanation' ] } " )
print ( f " Similarity: { match[ 'similarity' ] } " )
Response Structure
{
"query" : {
"platform" : "KALSHI" ,
"market_ticker" : "KXPERFORMGRAMMYS-26-CHA" ,
"title" : "Who will perform at the 68th Grammy Awards?" ,
"yes_subtitle" : "Chappell Roan" ,
"status" : "active"
},
"matches" : {
"POLYMARKET" : {
"exact" : [
{
"condition_id" : "0x6f14e52f..." ,
"market_slug" : "will-chappell-roan-perform-at-the-2026-grammy-awards" ,
"market_id" : "1137275" ,
"title" : "Will Chappell Roan perform at the 2026 Grammy Awards?" ,
"status" : "active" ,
"similarity" : 96 ,
"explanation" : "..."
}
],
"related" : []
}
},
"summary" : {
"total_matches" : 1 ,
"exact_matches" : 1 ,
"related_matches" : 0 ,
"platforms" : [ "POLYMARKET" ]
}
}
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 } /v2/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 } /v2/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 } /v2/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 } /v2/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 } /v2/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