Skip to main content

1. Get an API key

Create an account at surfaceapi.com/portal. Sign in via magic link and generate your API key in the developer portal.

2. Make a request

Pass your key in the X-API-Key header. You can look up any Kalshi ticker or Polymarket contract slug.

3. Read the response

contracts is keyed first by exchange, then by that exchange’s contract ID. matches follows the same exchange-and-contract keys to show linked contracts and whether their YES/NO sides are inverted. This structure supports clusters with multiple contracts per exchange and can accommodate additional exchanges. For a paginated list of clusters within one configured association, see List match clusters. Resolution rules are omitted by default. Add include_rules=true when you need the rules string for each contract. Use include_rules=false or omit the parameter for a smaller response. Surface validates team, date, and side alignment before accepting a match. If something doesn’t check out, it’s blocked — you won’t receive a partial or uncertain result.

It works in both directions

The response is identical regardless of which contract ID you query. Pass the Polymarket ID to get the same cluster:

Understanding contract ID

The contractID parameter refers to the exchange’s own identifier for a contract. Each exchange uses a different format:
  • Kalshi — use the market ticker (e.g., KXMLBGAME-26MAR252005NYYSF-SF). You can find this in Kalshi’s GET /markets response under the ticker field. Do not use the event_ticker or series_ticker.
  • Polymarket — use the market slug (e.g., mlb-nyy-sf-2026-03-25). You can find this in Polymarket’s GET /markets response under the slug field. Do not use the CLOB token IDs, condition ID, or event slug.
The Surface API accepts either format. Query with a Kalshi ticker or Polymarket slug — the response is the same either way.

Understanding is_inverse

Sports games on Kalshi have two contracts — one for each team. One maps directly to Polymarket (is_inverse: false) and the other is the inverse side (is_inverse: true). When is_inverse is true, YES on that Kalshi contract is equivalent to NO on the Polymarket contract. In this example, KXMLBGAME-26MAR252005NYYSF-NYY (Yankees YES) is inverse to the Polymarket contract where Yankees YES is also the direct side. Invert prices and sides accordingly.

Check your quota

Every authenticated response includes these headers: Repeat lookups of any contract within the same cluster are always free against the daily quota, but still count toward the minute request limit. Unknown contracts are free against the daily quota, but still count toward the minute request limit. See Introduction for full quota rules.