> ## 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.

# Buy Partner Pack

> Persist the entire request before submission. Retry with the identical body and idempotency key, including an expired deadline. Check and confirm the managed wallet Pack vault allowance before preparing the intent. RECOVERING is not terminal. Requires HMAC with trading and delegated_signing scopes. Never set x-on-behalf-of globally.

Requires HMAC with `trading` and `delegated_signing`. Select an owned managed server-wallet profile through body field `onBehalfOf`; do not send `x-on-behalf-of`.

## Before submission

1. [Confirm the Pack vault allowance](/developers/partner-packs.md#2-confirm-the-pack-vault-allowance).
2. Obtain an eligible [quote](/api-reference/packs/quote-pack.md).
3. Set a positive `minPayoutAmount`, a deadline at most 480 seconds ahead, and a unique purchase key.
4. Durably save the complete request and its environment/account identity before sending it.

Request amounts are integer micro-USDC strings. The backend handles signing and sponsored submission.

## Replay and recovery

On a timeout, disconnect, or ambiguous result, replay **every field unchanged**, including the original deadline and idempotency key. An expired local timestamp does not prove a purchase failed. A new key creates a separate purchase.

| Buy status | Meaning |
| - | - |
| `COMPLETED` | Minted position; settlement may already be `WON` or `LOST` |
| `PENDING` | Mint is in progress |
| `RECOVERING` | Position `FAILED` is awaiting reconciliation and can become `ACTIVE` |
| `FAILED` | Position `VAULT_REVERTED`; vault transaction reverted |

Poll [Get Partner Pack Position](/api-reference/packs/get-position.md) for pending and recovering purchases. If the bounded wait ends, replay the saved buy to obtain recovery metadata.

Explicit `PRICE_DRIFTED`, the exact expired-intent rejection, and `submissionState: "NOT_SUBMITTED"` have specific renewal paths. `PACK_ALLOWANCE_REQUIRED` identifies the token, vault spender, and required allowance. Follow the [recovery table](/developers/partner-packs.md#recover-buy-errors); HTTP status alone does not determine whether a new key is safe.

This endpoint shares the partner-owner limit of 10 requests per 10 seconds.


## OpenAPI

````yaml POST /parlay/partner/buy
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/partner/buy:
    post:
      tags:
        - Partner Packs
      summary: Buy a curated Pack
      description: >-
        Persist the entire request before submission. Retry with the identical
        body and idempotency key, including an expired deadline. Check and
        confirm the managed wallet Pack vault allowance before preparing the
        intent. RECOVERING is not terminal. Requires HMAC with trading and
        delegated_signing scopes. Never set x-on-behalf-of globally.
      operationId: PartnerPackController_buy
      parameters:
        - name: lmts-timestamp
          in: header
          required: true
          schema:
            type: string
          description: ISO-8601 HMAC signing timestamp.
        - name: lmts-signature
          in: header
          required: true
          schema:
            type: string
          description: >-
            Base64 HMAC-SHA256 signature. Sign the method, path including query,
            and exact body with the timestamp.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerPackBuyDto'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerPackBuyResponseDto'
        '400':
          $ref: '#/components/responses/PartnerPackBadRequest'
        '401':
          $ref: '#/components/responses/PartnerPackUnauthorized'
        '403':
          $ref: '#/components/responses/PartnerPackForbidden'
        '404':
          $ref: '#/components/responses/PartnerPackNotFound'
        '409':
          $ref: '#/components/responses/PartnerPackConflict'
        '422':
          $ref: '#/components/responses/PartnerPackUnprocessable'
        '429':
          $ref: '#/components/responses/PartnerPackRateLimited'
        '503':
          $ref: '#/components/responses/PartnerPackUnavailable'
      security:
        - HmacAuth: []
components:
  schemas:
    PartnerPackBuyDto:
      type: object
      properties:
        packId:
          type: string
          format: uuid
          example: 22222222-2222-4222-8222-222222222222
        stakeAmount:
          type: string
          pattern: ^[1-9]\d{0,19}$
          description: Positive integer micro-USDC string; 1000000 = 1 USDC.
          example: '10000000'
        onBehalfOf:
          type: integer
          minimum: 1
          maximum: 2147483647
          description: Owned managed server-wallet profile ID.
          example: 12345
        minPayoutAmount:
          type: string
          pattern: ^[1-9]\d{0,19}$
          description: Minimum acceptable total payout in integer micro-USDC.
          example: '10000000'
        deadline:
          type: string
          pattern: ^[1-9]\d{0,11}$
          description: >-
            Unix seconds. Future and at most 480 seconds away on first
            submission; preserve unchanged on replay.
        idempotencyKey:
          type: string
          minLength: 1
          maxLength: 128
          pattern: ^[\x21-\x7e]+$
          description: >-
            Stable purchase ID. Persist the complete body before submission and
            replay every field unchanged.
      required:
        - packId
        - stakeAmount
        - onBehalfOf
        - minPayoutAmount
        - deadline
        - idempotencyKey
    PartnerPackBuyResponseDto:
      type: object
      properties:
        status:
          type: string
          enum:
            - COMPLETED
            - PENDING
            - RECOVERING
            - FAILED
          description: >-
            RECOVERING maps to position FAILED; operation FAILED maps to
            position VAULT_REVERTED.
        position:
          $ref: '#/components/schemas/PartnerPackPositionDto'
      required:
        - status
        - position
    PartnerPackPositionDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - PENDING
            - ACTIVE
            - WON
            - LOST
            - FAILED
            - VAULT_REVERTED
          description: >-
            FAILED may recover to ACTIVE. VAULT_REVERTED is terminal. A claimed
            winning position remains WON.
        stakeAmount:
          type: string
          description: Raw micro-USDC; may be a decimal string such as 10000000.000000.
        collateralDeposited:
          type: string
          description: Raw micro-USDC.
        multiplierOffered:
          type: string
        vigPercent:
          type: string
        compoundTokenId:
          type: string
          nullable: true
        txHash:
          type: string
          nullable: true
          description: Buy transaction hash.
        claimTxHash:
          type: string
          nullable: true
          description: Confirmed redemption hash. Distinct from txHash.
        resolvedAt:
          type: string
          format: date-time
          nullable: true
        wallet:
          type: string
          description: Managed buyer and payout recipient.
        createdAt:
          type: string
          format: date-time
        legs:
          type: array
          items:
            $ref: '#/components/schemas/ParlayLegResponseDto'
        sourcePack:
          allOf:
            - $ref: '#/components/schemas/ParlaySourcePackDto'
          nullable: true
        payoutAmount:
          type: string
          nullable: true
          description: >-
            Actual settled payout in raw micro-USDC; null while unsettled or
            unavailable.
      required:
        - id
        - status
        - stakeAmount
        - collateralDeposited
        - multiplierOffered
        - vigPercent
        - wallet
        - createdAt
        - legs
        - payoutAmount
      description: >-
        Owned curated Pack position, including in-flight and recoverable
        purchases. Additional display fields may be returned.
    PartnerPackErrorDto:
      type: object
      properties:
        statusCode:
          type: integer
        code:
          type: string
        message:
          type: string
        parlayId:
          type: string
          format: uuid
        submissionState:
          type: string
          enum:
            - NOT_SUBMITTED
        recovery:
          type: string
        tokenAddress:
          type: string
        spender:
          type: string
        requiredAllowance:
          type: string
          description: Required raw micro-USDC allowance.
        retryAfterSeconds:
          type: integer
          minimum: 0
      description: >-
        Recovery metadata is conditional on the error. Do not infer
        non-submission from missing fields or an HTTP status alone.
    ParlayLegResponseDto:
      type: object
      properties:
        id:
          type: string
        legIndex:
          type: number
        marketId:
          type: number
        marketSlug:
          type: string
        marketTitle:
          type: string
        marketImageUrl:
          type: string
          nullable: true
          description: Logo/crest image URL from the leg market
        group:
          nullable: true
          description: Group context for this leg (null for non-grouped markets)
          allOf:
            - $ref: '#/components/schemas/ParlayLegGroupDto'
        leagueName:
          type: string
          nullable: true
          description: >-
            Solo market's own league. Set for solo market legs only; grouped
            legs use `group.leagueName`.
        startMatchTimestamp:
          type: number
          nullable: true
          description: Solo market kickoff time (epoch seconds); null when not scheduled
        conditionId:
          type: string
        outcome:
          type: string
          enum:
            - 'YES'
            - 'NO'
        priceAtCreation:
          type: string
        resolutionStatus:
          type: string
          enum:
            - LOST
            - PENDING
            - WON
            - SPLIT
        resolvedAt:
          type: string
          format: date-time
          nullable: true
        esportsPropType:
          type: string
          enum:
            - map_handicap
            - map_winner
            - 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:
        - id
        - legIndex
        - marketId
        - conditionId
        - outcome
        - priceAtCreation
        - resolutionStatus
    ParlaySourcePackDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name
    ParlayLegGroupDto:
      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
  responses:
    PartnerPackBadRequest:
      description: >-
        Invalid request, ineligible Pack, or a pre-broadcast failure. Inspect
        submissionState and recovery.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
    PartnerPackUnauthorized:
      description: >-
        Missing or invalid authentication. For buy only: the exact Intent
        expired — please retry rejection permits intent renewal.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
    PartnerPackForbidden:
      description: Missing HMAC scopes or invalid managed-account ownership.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
    PartnerPackNotFound:
      description: Pack or position not found, or Packs disabled.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
    PartnerPackConflict:
      description: Conflict. Inspect code, submissionState, and recovery before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
          examples:
            allowanceRequired:
              value:
                code: PACK_ALLOWANCE_REQUIRED
                message: USDC approval to the Pack vault is required for this wallet.
                tokenAddress: '0x0000000000000000000000000000000000000001'
                spender: '0x0000000000000000000000000000000000000002'
                requiredAllowance: '10000000'
            notSubmitted:
              value:
                message: Purchase simulation failed
                parlayId: 33333333-3333-4333-8333-333333333333
                submissionState: NOT_SUBMITTED
                recovery: >-
                  Fix the reported cause, then request a fresh quote and use a
                  new idempotency key. This key remains bound to the failed
                  position.
    PartnerPackUnprocessable:
      description: Insufficient funds or other execution validation failure.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
    PartnerPackRateLimited:
      description: >-
        Partner limit exceeded: 10 requests per 10 seconds per owner. Wait
        retryAfterSeconds.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
          example:
            message: Partner Pack rate limit exceeded
            retryAfterSeconds: 10
    PartnerPackUnavailable:
      description: >-
        Service configuration or rate limiter unavailable; preserve the request
        identity.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PartnerPackErrorDto'
  securitySchemes:
    HmacAuth:
      type: apiKey
      in: header
      name: lmts-api-key
      description: >-
        Scoped API token with HMAC-SHA256 signing. Requires three headers:
        lmts-api-key (token ID), lmts-timestamp (ISO-8601), lmts-signature
        (Base64-encoded HMAC). See Authentication docs for details.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.