> ## Documentation Index
> Fetch the complete documentation index at: https://docs.predexon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Matched Pairs

> Get all active exact-matched market groups across supported venues

## Overview

Get all active exact-matched market groups across supported venues. The legacy match is anchored on Polymarket with Kalshi and/or Limitless when available. Predict and Opinion are returned by default when canonical matching has verified equivalent listings.

This endpoint returns pre-computed active matches ordered by similarity score (highest first). Use the `venue` filter to restrict results to a venue: `polymarket`, `kalshi`, `limitless`, `predict`, or `opinion`.

<Note>**Requires Dev or Pro tier.** This endpoint is not available on the Free tier.</Note>

| Constraint   | Value                                |
| ------------ | ------------------------------------ |
| `limit`      | 1–200 (default 100)                  |
| `sort_by`    | `similarity` (default), `expiration` |
| `sort_order` | `asc`, `desc` (default)              |

<Warning>
  **LLM-Based Matching**: Market matching is powered by large language models (LLMs). There is a small percentage of markets where hallucinations may occur, resulting in invalid or incorrect matches. Always verify matches before making trading decisions.
</Warning>

## Sorting

By default, pairs are sorted by `similarity` in descending order (highest first). You can change the sort field and direction:

* **`sort_by=similarity`** (default) - Order by match confidence score
* **`sort_by=expiration`** - Order by `earliest_expiration_ts` (the soonest expiration across both platforms). Pairs where both expirations are null are excluded when sorting by expiration.

Use `sort_order=asc` to reverse the direction (e.g., soonest-expiring first).

## Expiration Filtering

Filter pairs by market expiration timestamps (unix seconds). These filters are useful for finding pairs that expire within a specific time window.

| Parameter           | Description                                                        |
| ------------------- | ------------------------------------------------------------------ |
| `expires_before`    | Only pairs where `earliest_expiration_ts` is before this timestamp |
| `expires_after`     | Only pairs where `earliest_expiration_ts` is after this timestamp  |
| `k_expires_before`  | Only pairs where Kalshi expires before this timestamp              |
| `k_expires_after`   | Only pairs where Kalshi expires after this timestamp               |
| `pm_expires_before` | Only pairs where Polymarket expires before this timestamp          |
| `pm_expires_after`  | Only pairs where Polymarket expires after this timestamp           |

<Note>
  Pairs where the relevant expiration field is null are excluded from results when using that filter. For example, using `expires_before` will exclude pairs where both platform expirations are null.
</Note>

## Response Fields

Each result can include these venue blocks:

| Field                      | Description                                                                                     |
| -------------------------- | ----------------------------------------------------------------------------------------------- |
| `POLYMARKET`               | Polymarket listing metadata. Present on every result.                                           |
| `KALSHI`                   | Kalshi listing metadata, when matched.                                                          |
| `LIMITLESS`                | Limitless listing metadata, when matched.                                                       |
| `PREDICT`                  | Predict listing metadata, when canonical matching has a verified equivalent.                    |
| `OPINION`                  | Opinion listing metadata, when canonical matching has a verified equivalent.                    |
| `predexon_id`              | Canonical outcome ID when canonical enrichment is available for the group.                      |
| `POLYMARKET.expiration_ts` | Polymarket market expiration (unix seconds), or `null` if unavailable                           |
| `KALSHI.expiration_ts`     | Kalshi market expiration (unix seconds), or `null` if unavailable                               |
| `earliest_expiration_ts`   | The earliest expiration across both platforms (unix seconds), or `null` if both are unavailable |

Predict and Opinion blocks are intentionally minimal and include only executable identifiers and title fields:

```json theme={null}
{
  "PREDICT": {
    "market_id": "28544",
    "condition_id": "0xf151...",
    "token_id": "350671...",
    "title": "Will Senegal win Group I in the 2026 World Cup?"
  },
  "OPINION": {
    "market_id": "14829",
    "condition_id": "d690...",
    "token_id": "241051...",
    "title": "Everton wins"
  }
}
```

`side` and `status` are not returned in these blocks. The side is implied by the matched claim, and active filtering controls routability.

<Warning>
  **Expiration timestamps are platform-provided estimates.** These dates are set by each venue (Polymarket, Kalshi, Limitless) and represent best-time estimates, not guaranteed resolution times. A market's expiration passing does not necessarily mean it has resolved - resolution may occur later depending on the outcome and platform rules. Additionally, some markets may have a `null` expiration on one or both platforms if the platform does not provide an end date.
</Warning>

## What is an "Exact" Match?

An **exact match** refers to market pairs that track the same real-world outcome and will resolve identically - when one resolves YES, the other will also resolve YES (and vice versa for NO). These are markets asking fundamentally the same question, even if the wording differs slightly between platforms.

### Similarity Score Spectrum

All pairs returned by this endpoint have a similarity score of **95 or higher** (on a 0-100 scale), which qualifies them as exact matches:

| Score Range | Classification  | Description                                                                                    |
| ----------- | --------------- | ---------------------------------------------------------------------------------------------- |
| **98-100**  | High confidence | Virtually identical markets with near-perfect semantic alignment.                              |
| **96-97**   | Confident       | Strong matches with minor wording variations. Reliable for most use cases.                     |
| **95-96**   | Threshold       | Meets exact match criteria but may include edge cases with differences in resolution criteria. |

<Info>
  **For maximum accuracy:** Filter with `min_similarity=98` when precision is critical. The 95-97 range is generally reliable but may contain occasional false positives where resolution criteria have minor discrepancies.
</Info>

## Use Cases

<CardGroup cols={2}>
  <Card title="Arbitrage Discovery" icon="scale-balanced">
    Find price discrepancies between identical markets on different platforms
  </Card>

  <Card title="Cross-Platform Analysis" icon="code-compare">
    Compare liquidity and volume across platforms for the same event
  </Card>

  <Card title="Market Coverage" icon="globe">
    Identify which markets exist on both platforms
  </Card>

  <Card title="Price Feeds" icon="chart-line">
    Build composite price feeds from multiple sources
  </Card>
</CardGroup>

<Note>
  By default, pairs are ordered by similarity score (highest first). Use `sort_by=expiration&sort_order=asc` to find soonest-expiring pairs, or `min_similarity` to filter for high-confidence matches only.
</Note>


## OpenAPI

````yaml GET /v2/matching-markets/pairs
openapi: 3.1.0
info:
  title: Predexon API
  description: Prediction market data aggregation and matching API
  version: 2.0.0
servers:
  - url: https://api.predexon.com
security:
  - apiKey: []
paths:
  /v2/matching-markets/pairs:
    get:
      tags:
        - matching
      summary: Get Matched Pairs
      description: >-
        Get all exact market pairs across Polymarket and Kalshi.


        Returns exact match pairs with real-time price data and arbitrage
        calculations.

        Results are ordered by similarity score (highest first) and paginated.


        Includes pricing data: yes/no bid/ask prices, spreads, and arbitrage
        opportunities.
      operationId: get_matched_pairs_v2_matching_markets_pairs_get
      parameters:
        - name: active_only
          in: query
          required: false
          schema:
            type: boolean
            description: Only return pairs where both markets are active
            default: true
            title: Active Only
          description: Only return pairs where both markets are active
        - name: min_similarity
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
                maximum: 100
                minimum: 0
              - type: 'null'
            description: Minimum similarity score (0-100)
            title: Min Similarity
          description: Minimum similarity score (0-100)
        - name: sort_by
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/PairSortBy'
            description: 'Sort field: ''similarity'' or ''expiration'''
            default: similarity
          description: 'Sort field: ''similarity'' or ''expiration'''
        - name: sort_order
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/OrderDirection'
            description: 'Sort direction: ''asc'' or ''desc'''
            default: desc
          description: 'Sort direction: ''asc'' or ''desc'''
        - name: expires_after
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: earliest expiration after this unix timestamp (seconds)'
            title: Expires After
          description: 'Filter: earliest expiration after this unix timestamp (seconds)'
        - name: expires_before
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: earliest expiration before this unix timestamp (seconds)'
            title: Expires Before
          description: 'Filter: earliest expiration before this unix timestamp (seconds)'
        - name: k_expires_after
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: Kalshi expiration after this unix timestamp (seconds)'
            title: K Expires After
          description: 'Filter: Kalshi expiration after this unix timestamp (seconds)'
        - name: k_expires_before
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: Kalshi expiration before this unix timestamp (seconds)'
            title: K Expires Before
          description: 'Filter: Kalshi expiration before this unix timestamp (seconds)'
        - name: pm_expires_after
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: Polymarket expiration after this unix timestamp (seconds)'
            title: Pm Expires After
          description: 'Filter: Polymarket expiration after this unix timestamp (seconds)'
        - name: pm_expires_before
          in: query
          required: false
          schema:
            anyOf:
              - type: integer
              - type: 'null'
            description: 'Filter: Polymarket expiration before this unix timestamp (seconds)'
            title: Pm Expires Before
          description: 'Filter: Polymarket expiration before this unix timestamp (seconds)'
        - name: venue
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Filter pairs that include this venue (polymarket, kalshi,
              limitless, predict, opinion)
            title: Venue
          description: >-
            Filter pairs that include this venue (polymarket, kalshi, limitless,
            predict, opinion)
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            maximum: 200
            minimum: 1
            description: Maximum number of pairs to return
            default: 100
            title: Limit
          description: Maximum number of pairs to return
        - name: pagination_key
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: Pagination key from previous response
            title: Pagination Key
          description: Pagination key from previous response
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal Server Error
components:
  schemas:
    PairSortBy:
      type: string
      enum:
        - similarity
        - expiration
      title: PairSortBy
      description: Sort options for matched pairs.
    OrderDirection:
      type: string
      enum:
        - asc
        - desc
      title: OrderDirection
      description: Sort order direction enum.
    ErrorResponse:
      properties:
        error:
          type: string
          title: Error
        message:
          type: string
          title: Message
      type: object
      required:
        - error
        - message
      title: ErrorResponse
      description: Standard error response.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key

````