Assymetrix Launches the Deepest Independent Prediction Market Data APIs
Read more
Read more
Assymetrix Launches the Deepest Independent Prediction Market Data APIs
Read more
Read more
Outcome Mapping Across Prediction Markets: A Developer Guide
Outcome Mapping Across Prediction Markets: A Developer Guide
Outcome Mapping Across Prediction Markets: A Developer Guide
How to map the same outcome across Polymarket, Kalshi and Limitless: identifiers, rule-text matching, confidence gates and the failure modes that cost money.

Outcome Mapping Across Prediction Markets: A Developer Guide
Outcome mapping in prediction markets means deciding that a specific outcome on one venue is the same bet as a specific outcome on another, then storing that decision so your code can rely on it. No two venues share an identifier, so every mapping is a judgment, and a wrong one turns an apparent arbitrage into a loss. This guide covers what to key on, what to match on, how to score confidence, and how to keep the mapping auditable.
AssymetrixBuild on Unified Market DataAccess structured prediction market data across Polymarket, Kalshi, and Limitless through a single Data API integration.Explore the Data API
TL;DR
Key every outcome as a venue-scoped tuple (venue, market, side), never as a bare title or a bare Yes/No label.
Match on rule text, settlement source, UTC close time and fallback clause. Titles mislead.
Map at the question level, not the event level, because one event can hold many independently resolving questions.
Gate real-money execution on a high match confidence, and treat a false positive as the costliest failure.
Store each mapping with its evidence and a reviewer, so a match can be audited and reversed.
Table of Contents
What an outcome map actually is
Start with identifiers, but do not stop there
The canonical layer
Match at the question level
What to match on
A tiered matching pipeline
Validate the spread before you trust the map
Our perspective
Put the map to work
A practical checklist
Sources
What an outcome map actually is
A prediction market contract is a binary claim with a price between 0 and 1 that reads as a probability. Polymarket, Kalshi and Limitless each model that claim differently. The same real-world question, say whether a central bank cuts rates at a given meeting, can exist on all three with different titles, different resolution wording, different close times and different identifier schemes.
An outcome map is the table that says which of those contracts are equivalent. Each row links a canonical outcome to one or more venue-native outcomes, along with the evidence for the link. Everything downstream depends on it: cross-venue price comparison, arbitrage scanning, divergence signals, backtests, and any agent that reads “the market’s probability” from more than one place.
It is also the least glamorous part of the stack, which is why it is where pipelines quietly break.
Start with identifiers, but do not stop there
The first layer is mechanical. Each venue gives you native identifiers, and your schema needs to hold them without collisions.
Polymarket identifies a market by a condition ID, and each side of a binary market trades as its own token with its own token ID.
Kalshi identifies a market by ticker. The Yes and No labels repeat across every market, so a bare “yes” tells you nothing. The outcome is only unique once you combine the market ticker with the side.
Limitless has its own market and outcome identifiers, which should be stored in the same venue-scoped way.
The common mistake is migrating from Polymarket’s unique-token model to Kalshi and assuming a side label identifies an outcome. It does not. Model the key as (venue, market_id, side) from day one, and normalize prices to the probability of Yes so that a Kalshi No at 0.37 and a Polymarket Yes at 0.63 can be compared on the same axis.
This layer only solves collisions inside your own database. It says nothing about whether two contracts on different venues are the same bet. For that you need a canonical layer on top, which is the subject of our guide to canonical IDs for cross-venue prediction market data.
The canonical layer
A canonical event or canonical outcome is an ID you mint (or receive from a data provider) that groups equivalent venue-native contracts. The structure is simple:
Layer | Example key | Purpose |
|---|---|---|
Venue-native outcome | (kalshi, ticker, yes) | Exactly what the venue trades |
Canonical question | canonical_question_id | The bet itself, independent of venue |
Mapping record | question_id, venue outcome, confidence, evidence, reviewer, timestamp | Why you believe the link holds |
The third row is the one teams skip. A mapping without evidence is an assertion you cannot defend when a position goes wrong.
Match at the question level
Event-level matching is too coarse. One event, such as an election night or a monthly economic release, can contain many tradable questions, and matching must happen at the question or submarket level to avoid grouping contracts that resolve independently.
Consider a monthly inflation release. One venue may list a ladder of thresholds, each its own binary market. Another may list a single multi-bracket market. “Same event” is true, but the contracts are not interchangeable until you align each threshold, each bracket boundary, and whether the boundary is inclusive.
Practical rule: if you cannot name the single sentence that resolves both contracts identically, do not map them.
What to match on
The same guidance on matching a question across venues frames the job as a judgment, not a purely technical join, and recommends comparing four things instead of titles, which can be deceptive.
Rule text. Read the resolution criteria on both sides. Look for differences in thresholds, inclusive versus exclusive bounds, and what counts as the event occurring.
Settlement source. If one venue settles on an official statistical release and another on a news report or a specific website, the two can diverge even when the title is identical.
UTC close time. Convert every close time to UTC. Two contracts closing hours apart can resolve differently if the underlying situation is still moving.
Fallback clause. What happens if the source is unavailable, the event is postponed, or the result is disputed? Different fallbacks produce different payouts in exactly the cases where you most need them to agree.
Add a fifth in practice: contract structure. Some venues frame the complement of what another venue lists. A “Will X not happen” contract maps to the No side of “Will X happen”, not the Yes side. Your mapping record should store a polarity flag so the flip is explicit instead of implied.
A worked example of a near miss
Suppose two venues both list a question about a government announcement by a given date.
Venue A resolves on the first official publication on a named agency site, closing at 23:59 UTC.
Venue B resolves on any credible report of the announcement, closing at midnight US Eastern.
The titles are nearly identical and the prices differ by six points. That gap looks like an opportunity. But the close times are hours apart and the settlement sources differ, so a leak reported on the final evening could pay out on B and not on A. The six points may be the market pricing exactly that difference. The right mapping outcome here is “related, not equivalent”, and your system should have that status available instead of forcing a yes or no.
A tiered matching pipeline
For more than a handful of markets, you need automation that proposes candidates and humans or verifiers that confirm them. Open-source projects in this area converge on a similar shape.
One open-source arbitrage dashboard project describes a multi-tier approach: keyword similarity, embedding search to discover candidates, then an LLM verification step to handle framing differences such as complementary contract structures and differing resolution definitions. Its authors treat false positives as a high-risk failure, which is the right posture.
A second open-source project, a GPU-accelerated semantic matching pipeline, uses retrieve-then-rerank with embeddings and a cross-encoder. Its team reports that matching can find equivalent contracts accurately, but that spread economics in currently fragmented markets often do not support profitable execution at scale.
Both findings matter for how you build:
Recall is cheap, precision is expensive. Let the retrieval stage be generous and make verification strict.
Accurate matching does not guarantee an edge. A perfect map of equivalent contracts still has to survive fees and liquidity.
Confidence gates
Store a numeric confidence with every mapping and use different thresholds for different actions. Some data providers that publish canonical events advise gating real-money execution on high match scores, typically 0.95 or above, as their canonical event documentation describes. A sensible scheme:
Confidence | Use |
|---|---|
Below 0.80 | Discard or send to review. Never display as a match. |
0.80 to 0.95 | Show on dashboards and research views, flagged as unverified. |
0.95 and above, with rule-text review | Eligible for signals and paper trading. |
Human-confirmed | Eligible for live execution. |
The numbers are starting points, not laws. Calibrate them against your own reviewed set: sample matches at each score band, check them by hand, and measure the actual false-positive rate.
Validate the spread before you trust the map
A correct mapping is necessary for arbitrage, not sufficient. The EdgeTerminal-style analysis in the same open-source project points out that apparent spreads often vanish because of thin liquidity, and that mismatched contract wording can cause significant losses. It argues for fee-adjusted lifecycle tracking, from detected to expired, so profit and loss can be verified rather than assumed.
A minimal validation pass after a mapping passes the gate:
Pull top-of-book depth on both venues and size the trade to what the book can fill, not to the displayed best price.
Subtract each venue’s fees and any funding or withdrawal friction.
Check that both contracts are still open and close inside your holding assumptions.
Log the opportunity with a state (detected, executed, expired) and the evidence you used.
That last step is a habit worth borrowing from other forecasting work: decision logging and scoring lets you compare what you expected with what happened, which is how you find out whether your mapping and spread filters are any good. For the liquidity side, see our notes on prediction market liquidity metrics and the arbitrage strategy guide.
Our perspective
We build a venue-neutral data layer across Polymarket, Kalshi and Limitless, so outcome mapping is not an abstract topic for us. It is the join that every cross-venue product depends on, from arbitrage signals to market divergence analysis.
Three convictions shape how we think about it.
First, the mapping is data, not code. It should live in a versioned table with evidence, confidence and a status, so you can ask what you believed on a given date. That matters for backtests: if you map today’s markets with today’s knowledge and apply the result to history, you leak information.

Second, “not the same” is a valid answer, and “related” is a useful one. Forcing every pair into equivalent or unrelated hides the near misses where most of the losses live.
Third, a single normalized schema across venues removes a whole class of integration work. Rebuilding three feeds and three identifier systems for every project is wasted effort when the unit you care about is the outcome. That is the idea behind our cross-venue signal generation guide and the unified data layer.
— Dean
Put the map to work
If you would rather not maintain identifier normalization yourself, our Data API exposes cross-venue prediction market data for Polymarket, Kalshi and Limitless through one integration, built on roughly 1.5 terabytes of historical data. The REST and WebSocket guide shows the integration shape, and the Python walkthrough gets you to a first query.
A practical checklist
Store (venue, market_id, side) for every outcome, plus raw rule text and a hash of it.
Convert all times to UTC and store the settlement source as a field you can compare.
Store polarity for complementary contracts.
Record a status of equivalent, related or distinct, never just a boolean.
Save evidence, confidence, reviewer and timestamp on every mapping.
Re-check mappings when a venue amends rules, since the text you matched on may have changed.
Version the table so backtests use only what was known at the time.
Track false positives as a metric and review each one.
FAQ
What is outcome mapping in prediction markets?
It is the process of linking equivalent outcomes across venues, for example the Yes side of a question on Kalshi and the matching token on Polymarket, under one canonical ID. Each link should carry evidence, a confidence score and a polarity flag. It is the foundation of cross-venue comparison and arbitrage.
Can I match markets by title alone?
No. Titles can be deceptive, and identical wording can sit on top of different settlement sources, close times or fallback clauses. Compare the rule text, the settlement source, the UTC close time and the fallback clause before treating two contracts as the same bet.
Should I use embeddings or an LLM to match markets?
Use them to propose candidates, not to approve live trades on their own. Open-source pipelines combine embedding search with LLM or cross-encoder verification, but they still treat false positives as the main risk. Keep a human review step for anything that will carry real money.
Does a correct mapping mean an arbitrage is profitable?
No. Spreads often disappear once you account for thin liquidity and fees. Size against actual book depth, subtract costs, and track each opportunity from detection to expiry.
Sources
Outcome Mapping Across Prediction Markets: A Developer Guide
Outcome mapping in prediction markets means deciding that a specific outcome on one venue is the same bet as a specific outcome on another, then storing that decision so your code can rely on it. No two venues share an identifier, so every mapping is a judgment, and a wrong one turns an apparent arbitrage into a loss. This guide covers what to key on, what to match on, how to score confidence, and how to keep the mapping auditable.
AssymetrixBuild on Unified Market DataAccess structured prediction market data across Polymarket, Kalshi, and Limitless through a single Data API integration.Explore the Data API
TL;DR
Key every outcome as a venue-scoped tuple (venue, market, side), never as a bare title or a bare Yes/No label.
Match on rule text, settlement source, UTC close time and fallback clause. Titles mislead.
Map at the question level, not the event level, because one event can hold many independently resolving questions.
Gate real-money execution on a high match confidence, and treat a false positive as the costliest failure.
Store each mapping with its evidence and a reviewer, so a match can be audited and reversed.
Table of Contents
What an outcome map actually is
Start with identifiers, but do not stop there
The canonical layer
Match at the question level
What to match on
A tiered matching pipeline
Validate the spread before you trust the map
Our perspective
Put the map to work
A practical checklist
Sources
What an outcome map actually is
A prediction market contract is a binary claim with a price between 0 and 1 that reads as a probability. Polymarket, Kalshi and Limitless each model that claim differently. The same real-world question, say whether a central bank cuts rates at a given meeting, can exist on all three with different titles, different resolution wording, different close times and different identifier schemes.
An outcome map is the table that says which of those contracts are equivalent. Each row links a canonical outcome to one or more venue-native outcomes, along with the evidence for the link. Everything downstream depends on it: cross-venue price comparison, arbitrage scanning, divergence signals, backtests, and any agent that reads “the market’s probability” from more than one place.
It is also the least glamorous part of the stack, which is why it is where pipelines quietly break.
Start with identifiers, but do not stop there
The first layer is mechanical. Each venue gives you native identifiers, and your schema needs to hold them without collisions.
Polymarket identifies a market by a condition ID, and each side of a binary market trades as its own token with its own token ID.
Kalshi identifies a market by ticker. The Yes and No labels repeat across every market, so a bare “yes” tells you nothing. The outcome is only unique once you combine the market ticker with the side.
Limitless has its own market and outcome identifiers, which should be stored in the same venue-scoped way.
The common mistake is migrating from Polymarket’s unique-token model to Kalshi and assuming a side label identifies an outcome. It does not. Model the key as (venue, market_id, side) from day one, and normalize prices to the probability of Yes so that a Kalshi No at 0.37 and a Polymarket Yes at 0.63 can be compared on the same axis.
This layer only solves collisions inside your own database. It says nothing about whether two contracts on different venues are the same bet. For that you need a canonical layer on top, which is the subject of our guide to canonical IDs for cross-venue prediction market data.
The canonical layer
A canonical event or canonical outcome is an ID you mint (or receive from a data provider) that groups equivalent venue-native contracts. The structure is simple:
Layer | Example key | Purpose |
|---|---|---|
Venue-native outcome | (kalshi, ticker, yes) | Exactly what the venue trades |
Canonical question | canonical_question_id | The bet itself, independent of venue |
Mapping record | question_id, venue outcome, confidence, evidence, reviewer, timestamp | Why you believe the link holds |
The third row is the one teams skip. A mapping without evidence is an assertion you cannot defend when a position goes wrong.
Match at the question level
Event-level matching is too coarse. One event, such as an election night or a monthly economic release, can contain many tradable questions, and matching must happen at the question or submarket level to avoid grouping contracts that resolve independently.
Consider a monthly inflation release. One venue may list a ladder of thresholds, each its own binary market. Another may list a single multi-bracket market. “Same event” is true, but the contracts are not interchangeable until you align each threshold, each bracket boundary, and whether the boundary is inclusive.
Practical rule: if you cannot name the single sentence that resolves both contracts identically, do not map them.
What to match on
The same guidance on matching a question across venues frames the job as a judgment, not a purely technical join, and recommends comparing four things instead of titles, which can be deceptive.
Rule text. Read the resolution criteria on both sides. Look for differences in thresholds, inclusive versus exclusive bounds, and what counts as the event occurring.
Settlement source. If one venue settles on an official statistical release and another on a news report or a specific website, the two can diverge even when the title is identical.
UTC close time. Convert every close time to UTC. Two contracts closing hours apart can resolve differently if the underlying situation is still moving.
Fallback clause. What happens if the source is unavailable, the event is postponed, or the result is disputed? Different fallbacks produce different payouts in exactly the cases where you most need them to agree.
Add a fifth in practice: contract structure. Some venues frame the complement of what another venue lists. A “Will X not happen” contract maps to the No side of “Will X happen”, not the Yes side. Your mapping record should store a polarity flag so the flip is explicit instead of implied.
A worked example of a near miss
Suppose two venues both list a question about a government announcement by a given date.
Venue A resolves on the first official publication on a named agency site, closing at 23:59 UTC.
Venue B resolves on any credible report of the announcement, closing at midnight US Eastern.
The titles are nearly identical and the prices differ by six points. That gap looks like an opportunity. But the close times are hours apart and the settlement sources differ, so a leak reported on the final evening could pay out on B and not on A. The six points may be the market pricing exactly that difference. The right mapping outcome here is “related, not equivalent”, and your system should have that status available instead of forcing a yes or no.
A tiered matching pipeline
For more than a handful of markets, you need automation that proposes candidates and humans or verifiers that confirm them. Open-source projects in this area converge on a similar shape.
One open-source arbitrage dashboard project describes a multi-tier approach: keyword similarity, embedding search to discover candidates, then an LLM verification step to handle framing differences such as complementary contract structures and differing resolution definitions. Its authors treat false positives as a high-risk failure, which is the right posture.
A second open-source project, a GPU-accelerated semantic matching pipeline, uses retrieve-then-rerank with embeddings and a cross-encoder. Its team reports that matching can find equivalent contracts accurately, but that spread economics in currently fragmented markets often do not support profitable execution at scale.
Both findings matter for how you build:
Recall is cheap, precision is expensive. Let the retrieval stage be generous and make verification strict.
Accurate matching does not guarantee an edge. A perfect map of equivalent contracts still has to survive fees and liquidity.
Confidence gates
Store a numeric confidence with every mapping and use different thresholds for different actions. Some data providers that publish canonical events advise gating real-money execution on high match scores, typically 0.95 or above, as their canonical event documentation describes. A sensible scheme:
Confidence | Use |
|---|---|
Below 0.80 | Discard or send to review. Never display as a match. |
0.80 to 0.95 | Show on dashboards and research views, flagged as unverified. |
0.95 and above, with rule-text review | Eligible for signals and paper trading. |
Human-confirmed | Eligible for live execution. |
The numbers are starting points, not laws. Calibrate them against your own reviewed set: sample matches at each score band, check them by hand, and measure the actual false-positive rate.
Validate the spread before you trust the map
A correct mapping is necessary for arbitrage, not sufficient. The EdgeTerminal-style analysis in the same open-source project points out that apparent spreads often vanish because of thin liquidity, and that mismatched contract wording can cause significant losses. It argues for fee-adjusted lifecycle tracking, from detected to expired, so profit and loss can be verified rather than assumed.
A minimal validation pass after a mapping passes the gate:
Pull top-of-book depth on both venues and size the trade to what the book can fill, not to the displayed best price.
Subtract each venue’s fees and any funding or withdrawal friction.
Check that both contracts are still open and close inside your holding assumptions.
Log the opportunity with a state (detected, executed, expired) and the evidence you used.
That last step is a habit worth borrowing from other forecasting work: decision logging and scoring lets you compare what you expected with what happened, which is how you find out whether your mapping and spread filters are any good. For the liquidity side, see our notes on prediction market liquidity metrics and the arbitrage strategy guide.
Our perspective
We build a venue-neutral data layer across Polymarket, Kalshi and Limitless, so outcome mapping is not an abstract topic for us. It is the join that every cross-venue product depends on, from arbitrage signals to market divergence analysis.
Three convictions shape how we think about it.
First, the mapping is data, not code. It should live in a versioned table with evidence, confidence and a status, so you can ask what you believed on a given date. That matters for backtests: if you map today’s markets with today’s knowledge and apply the result to history, you leak information.

Second, “not the same” is a valid answer, and “related” is a useful one. Forcing every pair into equivalent or unrelated hides the near misses where most of the losses live.
Third, a single normalized schema across venues removes a whole class of integration work. Rebuilding three feeds and three identifier systems for every project is wasted effort when the unit you care about is the outcome. That is the idea behind our cross-venue signal generation guide and the unified data layer.
— Dean
Put the map to work
If you would rather not maintain identifier normalization yourself, our Data API exposes cross-venue prediction market data for Polymarket, Kalshi and Limitless through one integration, built on roughly 1.5 terabytes of historical data. The REST and WebSocket guide shows the integration shape, and the Python walkthrough gets you to a first query.
A practical checklist
Store (venue, market_id, side) for every outcome, plus raw rule text and a hash of it.
Convert all times to UTC and store the settlement source as a field you can compare.
Store polarity for complementary contracts.
Record a status of equivalent, related or distinct, never just a boolean.
Save evidence, confidence, reviewer and timestamp on every mapping.
Re-check mappings when a venue amends rules, since the text you matched on may have changed.
Version the table so backtests use only what was known at the time.
Track false positives as a metric and review each one.
FAQ
What is outcome mapping in prediction markets?
It is the process of linking equivalent outcomes across venues, for example the Yes side of a question on Kalshi and the matching token on Polymarket, under one canonical ID. Each link should carry evidence, a confidence score and a polarity flag. It is the foundation of cross-venue comparison and arbitrage.
Can I match markets by title alone?
No. Titles can be deceptive, and identical wording can sit on top of different settlement sources, close times or fallback clauses. Compare the rule text, the settlement source, the UTC close time and the fallback clause before treating two contracts as the same bet.
Should I use embeddings or an LLM to match markets?
Use them to propose candidates, not to approve live trades on their own. Open-source pipelines combine embedding search with LLM or cross-encoder verification, but they still treat false positives as the main risk. Keep a human review step for anything that will carry real money.
Does a correct mapping mean an arbitrage is profitable?
No. Spreads often disappear once you account for thin liquidity and fees. Size against actual book depth, subtract costs, and track each opportunity from detection to expiry.
Sources
Other Blog



