A Betting Exchange Like Betfair on Your Own Data: How It Works and What You Need to Launch
How to build your own betting exchange on the Betfair model: how an exchange differs from a bookmaker, what data SportAPI provides, how to match back and lay bets, and where liquidity comes from on day one.

Your own betting exchange on the Betfair model has two layers: sports data and the exchange engine. The data — events, markets, live state, and suspended outcomes — and market settlement after the match come from SportAPI. The engine — the order book, back and lay matching, wallets, and commission — is built by your team or by SportAPI as part of turnkey platform development. Data for one sport costs from $30 a month, and SportAPI odds solve the biggest problem of a new exchange: empty markets at launch.
Below: how an exchange differs from a bookmaker, what it is made of, how to match bets, how to fill markets with liquidity from day one, and how to settle markets after the match.
How a betting exchange differs from a bookmaker
With a bookmaker, a player bets against the house at the house’s odds. On an exchange, players bet against each other: one backs an outcome, another lays it, and the exchange earns a commission on net winnings.
| Bookmaker | Betting exchange | |
|---|---|---|
| Who takes the bet | The house | Another player |
| Who sets the odds | The house, with a margin | Players, through orders |
| Betting against an outcome | No | Yes, lay |
| Operator revenue | Margin built into odds | Commission on net winnings in a market |
| Main operator risk | Player results | Empty markets without liquidity |
With no margin, exchange odds are usually higher than bookmaker odds — that is what attracts players.
What a betting exchange is made of
| Component | What it does | Source |
|---|---|---|
| Event and market catalog | Sports, competitions, matches, markets, and selections | SportAPI: menu, events, event |
| Selection IDs | A stable ID for every selection in the order book | SportAPI: oc_pointer |
| Live state | Score, period, match time | SportAPI: live line |
| Market suspension | Stopping trading at dangerous moments | SportAPI: the oc_block flag |
| Reference prices and liquidity | Starting prices for a market maker | SportAPI: line odds |
| Market settlement | The result of every selection: won, lost, void | SportAPI: bet settlement service (Coupon API) |
| Order book and matching | Pairing back and lay bets | Your engine |
| Wallets and commission | Balance, liability reserve, commission | Your engine |
Half of an exchange is data, and you do not need to collect it yourself. The other half is the engine, and that is where your team’s effort belongs.
Data: events, markets, and selection IDs
The exchange catalog is built from the Sports Odds API: menu returns the tree of sports and competitions, events returns matches, and event returns every market of a match. Each selection has an oc_pointer, for example:
758850796|1|1|0 → match 758850796, group 1 (1x2), outcome 1 (W1), parameter 0
Use oc_pointer as the selection ID in your order book: it is stable, ties orders unambiguously to the match and market, and the same pointer comes in live. The pointer format is described in the odds model.
The engine: matching back and lay bets
Each selection has its own order book. A back order waits for someone to offer the same or higher odds; a lay order waits for the same or lower odds. A simplified engine in Python:
from dataclasses import dataclass
@dataclass
class Order:
user: str
side: str # "back" — bet for the outcome, "lay" — bet against it
odds: float
stake: float # backer stake; for lay — how much backing you are willing to accept
class SelectionBook:
"""Order book of one selection, e.g. oc_pointer 758850796|1|1|0."""
def __init__(self, selection_id):
self.selection_id = selection_id
self.backs, self.lays, self.matched = [], [], []
def place(self, order):
resting = self.lays if order.side == "back" else self.backs
# a backer gets the highest odds, a layer gets the lowest
resting.sort(key=lambda o: o.odds, reverse=order.side == "back")
for other in resting:
if order.side == "back":
fits = other.odds >= order.odds
else:
fits = other.odds <= order.odds
if not fits or order.stake == 0:
break
size = min(order.stake, other.stake)
backer, layer = (order, other) if order.side == "back" else (other, order)
self.matched.append(
{"back": backer.user, "lay": layer.user, "odds": other.odds, "stake": size}
)
order.stake -= size
other.stake -= size
resting[:] = [o for o in resting if o.stake > 0]
if order.stake > 0:
(self.backs if order.side == "back" else self.lays).append(order)
def maker_quotes(odds_1x2, spread=0.03):
"""Market maker prices around SportAPI odds with the margin removed."""
inverse = {outcome: 1 / odds for outcome, odds in odds_1x2.items()}
total = sum(inverse.values())
quotes = {}
for outcome, value in inverse.items():
fair = total / value # odds without the bookmaker margin
quotes[outcome] = {
"lay": round(fair * (1 - spread), 2),
"back": round(fair * (1 + spread), 2),
}
return quotes
Example: the market maker is ready to accept backing on W1 at 2.42, and Anna wants to back at no less than 2.30 — she gets the best available price:
print(maker_quotes({"W1": 2.22, "X": 3.72, "W2": 2.48}))
book = SelectionBook("758850796|1|1|0")
book.place(Order("maker", "lay", 2.42, 100)) # the market maker accepts backing on W1 at 2.42
book.place(Order("anna", "back", 2.30, 40)) # Anna accepts 2.30 or better and gets 2.42
print(book.matched)
print([(o.user, o.stake) for o in book.lays])
[{'back': 'anna', 'lay': 'maker', 'odds': 2.42, 'stake': 40}]
[('maker', 60)]
A real exchange adds partial fills with time priority, the layer’s liability reserve (stake × (odds − 1)), order cancellation, and an audit trail for every trade. The logic stays the same.
Liquidity from day one: a market maker on SportAPI odds
The biggest problem of a new exchange is empty markets: a player has nobody to trade with and leaves. The fix is your own market maker bot that places back and lay orders around a fair price.
The SportAPI line gives you that fair price: remove the margin from the odds and you get a probability estimate for each outcome. The maker_quotes function above does exactly that:
Line odds: W1 2.22 X 3.72 W2 2.48 (margin about 12%)
Fair odds: W1 2.49 X 4.18 W2 2.78
Market maker: accepts backing on W1 at 2.42, accepts laying at 2.57
A player sees 2.42 on the exchange instead of 2.22 at a bookmaker, and the market maker earns the spread between back and lay prices. As the exchange grows, player orders crowd out the bot and liquidity becomes organic. Update the bot’s prices whenever the line changes — in live that is every few seconds.
Live: suspending markets
At a dangerous moment — a penalty, a shot on target, a goal — odds change sharply. If the market keeps trading, fast players pick off orders at stale prices. That is why exchanges suspend markets.
In the SportAPI live line every selection has an oc_block flag: true means it is temporarily closed. Use it as the signal:
oc_blockbecomestrue→ suspend the market and stop accepting new orders.- Decide what happens to unmatched orders: cancel or keep them — it is your exchange rule, so tell players in advance.
oc_blockbecomesfalseagain → reopen the market, and the market maker posts new prices from the fresh line.
Many exchanges also add a delay of a few seconds to in-play bets — another layer of protection against trading on faster information.
Market settlement and commission
After the match the market closes and settles: every selection gets a result — won, lost, void, or a half result on Asian markets. You do not have to build this settlement yourself: the SportAPI bet settlement service does it. It already knows the rules for totals, handicaps, and voids, tracks the match result itself, and sends the outcome of every selection by callback or on request. The exchange engine only distributes payouts between the parties to each trade and keeps the commission.
The exchange takes commission on a player’s net winnings in a market. An example at 5% commission:
A 100 back bet at 3.00 wins → net winnings 200
Commission 5% → 10, the player receives 190 on top of the stake
If a player won some trades and lost others in the same market, commission is charged on the net result for the market, not on each trade.
Licensing, payments, and player checks
Running a betting exchange requires a license in the jurisdiction where you operate, player verification, and payment infrastructure. Solve these before launch, in parallel with development. SportAPI covers sports data and platform development but does not issue licenses or hold player wallets.
What it costs and where to start
| What you need | Cost |
|---|---|
| Events, markets, prematch and live, odds for one sport | from $30 a month |
| Market settlement — bet settlement service | from $300 a month |
| Exchange engine, wallets, interface | Your own team or turnkey platform development |
| Testing before you pay | 2-day SportAPI trial key, all sports |
Mistakes when launching an exchange
- Launching without liquidity. An empty order book scares off the first players for good. A market maker on line odds is needed from day one.
- Trading through dangerous moments. Without suspension on
oc_block, the exchange loses the market maker’s money and players’ trust. - Home-made selection IDs. Linking orders to matches by team names guarantees errors. Use
oc_pointer. - Commission on every trade. Exchange players expect commission on net market winnings — otherwise active traders leave.
- Too many sports at once. Liquidity gets spread thin. Start with football and a couple of top leagues, then expand.
FAQ
Can I build a betting exchange on SportAPI data alone?
The data and settlement — yes: SportAPI fully covers events, markets, live state, suspensions, and settlement of selections after the match. The exchange engine — order book, wallets, and commission — is developed separately: by your team or by SportAPI as a turnkey project.
Where do odds come from on a new exchange?
From players, through orders. At launch a market maker sets them by quoting around SportAPI line odds with the margin removed.
How does an exchange know when to suspend a market?
From the oc_block flag in the live line: when a selection is temporarily closed, the exchange market stops too.
Why is an exchange better for players than a bookmaker?
Odds without a margin and the ability to bet against an outcome. The operator earns commission on net winnings, not a margin.
Can I check the data before paying?
Yes. The 2-day trial key includes all sports, prematch and live — enough to build a market catalog and run a market maker on a test exchange.
What to do today
- Get a SportAPI trial key and build an event catalog from
menuandevents. - Make
oc_pointerthe selection ID in your order book. - Run a market maker on line odds with the margin removed.
- Connect market suspension on
oc_block. - Connect market settlement through the bet settlement service and commission on net winnings.
Message the SportAPI manager on Telegram with the sports and markets you are building an exchange for — you will get a trial key for the Sports Odds API or can discuss turnkey platform development.
Betfair is a trademark of its owner. SportAPI is not affiliated with Betfair; the name is used only to describe the betting exchange model.