An overview of the Betfair Exchange API — what it offers, how the REST and Streaming APIs compare, how to get credentials, and what a first Java integration looks like.
The Betfair Exchange API is one of the most complete betting market data APIs available. Unlike a traditional bookmaker’s feed, it exposes the underlying exchange: every unmatched order, every matched trade, live price changes in milliseconds, and the ability to place, update, and cancel orders programmatically. For a developer building a trading system, it is both the data source and the execution venue.
The API has two primary interfaces:
REST API (api.betfair.com): Request/response. Catalogue data (markets, events, runners), market books (current prices), account information, and order operations. You poll for updates.
Streaming API (stream-api.betfair.com): Persistent TCP connection. Push-based price and order updates. Millisecond latency. The right choice for any system that needs to act on price movement.
Most production systems use both: the REST API to catalogue and set up markets, the Streaming API to receive live data.
You need three things to call the API:
For interactive use (scripts, one-off tools), interactive login via username + password is sufficient. For server-side applications that run unattended, certificate-based non-interactive login is required — the certificate replaces the password and enables login without human interaction.
Add the necessary HTTP dependencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
A simple REST call to list UK horse racing markets:
public class BetfairApiExample {
private static final String API_URL =
"https://api.betfair.com/exchange/betting/rest/v1.0/";
private final HttpClient httpClient = HttpClient.newHttpClient();
private final ObjectMapper mapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
public List<MarketCatalogue> listUkHorseRacingMarkets(
String sessionToken, String appKey) throws Exception {
String requestBody = """
{
"filter": {
"eventTypeIds": ["7"],
"marketCountries": ["GB"],
"marketTypes": ["WIN"]
},
"maxResults": 10,
"marketProjection": ["MARKET_DESCRIPTION", "RUNNER_DESCRIPTION", "EVENT"]
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL + "listMarketCatalogue/"))
.header("X-Authentication", sessionToken)
.header("X-Application", appKey)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return mapper.readValue(response.body(),
mapper.getTypeFactory().constructCollectionType(List.class, MarketCatalogue.class));
}
}
The API returns JSON. A MarketCatalogue entry contains:
marketId — unique identifier (e.g., "1.234567890")marketName — human-readable (e.g., "3:30 Ascot")event — parent event informationdescription — market type, betting type, turn in play allowedrunners — list of runners with selection IDsThe selectionId (long integer) is the stable identifier for a runner across markets. The same horse has the same selection ID in all markets for that race.
| Operation | Purpose |
|---|---|
listMarketCatalogue |
Browse available markets with metadata |
listMarketBook |
Current prices and matched volumes |
placeOrders |
Place back or lay bets |
updateOrders |
Change price or size of an open order |
cancelOrders |
Cancel open orders |
listCurrentOrders |
View your open orders |
listClearedOrders |
View settled bets |
getAccountFunds |
Check available balance |
Betfair imposes rate limits on the REST API — both request counts per second and data weight (each market request has a data cost). Exceeding limits results in TOO_MANY_REQUESTS or REQUEST_SIZE_EXCEEDS_LIMIT errors. The Streaming API has no equivalent rate limit — it pushes updates to you.
Betfair issues two application keys per application: a delayed key (free, with ~60-second price delays) and a live key (requires a minimum trading history). Development and backtesting can use the delayed key; live trading requires the live key.
Both keys are obtained from your account settings → API Access → Developer App Keys.
With credentials in hand and the basic HTTP structure understood, the next steps are certificate-based authentication for production use, and streaming API subscription for live price data.
If you’re starting a Betfair Exchange API integration in Java and want help with the architecture, get in touch.