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

# Search Active Packs

> Free-text search over the packs the active-pack listing returns. The search applies the same ACTIVE, trade-window, and eligibility gating as the listing, so it never surfaces a pack the listing hides. Matches the pack name, each leg's team names, match titles, market titles, and league names. Matching is case- and accent-insensitive and tokenized: every word in the query must appear somewhere in the fields being tested, but words can match in any order and across different fields. Results are ranked by relevance: packs matched on their name first, then packs where a single leg's teams or match title carries the whole query, then matches spread across other fields. When packs are paused platform-wide, the search returns an empty array.

Free-text search over active packs. Public, no authentication required. The search covers exactly the packs the active-pack listing returns, with the same `ACTIVE`, trade-window, and eligibility gating, so it never surfaces a pack the listing hides.

## When to use

Use this endpoint to power a pack search box. Pack names are often editorial and say nothing about their contents, so the search also matches what is inside each pack: leg team names, match titles, market titles, and league names. A user searching for a team or league finds every active pack that carries it, even when the pack name mentions neither.

## Matching

* Matching is case- and accent-insensitive: `koln` matches `1. FC Köln`, `fenerbahce` matches `Fenerbahçe`.
* The search tokenizes the query, so word order does not matter and words can match across different fields: `man city` finds a Manchester City pack, and `vitality 9z` finds a pack holding both teams in different legs.
* Every word in the query must appear somewhere for a pack to match.
* `query` must be 2-100 characters. A query shorter than 2 characters after trimming returns an empty array rather than an error, matching `/markets/search`.

## Ranking

Results come back in three relevance tiers:

1. Packs whose name matches the query.
2. Packs where a single leg's team names or match title carries the whole query. A query spread across different legs does not earn this tier.
3. Packs matched across any other fields, such as market titles or league names.

Within a tier, packs keep the listing's order (earliest deadline first).

## Limits and availability

* `limit` caps the number of results at 1-50. The default is 20.
* When packs are paused platform-wide, the search returns an empty array, matching the listing.

## Caching

Responses carry `Cache-Control: public, max-age=30, stale-while-revalidate=60`, so results can trail the live listing by up to a minute.


## OpenAPI

````yaml GET /parlay/packs/search
openapi: 3.0.0
info:
  title: Limitless Exchange API
  description: >-

    # Limitless Exchange Trading API


    *Production-ready API for prediction market trading, portfolio management,
    and market data*


    > 🎯 **Quick Navigation**: [Authentication](#tag/authentication) |
    [Markets](#tag/markets) | [Trading](#tag/trading) |
    [Portfolio](#tag/portfolio)


    ---
      


    ## 🚀 Quick Start


    Choose your preferred programming language for complete end-to-end
    implementation:


    ### Overview


    The Limitless Exchange API offers both REST and WebSocket integration:


    **REST API (Trading)**:

    1. **🔐 Authentication**: Use API key for all programmatic access

    2. **📊 Fetch Market Data**: Get market info including venue contract
    addresses (once per market)

    3. **📋 Order Creation**: Build and sign orders using EIP-712 structured
    data

    4. **🚀 Order Submission**: Submit signed orders and receive confirmations


    **WebSocket API (Real-Time Data)**:

    1. **🔌 Connection**: Connect to `/markets` namespace for real-time updates

    2. **📊 Subscriptions**: Subscribe to market prices and position changes

    3. **📡 Events**: Handle live market data and transaction updates


    ### 🔐 Authentication for API Users


    > **⚠️ DEPRECATION NOTICE**: Cookie-based session authentication is
    deprecated and will be removed within weeks. Please migrate to API keys
    immediately.


    | Method | Header | Status |

    |--------|--------|--------|

    | **API Key** | `X-API-Key: lmts_...` | ✅ Required for programmatic access |

    | Cookie Session | `Cookie: limitless_session=...` | ⚠️ Deprecated (removal
    imminent) |


    **Getting an API Key**


    API keys can only be created via the Limitless Exchange UI:

    1. Log in to [limitless.exchange](https://limitless.exchange) using your
    wallet

    2. Click your profile menu (top right)

    3. Select "Api keys"

    4. Generate a new key


    **Using Your API Key**


    Include in all requests via the `X-API-Key` header:


    ```bash

    # REST API

    curl -H "X-API-Key: lmts_your_key_here"
    https://api.limitless.exchange/markets


    # WebSocket - pass X-API-Key header during connection handshake

    ```


    ### Migration from Cookie to API Key


    If you're currently using cookie-based authentication, migrate by:


    1. **Generate an API key** via the UI (profile menu → Api keys)

    2. **Replace cookie header** with API key header:


    ```diff

    # Before (deprecated)

    - Cookie: limitless_session=your_session_token


    # After

    + X-API-Key: lmts_your_key_here

    ```


    3. **Remove session management code** - no more login flow or cookie
    handling needed


    ### Important: Venue System for CLOB Markets


    CLOB markets use a **venue system** where each market is associated with
    specific contract addresses. Before placing orders:


    1. **Fetch market data once**: `GET /markets/:slug` returns venue
    information

    2. **Use venue.exchange**: This is the `verifyingContract` for EIP-712 order
    signing

    3. **Cache the venue**: Venue data is static per market - fetch once and
    reuse


    **Sample venue response:**

    ```json

    {
      "venue": {
        "exchange": "0xA1b2C3...",
        "adapter": "0xD4e5F6..."
      }
    }

    ```


    ### Required Approvals


    Before trading, set up token approvals based on order type:


    | Order Type | Market Type | Approve To |

    |------------|-------------|------------|

    | BUY | All CLOB | USDC → `venue.exchange` |

    | SELL | Simple CLOB | CT → `venue.exchange` |

    | SELL | NegRisk/Grouped | CT → `venue.exchange` AND `venue.adapter` |


    ### Checksummed Addresses


    All addresses must use **checksummed format** (EIP-55 mixed-case):

    - Authentication: `x-account` header

    - Orders: `maker` and `signer` fields

    - Example: `0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed`


    ### Implementation Guides


    **[🐍 Python Quick Start](#description/-python-quick-start)**

    - REST API: eth-account, requests, and web3.py libraries

    - WebSocket: python-socketio, asyncio integration


    **[☕ Java Quick Start](#description/-java-quick-start)**  

    - REST API: Web3j, OkHttp3, and Jackson libraries


    **[📦 Node.js/TypeScript Quick
    Start](#description/-nodejs-typescript-quick-start)**

    - REST API: viem, ethers, and cross-fetch libraries

    - WebSocket: socket.io-client for real-time trading

    - Full TypeScript support with end-to-end examples


    **[🔌 WebSocket Integration](#description/-websocket-integration)**

    - Real-time market data and position updates

    - Production-ready Python client with authentication


    ---
      


    ## 🐍 Python Quick Start


    Complete end-to-end Python implementation for Limitless Exchange API
    integration.
      


    ### 🐍 Python E2E Order Creation Guide


    Complete Python implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔐 Complete authentication flow with eth-account

    - 📋 Order construction with Web3.py calculations

    - ✍️ EIP-712 structured data signing

    - 🚀 Order submission with requests library

    - ⚠️ Comprehensive error handling

    - 🛠️ Production deployment considerations


    *For the complete Python guide, ensure the file is available at
    docs/scripts-samples/python-e2e-order-creation.md*
        


    ## ☕ Java Quick Start


    Complete end-to-end Java implementation for Limitless Exchange API
    integration.
      


    ### ☕ Java E2E Order Creation Guide


    Complete Java enterprise implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔐 Complete authentication flow with Web3j

    - 📋 Order construction with BigInteger precision

    - ✍️ EIP-712 structured data signing

    - 🚀 Order submission with OkHttp3

    - ⚠️ Enterprise error handling patterns

    - 🏗️ Production Maven project structure


    *For the complete Java guide, ensure the file is available at
    docs/scripts-samples/java-e2e-order-creation.md*
        


    ## 📦 Node.js/TypeScript Quick Start


    Complete end-to-end Node.js/TypeScript implementation for trading and
    WebSocket subscriptions.
      


    ### 📦 Node.js/TypeScript Trading & WebSocket Guide


    Complete Node.js/TypeScript implementation guide is being loaded from
    external documentation...


    **Guide Contents:**

    - 🔐 **Authentication**: Wallet-based auth with ethers and viem

    - 📋 **Order Creation**: EIP-712 signing with viem WalletClient

    - 🚀 **Order Submission**: REST API integration with cross-fetch

    - 🔌 **WebSocket Subscriptions**: socket.io-client for real-time updates

    - 📊 **Market Data**: AMM prices and CLOB orderbook subscriptions

    - ⚠️ **Type Safety**: Full TypeScript support with proper types

    - 🛠️ **Production Ready**: Complete end-to-end working example


    **Key Features:**

    - **Combined Subscriptions**: Subscribe to both AMM and CLOB markets
    simultaneously

    - **Authentication Flow**: Complete wallet-based authentication with session
    management

    - **Trading Integration**: Place orders and receive real-time updates

    - **TypeScript First**: Type-safe implementation with proper interfaces


    *For the complete Node.js guide, ensure the file is available at
    docs/scripts-samples/node-socket-trading-and-subscribe.md*
        


    ## 🔌 WebSocket Integration


    Real-time market data and position updates using WebSocket connections.
      


    ### 🔌 WebSocket Real-Time Integration Guide


    Complete WebSocket implementation guide is being loaded from external
    documentation...


    **Guide Contents:**

    - 🔌 **WebSocket Connection**: python-socketio client with async support

    - 🔐 **Authentication**: JWT session cookie integration

    - 📊 **Market Subscriptions**: Real-time price updates and position changes

    - ⚡ **Event Handling**: Comprehensive event processing patterns

    - 🔄 **Auto-Reconnection**: Production-ready reconnection logic

    - 🛠️ **Error Recovery**: Robust error handling and fallback strategies


    **Key Features:**

    - **Public Mode**: Market price updates without authentication

    - **Authenticated Mode**: Full access to positions and transactions

    - **Multi-Market Support**: Subscribe to multiple markets simultaneously

    - **Production Ready**: Tested patterns for production deployment


    *For the complete WebSocket guide, ensure the file is available at
    docs/scripts-samples/python-socket-subscribe.md*
        
  version: '1.0'
  contact:
    name: API Support
    url: https://limitless.exchange
    email: hey@limitless.network
servers:
  - url: https://api.limitless.exchange
    description: Production API
security: []
tags:
  - name: Authentication
    description: User authentication and session management
  - name: Markets
    description: Browse, search, and analyze prediction markets
  - name: Market Navigation
    description: Navigation tree, market pages, and property filters
  - name: Trading
    description: Create, manage, and cancel orders
  - name: Portfolio
    description: Position tracking, trade history, and performance
  - name: Feed
    description: Public trading activity feeds
paths:
  /parlay/packs/search:
    get:
      tags:
        - Packs
      summary: Search active packs
      description: >-
        Free-text search over the packs the active-pack listing returns. The
        search applies the same ACTIVE, trade-window, and eligibility gating as
        the listing, so it never surfaces a pack the listing hides. Matches the
        pack name, each leg's team names, match titles, market titles, and
        league names. Matching is case- and accent-insensitive and tokenized:
        every word in the query must appear somewhere in the fields being
        tested, but words can match in any order and across different fields.
        Results are ranked by relevance: packs matched on their name first, then
        packs where a single leg's teams or match title carries the whole query,
        then matches spread across other fields. When packs are paused
        platform-wide, the search returns an empty array.
      operationId: ParlayController_searchPacks
      parameters:
        - name: query
          required: true
          in: query
          description: >-
            Free-text query, matched case- and accent-insensitively against the
            pack name, its legs' team names, match titles, market titles, and
            league names. A query shorter than 2 characters after trimming
            returns an empty array.
          schema:
            example: liverpool
            type: string
            minLength: 2
            maxLength: 100
        - name: limit
          required: false
          in: query
          description: Maximum number of results to return.
          schema:
            type: number
            default: 20
            minimum: 1
            maximum: 50
      responses:
        '200':
          description: Matching active packs, ranked by relevance
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PackResponseDto'
        '400':
          description: >-
            Missing query, query longer than 100 characters, or limit outside
            1-50
components:
  schemas:
    PackResponseDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        parlayType:
          type: string
          enum:
            - CLOB
            - NEGRISK
        status:
          type: string
          enum:
            - ACTIVE
            - CLOSED
            - DRAFT
            - HIDDEN
        wasteStrategy:
          type: string
          enum:
            - HOLD
            - SELL
          description: Waste-disposition strategy for parlays bought from this pack
        earliestDeadline:
          type: string
          description: ISO timestamp of the earliest leg deadline
        legs:
          type: array
          items:
            $ref: '#/components/schemas/PackLegResponseDto'
        payout:
          description: Always computed with stake = "10"
          allOf:
            - $ref: '#/components/schemas/PackPayoutDto'
        properties:
          type: array
          items:
            $ref: '#/components/schemas/PackPropertyResponseDto'
          description: Property-key tags attached to this pack (used by filter pages)
        eligible:
          type: boolean
          description: >-
            True when the pack would be accepted by a quote against current
            orderbook state. False signals clients to disable the buy CTA and
            surface ineligibleReason.
        ineligibleReason:
          type: string
          nullable: true
          description: >-
            Single-line reason from the most recent quote attempt when
            eligible=false. Null when eligible.
        inDeadlineWindow:
          type: boolean
          description: >-
            Mirrors the deadline gate the active-pack listing applies. False
            packs are hidden from users even when ACTIVE.
        packOutcome:
          type: string
          enum:
            - WON
            - LOST
            - PENDING
          description: >-
            LOST the moment any resolved leg mismatches, WON only when every leg
            resolves matching, PENDING otherwise
      required:
        - id
        - name
        - parlayType
        - status
        - wasteStrategy
        - earliestDeadline
        - legs
        - payout
        - properties
        - inDeadlineWindow
        - packOutcome
    PackLegResponseDto:
      type: object
      properties:
        marketId:
          type: number
        marketSlug:
          type: string
        marketTitle:
          type: string
        marketType:
          type: string
          enum:
            - CLOB
            - NEGRISK
          nullable: true
          description: >-
            Per-leg market type (CLOB or NEGRISK); present for mixed-pack intent
            building
        outcome:
          type: string
          enum:
            - 'YES'
            - 'NO'
        livePrice:
          type: number
          description: Current market price (0..1)
        priceSnapshot:
          type: number
          description: Price at pack build time (0..1)
        group:
          nullable: true
          description: Group context for this leg (null for non-grouped markets)
          allOf:
            - $ref: '#/components/schemas/PackLegGroupDto'
        leagueName:
          type: string
          nullable: true
          description: Solo market's own league/discipline
        marketImageUrl:
          type: string
          nullable: true
          description: Logo/crest image URL from the leg market
        startMatchTimestamp:
          type: number
          nullable: true
          description: Solo market kickoff time (epoch seconds); null when not scheduled
        resolvedOutcome:
          type: string
          enum:
            - 'YES'
            - 'NO'
          nullable: true
          description: >-
            Actual on-chain market outcome. Null while the underlying market is
            unresolved.
        esportsPropType:
          type: string
          enum:
            - map_winner
            - map_handicap
            - total_maps
          nullable: true
          description: >-
            Which typed esports prop this leg is, so it can be drawn as a prop
            of a fixture rather than as the fixture. Null on match winners and
            on every non-esports market.
        outcomeLabels:
          type: array
          nullable: true
          minItems: 2
          maxItems: 2
          items:
            type: string
          description: >-
            For named-outcome markets: labels as [homeTeam/YES, awayTeam/NO].
            Null when labels are unavailable.
        outcomeImageUrls:
          type: array
          nullable: true
          minItems: 2
          maxItems: 2
          items:
            type: string
            nullable: true
          description: >-
            Outcome-specific artwork as [homeTeam/YES, awayTeam/NO]. Null when
            no artwork is available.
      required:
        - marketId
        - marketSlug
        - marketTitle
        - outcome
        - livePrice
        - priceSnapshot
        - resolvedOutcome
        - esportsPropType
        - outcomeLabels
        - outcomeImageUrls
    PackPayoutDto:
      type: object
      properties:
        stake:
          type: string
          description: Display stake in dollars
          example: '10'
        parlayMultiplier:
          type: number
          description: Parlay multiplier after vig (4dp)
        parlayPayout:
          type: string
          description: Parlay payout in dollars (2dp)
          example: '76.80'
        singlesMultiplier:
          type: number
          description: Average singles multiplier (4dp)
        singlesPayout:
          type: string
          description: Singles payout in dollars, stake split equally across legs (2dp)
        savingsPct:
          type: number
          description: Savings percent vs singles
      required:
        - stake
        - parlayMultiplier
        - parlayPayout
        - singlesMultiplier
        - singlesPayout
        - savingsPct
    PackPropertyResponseDto:
      type: object
      properties:
        id:
          type: string
          description: Pack property row id
        propertyKeyId:
          type: string
          description: Property key UUID
        propertyKeySlug:
          type: string
          description: Property key slug (e.g. "domain")
        propertyKeyName:
          type: string
          description: Property key name
        value:
          description: Value for this pack
      required:
        - id
        - propertyKeyId
        - propertyKeySlug
        - propertyKeyName
        - value
    PackLegGroupDto:
      type: object
      properties:
        id:
          type: number
        slug:
          type: string
        title:
          type: string
        leagueName:
          type: string
          nullable: true
          description: Match group's league/discipline
        homeTeam:
          type: string
          nullable: true
        awayTeam:
          type: string
          nullable: true
        homeScore:
          type: number
          nullable: true
        awayScore:
          type: number
          nullable: true
        startMatchTimestamp:
          type: number
          nullable: true
          description: Match kickoff time (epoch seconds); null for non-sports groups
      required:
        - id
        - slug
        - title

````