layer docs

Markets#

Beta, early access. These endpoints are open to selected accounts while they're tested, and may still change. /v0/matches is unchanged and stays the way to get Kalshi ↔ one-venue matches.

A Layer market is one real-world question, like "Velez Sarsfield beat Union Santa Fe on Nov 6", with every venue's market for it side by side. Each venue's market is a listing.

/v0/matches gives you Kalshi and one other venue per item, one venue per request. /v0/markets gives you every venue in one item.

Reading a market#

Every answer below is a real one. Five things to look at:

  1. question: the real-world question, in plain words. It's left out when a venue on the market doesn't allow Layer to show its wording, as on every market that includes polymarket.com (see All fields).
  2. listings: one per venue that lists it, each with its venue, market_id and url.
  3. basis on each listing: identical means the same bet. equivalent_with_caveats means the same question with a rule difference, named in caveats (such as rounding_differs). Keep only identical listings and you always have the same bet.
  4. price on each listing: the venue's live best bid and ask for YES and NO, with sizes.
  5. best_trade: the best "buy YES on one venue, NO on another" between identical listings, with fees. best_trade_any is the same between any two listings, rule differences included.

GET/v0/markets#

Open markets listed on two or more venues that haven't ended, soonest first: by start_time for markets starting later or in the last 4 hours, else by event_time (a season-long market sorts by when it settles).

curl -H "Authorization: Bearer $LAYER_API_KEY" "https://uselayer.sh/v0/markets?category=crypto&from=2026-11-06&limit=1&prices=false"
json
{
  "count": 1,
  "markets": [
    {
      "id": "lyr_0117c14f6267",
      "event_id": "lyr_evt_185a779da3e5",
      "category": "crypto",
      "question": "ETH at or above $2,960 at 5 PM ET, Nov 6",
      "event_time": "2026-11-06T22:05:00.000Z",
      "status": "open",
      "listings": [
        {
          "venue": "kalshi",
          "market_id": "KXETHD-26NOV0617-T2959.99",
          "url": "https://kalshi.com/markets/kxethd/x/kxethd-26nov0617",
          "series": "KXETHD",
          "basis": "identical",
          "caveats": [],
          "reference": true,
          "question": "Ethereum price at Nov 6, 2026 at 5pm EST?",
          "outcome": "$2,960 or above"
        },
        {
          "venue": "polymarket_us",
          "market_id": "cpceth-eth-above-wk-2026-11-06-2960",
          "url": "https://polymarket.us/event/eth-above-wk-2026-11-06",
          "series": "eth-strike-weekly",
          "basis": "equivalent_with_caveats",
          "caveats": ["rounding_differs"],
          "question": "ETH Price at 5:00PM ET on Fri, Nov 6",
          "outcome": "$2,960 or above"
        }
      ]
    }
  ],
  "attribution": "Market data from Kalshi (kalshi.com) and Polymarket US (polymarket.us). Each market's url links to its page on the venue, where it's traded."
}

Here Kalshi is the reference listing, and Polymarket US is the same question with one difference: the two venues round the price differently.

Query Default Meaning
category all sports, crypto, politics, economics, …
q none Words that must all appear: q=nfl, q=bitcoin.
from not ended yet YYYY-MM-DD, the first day (UTC). Without it, only markets that haven't ended: their event_time is now or later, or they have none.
to none YYYY-MM-DD, the last day (UTC). from and to filter on the same time the list sorts by.
venues any Listed on all of these: venues=kalshi,polymarket_us. Names: kalshi, polymarket, polymarket_us, novig, hyperliquid.
event_id none Every market of one game or occasion.
limit, offset 50, 0 Page size (1–200) and how many to skip.
prices true false leaves out prices and best trades, for a faster answer.

GET/v0/markets/{id}#

One market, with live prices and best trades.

curl -H "Authorization: Bearer $LAYER_API_KEY" "https://uselayer.sh/v0/markets/lyr_60a98333e4c6"
json
{
  "market": {
    "id": "lyr_60a98333e4c6",
    "event_id": "lyr_evt_781c1f1f4743",
    "category": "sports",
    "question": "Union Santa Fe vs Velez Sarsfield: Velez Sarsfield wins",
    "event_time": "2026-11-07T01:00:00.000Z",
    "status": "open",
    "listings": [
      {
        "venue": "kalshi",
        "market_id": "KXARGPREMDIVGAME-26NOV06UNIVEL-VEL",
        "url": "https://kalshi.com/markets/kxargpremdivgame/x/kxargpremdivgame-26nov06univel",
        "basis": "identical",
        "caveats": [],
        "reference": true,
        "outcome": "Velez Sarsfield",
        "price": {
          "yes": { "bid": { "price": 0.36, "size": 1262.4 }, "ask": { "price": 0.37, "size": 3437.12 } },
          "no": { "bid": { "price": 0.63, "size": 3437.12 }, "ask": { "price": 0.64, "size": 1262.4 } }
        }
      },
      {
        "venue": "polymarket_us",
        "market_id": "atc-lpa-uni-vel-2026-11-06-vel",
        "url": "https://polymarket.us/event/lpa-uni-vel-2026-11-06",
        "basis": "identical",
        "caveats": [],
        "outcome": "CA Vélez Sarsfield (Reg. Time)",
        "price": {
          "yes": { "bid": { "price": 0.35, "size": 1777 }, "ask": { "price": 0.37, "size": 1400.5 } },
          "no": { "bid": { "price": 0.63, "size": 1400.5 }, "ask": { "price": 0.65, "size": 1777 } }
        }
      }
    ],
    "prices_as_of": "2026-11-06T03:26:37.655Z",
    "best_trade": {
      "kalshi": { "buy": "no", "price": 0.64, "size": 1262.4 },
      "polymarket_us": { "buy": "yes", "price": 0.37, "size": 1400.5 },
      "contracts": 1262,
      "cost": 1274.62,
      "fees": 40.8,
      "payout": 1262,
      "net_profit": -53.42,
      "net_profit_per_contract": -0.04233,
      "return_pct": -4.06,
      "profitable": false,
      "expected_payout_at": "2026-11-07T07:00:00.000Z",
      "days_held": 1.15,
      "listings": [
        { "venue": "kalshi", "market_id": "KXARGPREMDIVGAME-26NOV06UNIVEL-VEL", "basis": "identical", "caveats": [] },
        { "venue": "polymarket_us", "market_id": "atc-lpa-uni-vel-2026-11-06-vel", "basis": "identical", "caveats": [] }
      ]
    },
    "best_trade_any": { "…": "the same trade as best_trade here: both listings are identical" }
  },
  "attribution": "Market data from Kalshi (kalshi.com) and Polymarket US (polymarket.us). Each market's url links to its page on the venue, where it's traded."
}

How to read it:

  • The trade: buy NO on Kalshi at 64¢ and YES on Polymarket US at 37¢, for 1,262 contracts.
  • What it costs: $1,274.62, plus $40.80 in fees, to get $1,262 back. That's a loss of $53.42, so profitable is false. Most of the time there's no free money; when there is, profitable is true.
  • Shortened: some fields are left out here to keep it short, such as each listing's question, group_id and series, and the trade's latest_payout_at and per-day returns. All fields lists them.

Layer ids never change. If two markets are merged, the old id answers with the one it became, and merged_from says so.

GET/v0/markets/lookup#

Find the Layer market from any venue's market id.

curl -H "Authorization: Bearer $LAYER_API_KEY" "https://uselayer.sh/v0/markets/lookup?venue=kalshi&market_id=KXARGPREMDIVGAME-26NOV06UNIVEL-VEL"

This answers with the same market as above. When there's no Layer market for it, market is null and reason says why:

json
{
  "market": null,
  "reason": "no_twin_yet",
  "detail": "Layer knows this market, but no other venue it serves lists the same question yet."
}
reason Meaning
no_twin_yet No other venue lists the same question yet, or a new match hasn't reached Layer markets yet (they're updated in batches, so they can lag /v0/matches).
under_review Its listing is held while its match or settlement is checked.
unknown_market Layer hasn't read that market id.
venue_not_served That venue isn't served right now.

For polymarket.com, the condition id, the numeric id or the slug all work: <slug> for a Yes/No market, <slug>:<i> for one outcome of a multi-outcome market.

Moving from /v0/matches#

Nothing changes unless you want it to. /v0/matches stays as it is.

  • One item instead of several. One /v0/markets item is all the /v0/matches items that share a Kalshi market, across venues. Your Kalshi ↔ Polymarket US pair is the market's kalshi listing plus its polymarket_us listing.
  • Basis per listing. basis and caveats are on each listing, compared with the reference, instead of on the pair.
  • Find yours. Have a match from /v0/matches? Call /v0/markets/lookup?venue=kalshi&market_id=<kalshi.market_id>.
  • Lag. Layer markets can lag /v0/matches for new matches.

Errors#

Status error When
400 bad_request A filter Layer can't read; detail says which.
401 unauthorized No key, or the key is unknown or revoked.
403 markets_not_enabled Your account doesn't have early access yet.
404 not_found /v0/markets/{id}: no Layer market with that id.
429 rate_limited Over 60 requests/minute, as for every /v0 endpoint. Wait retry-after seconds.
503 markets_unavailable Briefly, right after a deploy. Try again in a few minutes.

Not yet#

  • Live 15-minute crypto windows. They're in /v0/matches. /v0/markets has crypto price levels, but not yet the short windows.
  • Markets Kalshi doesn't list. Every Layer market today includes a Kalshi listing.
  • Settled markets (/v0/markets/settled), Gemini, and crypto price ranges.
  • Hyperliquid best trades. Hyperliquid listings get a price but no best trade: its fees aren't modelled.

All fields#

Field Meaning
id, event_id The market's Layer id, and its game's or occasion's.
status open, closed (trading over) or settled. The list returns only open markets; /{id} and lookup return any.
question, start_time, event_time Shown when every venue on the market allows Layer to show its data; otherwise left out. On a market that includes polymarket.com, they're missing. start_time: when the game or window starts (ISO 8601), or null when Layer doesn't know it yet. event_time: for a game, the venue's expected settle time, a few hours after the start; for a crypto window, its end.
reference_hidden true when the reference listing isn't shown (its venue isn't served, or it's under review). The other listings' basis still holds.
listings[].reference true on the listing the others are compared with: Kalshi's when it's there.
listings[].question, outcome The venue's own wording, where that venue allows it.
listings[].group_id, series, slug The venue's event, series and (for polymarket.com) slug.
listings[].price null only when that venue's prices couldn't be read; a side with no order has a null bid or ask (an ended game shows them all null).
prices_unavailable At the top of the answer: venues whose prices couldn't be read this time.
best_trade, best_trade_any null when no pair has both asks. Priced like POST /v0/profit.
attribution One sentence naming every venue on the answer once. Show it wherever you show the data.