# Why lay liquidity matters in a matched odds feed

> A lay price is only usable if money sits behind it. What lay liquidity is, why each lay offer in a matched feed carries it, and how to check a pair is fillable.

Published 1 July 2026 · updated 18 September 2026

**Lay liquidity is the money waiting to be matched at an exchange lay price, and it decides whether a matched bet can actually be placed.** A strong lay price with little behind it looks like an opportunity on screen and fails the moment a user tries to take it at their stake.

## What is lay liquidity?

Lay liquidity is the money on offer at an exchange lay price, and it caps how much you can lay at that price. On an exchange, a lay price is an offer from backers who want the other side of your bet. The **liquidity** at that price is how much of their stake is sitting there unmatched. If it is deep, a normal lay goes through in full at the price you saw. If it is thin, only part of your stake is matched, and the rest waits or has to be taken at a worse price.

This is where exchange data differs from bookmaker data. A bookmaker's back price stands until the bookmaker moves it, within whatever stake limit it applies to the account. An exchange lay price only holds up to the money behind it. The [lay odds glossary entry](https://oddsrelay.io/glossary/lay-odds) covers the two sides in more detail, and [how to get Betfair lay odds](https://oddsrelay.io/blog/how-to-get-betfair-lay-odds) covers reading them from an exchange directly.

## The size rides on every lay offer

A lay price on its own cannot tell you whether a pair is usable. Two outcomes can show the same back price and the same lay price, and one is worth acting on while the other is not, purely because of the money behind the lay. So each lay offer on an OddsRelay matched board carries `available`, the money on offer at that price, beside the `price` it belongs to.

One outcome on GET /v2/odds/standard, trimmed · example:

```json
{
  "event_id": "or_evt_917dd44bce05",
  "commence_time": "2026-09-20T14:00:00Z",
  "home_team": "Arsenal",
  "away_team": "Chelsea",
  "markets": [{
    "key": "h2h",
    "outcomes": [{
      "name": "Chelsea",
      "back": [{ "bookmaker": "william_hill", "price": 2.5, "link": null }],
      "lay": [
        { "exchange": "matchbook", "price": 2.56, "available": 38.5, "link": null },
        { "exchange": "smarkets", "price": 2.6, "available": 412.0, "link": null }
      ]
    }]
  }]
}
```

In this example the Matchbook lay is the closer price, and it has 38.5 behind it. The Smarkets lay is slightly further from the back price and has more than ten times the liquidity. Which one a user should take depends on the stake they need to lay, and that is a sum the product has to do. The `lay` array can hold offers from several exchanges, so comparing depth for the same selection is a loop over it. The board draws its lay side from Betfair, Smarkets and Matchbook, and the `exchanges` filter narrows it to the ones you use (the [matched-board filters guide](https://oddsrelay.io/docs/guides/matched-board-filters) lists every filter). Each exchange's own page, such as [Smarkets](https://oddsrelay.io/bookmakers/smarkets), shows the sports it carries.

The boards also set a floor of their own. A lay price with too little money behind it never becomes a pair, so a board does not fill up with offers that could barely take a stake. That floor is set for the whole feed. It cannot know your users' stakes, which is why the figure itself still arrives on every offer.

## Check the pair against the stake

The feed carries prices and sizes. It rates nothing. Your product works out the rating and qualifying loss from the two prices, as the [oddsmatcher widget](https://oddsrelay.io/widgets/oddsmatcher) does, and the liquidity check belongs in the same sums: work out the lay stake the user's back bet needs, then compare it with `available`.

Your arithmetic on one pair · example:

```ts
// Customer-side sums. Commission is your users' own exchange rate.
const commission = 0.02;
const backStake = 25;

const layStake = (backStake * back.price) / (lay.price - commission);
const rating = (back.price / lay.price) * 100;
const fillable = lay.available !== null && lay.available >= layStake;
```

With the example above, a back stake of 25 at 2.5 needs a lay stake of about 24.6 on the Matchbook offer. Both exchanges can take that. At a back stake of 100 the lay stake is near 98 on Matchbook and 97 on Smarkets, and only the Smarkets offer has the liquidity. The rating on the Matchbook pair is the better number, and it is the wrong pair for that user.

A product can handle a short lay in three ways:

- **Hard gate.** Drop the pair before it reaches the screen when `available` is below the lay stake. An oddsmatcher then only lists pairs the user can place.
- **Soft flag.** Keep the pair but mark it thin, so the user sees the price and knows it will only part-fill.
- **Best fillable exchange.** Among the offers in `lay`, choose the best price that still covers the stake, and show that one instead of the headline best price.

Whichever one you pick, measure it against each user's own lay stake. A fixed floor in your own code repeats the feed's gate at a different number and still misjudges the user staking five times the average. The [qualifying loss and ratings post](https://oddsrelay.io/blog/qualifying-loss-and-ratings-explained) walks through the rest of the per-pair arithmetic, and [pairing back and lay odds](https://oddsrelay.io/blog/pairing-back-and-lay-odds) applies the check across several bookmakers.

## Liquidity moves, so read its time

Money behind a lay varies by market, by selection and over time. A big football match close to kick-off is usually deep. A minor selection days out can be thin, and depth on one selection can shift within minutes as backers come and go. None of that is a fault in the data. It is the state of the exchange.

So treat `available` as a reading with a time on it. Every response carries the board's time, `meta.processed_at` (or the `X-Processed-At` header). A matched board's envelope also carries `meta.last_seen`, the last read of each venue and sport, and now minus that time is an upper bound on how old a lay price and its `available` figure can be. Gate on the figure, act on it promptly, and re-check the exchange before a large stake goes on. Reading an exchange directly has its own timing catch, set out in [the Betfair API 5-second delay](https://oddsrelay.io/blog/betfair-api-5-second-delay). The [freshness guide](https://oddsrelay.io/docs/guides/freshness) explains both fields.

Teams that want exchange prices without the pairing can take the raw board, `GET /v2/odds/raw`, where each exchange's outcomes list `back_price`, `lay_price` and `available` side by side. There, `includeLiquidity=false` leaves the size out when a product has no use for it. The [lay and exchange coverage guide](https://oddsrelay.io/guides/lay-and-exchange-coverage-explained) covers what lay coverage should include and why some markets have no exchange at all.

## Read it on a real reply

Which exchanges and sports are live right now is on the [coverage page](https://oddsrelay.io/coverage), and the field-by-field shape of every reply is in the [API reference](https://oddsrelay.io/docs/reference).

## Sources

- [Smarkets Help Centre: Matched/partially matched bets](https://help.smarkets.com/hc/en-gb/articles/212729225-Matched-partially-matched-bets), checked 29 September 2026

18+ · OddsRelay supplies odds data only and takes no bets. Please gamble responsibly.

Source: https://oddsrelay.io/blog/why-lay-liquidity-matters
