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—identicalif the rules match exactly, orequivalent_with_caveatsif they pay out the same except in an edge case.caveats— which edge cases differ, for examplesource_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_limitedwith aretry-afterheader. - Keys can be sent as
authorization: Bearer <key>orx-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.