layer docs

Quickstart

About two minutes from sign-up to your first match.

1. Sign up

Go to uselayer.sh and click Get API access. Sign in with GitHub, Google, Discord, a wallet, or email.

2. Create a key

Onboarding asks you to accept the terms and what you're building, then creates your first key. It starts with lyr_.

Copy it right away — it's shown once. Layer only stores a hash of it. You can create, name, revoke and rotate keys any time on your dashboard.

Put it in your shell once, so the commands below run as-is:

export LAYER_KEY="lyr_your_key"

3. List live matches

curl -H "authorization: Bearer $LAYER_KEY" \
  "https://uselayer.sh/v0/matches?limit=3"

You get back pairs of markets — one on Kalshi, one on Polymarket — that pay out the same way:

{
  "count": 3,
  "matches": [
    {
      "kalshi": {
        "market_id": "KXEFLL1BTTS-26SEP26BRABAR-BTTS",
        "event": "Bradford vs Barnsley: BTTS — BRA vs BAR (Sep 26)",
        "question": "Both Teams To Score"
      },
      "polymarket": {
        "market_id": "0xfb79…",
        "question": "Bradford City AFC vs. Barnsley FC: Both Teams to Score",
        "yes_token_id": "…"
      },
      "event_date": "2026-09-26",
      "confidence": 0.85,
      "basis": "equivalent_with_caveats",
      "caveats": ["source_differs"]
    }
  ]
}

Your matches will differ — markets open and close every day. What the fields mean:

  • confidence — how sure Layer is that the two markets are the same bet, from 0 to 1.
  • basis — identical if the rules match exactly, or equivalent_with_caveats if they pay out the same except in an edge case.
  • caveats — which edge cases differ, for example source_differs: they settle using different data sources. The full list is in the Overview. How each venue handles a cancelled or postponed event isn't listed per match; see "Settlement policies" in the Overview.

4. Look up one market

Take any market_id from your step 3 response — from either venue — and ask for its twin:

MARKET_ID="paste_a_kalshi_market_id"

curl -H "authorization: Bearer $LAYER_KEY" \
  "https://uselayer.sh/v0/match?venue=kalshi&market_id=$MARKET_ID"

With jq installed, you can grab one straight from the list instead:

MARKET_ID=$(curl -s -H "authorization: Bearer $LAYER_KEY" \
  "https://uselayer.sh/v0/matches?limit=1" | jq -r '.matches[0].kalshi.market_id')

It works both ways: pass venue=polymarket with a Polymarket id and you get the Kalshi market back.

Checking a whole watchlist? POST /v0/match takes up to 50 markets in one call, and it counts as one request against your limit. See the API reference.

5. Check a trade's profit

Found a pair where YES on one venue plus NO on the other costs less than $1? Send the two prices and Layer works out both venues' fees and what's left:

curl -X POST -H "authorization: Bearer $LAYER_KEY" \
  -H "content-type: application/json" \
  -d '{"contracts":100,"kalshi":{"price":0.42},"polymarket":{"price":0.55,"category":"sports"}}' \
  "https://uselayer.sh/v0/profit"

The answer has each venue's cost and fee, the spread, the net_profit after fees, and profitable. Layer doesn't fetch prices for you: take them from each venue's API. All the options (maker orders, Kalshi fee multipliers, a market's exact Polymarket fee rate) are under POST /v0/profit in the API reference.

Limits

  • 60 requests per minute per key. Over that you get 429 rate_limited with a retry-after header.
  • Keys can be sent as authorization: Bearer <key> or x-api-key: <key>.

Next

  • API reference — all fields, errors, "no match" reasons and fee formulas.
  • How matching works — why you can trust a match, and how Layer checks itself against real results.