Skip to main content

Python SDK for Limitless Exchange

Project description

Limitless Exchange Python SDK

A minimalistic, async Python SDK for interacting with the Limitless Exchange API.

Features

  • 🔐 API Key authentication - Simple and secure authentication with API keys
  • 📈 Market data access - Markets, orderbooks, and historical data
  • 📋 Order management - GTC and FOK orders with automatic signing
  • 💼 Portfolio tracking - Positions and user history
  • 🔄 Automatic retries - Configurable retry logic with error handling
  • 🌐 WebSocket support - Real-time orderbook updates
  • 🛡️ Custom headers - Global and per-request header configuration
  • Async/await support - Modern async Python with aiohttp
  • 🚀 Venue caching - Automatic contract address caching for optimized order creation

⚠️ Disclaimer

USE AT YOUR OWN RISK

This SDK is provided "as-is" without any warranties or guarantees. Trading on prediction markets involves financial risk. By using this SDK, you acknowledge that:

  • You are responsible for testing the SDK thoroughly before using it in production
  • The SDK authors are not liable for any financial losses or damages
  • You should review and understand the code before executing any trades
  • It is recommended to test all functionality on testnet or with small amounts first
  • The SDK may contain bugs or unexpected behavior despite best efforts

Feedback Welcome: We encourage you to report any bugs, suggest improvements, or contribute to the project. Please submit issues or pull requests on our GitHub repository.

🌍 Geographic Restrictions

Important: Limitless restricts order placement from US locations due to regulatory requirements and compliance with international sanctions. Before placing orders, builders should verify their location complies with applicable regulations.

Installation

pip install limitless-sdk

Quick Start

import asyncio
import os
from limitless_sdk.api import HttpClient
from limitless_sdk.markets import MarketFetcher
from limitless_sdk.portfolio import PortfolioFetcher

async def main():
    # Setup - API key automatically loaded from LIMITLESS_API_KEY env variable
    http_client = HttpClient(base_url="https://api.limitless.exchange")

    try:
        # Get markets
        market_fetcher = MarketFetcher(http_client)
        markets = await market_fetcher.get_active_markets()
        print(f"Found {markets.total_markets_count} markets")

        # Fetch specific market (caches venue data for orders)
        market = await market_fetcher.get_market("bitcoin-2024")
        print(f"Market: {market.title}")

        # Get positions (requires authentication)
        portfolio_fetcher = PortfolioFetcher(http_client)
        positions = await portfolio_fetcher.get_positions()
        print(f"CLOB positions: {len(positions['clob'])}")

    finally:
        await http_client.close()

if __name__ == "__main__":
    asyncio.run(main())

Authentication

The SDK uses API keys for authentication. API keys can be obtained from your Limitless Exchange account settings.

Basic Authentication

import os
from limitless_sdk.api import HttpClient

# Option 1: Automatic from environment variable (recommended)
# Set LIMITLESS_API_KEY in your .env file or environment
http_client = HttpClient()

# Option 2: Explicit API key
http_client = HttpClient(
    api_key=os.getenv("LIMITLESS_API_KEY")
)

# Option 3: Custom base URL (for dev/staging)
http_client = HttpClient(
    base_url="https://staging.api.limitless.exchange",
    api_key="sk_test_..."
)

# All requests automatically include X-API-Key header

Environment Variables

Create a .env file in your project root:

# Required for authenticated endpoints
LIMITLESS_API_KEY=sk_live_your_api_key_here

# Optional: Custom API URL (defaults to production)
# LIMITLESS_API_URL=https://api.limitless.exchange

Custom HTTP Headers

You can configure custom headers globally (applied to ALL requests) or per-request:

# Global headers (applied to all requests)
http_client = HttpClient(
    additional_headers={
        "X-Custom-Header": "value",
        "X-API-Version": "v1"
    }
)

# Per-request headers (request ID, tracing, etc.)
response = await http_client.get("/endpoint", headers={"X-Request-ID": "123"})

Market Data

Get Markets

from limitless_sdk.markets import MarketFetcher

market_fetcher = MarketFetcher(http_client)

# Get active markets (paginated)
markets = await market_fetcher.get_active_markets({"page": 1, "limit": 50})
print(f"Total: {markets.total_markets_count}")
print(f"Markets: {len(markets.data)}")

# Get specific market (automatically caches venue data)
market = await market_fetcher.get_market("market-slug")
print(f"Title: {market.title}")
print(f"YES Token: {market.tokens.yes}")
print(f"NO Token: {market.tokens.no}")

# Venue data is now cached for efficient order creation
# Includes: exchange address (for signing) and adapter address (for NegRisk approvals)

Get Orderbook

orderbook = await market_fetcher.get_orderbook("market-slug")

# Access bids/asks
for order in orderbook.get('orders', []):
    print(f"Price: {order['price']}, Size: {order['size']}")

Token Approvals

Important: Before placing orders, you must approve tokens for the exchange contracts. This is a one-time setup per wallet.

Required Approvals

CLOB Markets:

  • BUY orders: Approve USDC → market.venue.exchange
  • SELL orders: Approve Conditional Tokens → market.venue.exchange

NegRisk Markets:

  • BUY orders: Approve USDC → market.venue.exchange
  • SELL orders: Approve Conditional Tokens → both market.venue.exchange AND market.venue.adapter

Quick Setup

Run the approval setup script:

# Configure your wallet in .env
python examples/00_setup_approvals.py

Manual Approval Example

from web3 import Web3
from eth_account import Account
from limitless_sdk.markets import MarketFetcher
from limitless_sdk.utils.constants import get_contract_address

# 1. Fetch market to get venue addresses
market = await market_fetcher.get_market('market-slug')

# 2. Initialize Web3 and wallet
w3 = Web3(Web3.HTTPProvider('https://mainnet.base.org'))
account = Account.from_key(private_key)

# 3. Get contract addresses
usdc_address = get_contract_address("USDC", 8453)
ctf_address = get_contract_address("CTF", 8453)

# 4. Create contract instances
usdc = w3.eth.contract(address=usdc_address, abi=ERC20_APPROVE_ABI)
ctf = w3.eth.contract(address=ctf_address, abi=ERC1155_APPROVAL_ABI)

# 5. Approve USDC for BUY orders
max_uint256 = 2**256 - 1
tx = usdc.functions.approve(venue.exchange, max_uint256).build_transaction({...})
signed_tx = account.sign_transaction(tx)
w3.eth.send_raw_transaction(signed_tx.raw_transaction)

# 6. Approve CT for SELL orders
tx = ctf.functions.setApprovalForAll(venue.exchange, True).build_transaction({...})
signed_tx = account.sign_transaction(tx)
w3.eth.send_raw_transaction(signed_tx.raw_transaction)

# 7. For NegRisk SELL orders, also approve adapter
if market.neg_risk_request_id:
    tx = ctf.functions.setApprovalForAll(venue.adapter, True).build_transaction({...})
    signed_tx = account.sign_transaction(tx)
    w3.eth.send_raw_transaction(signed_tx.raw_transaction)

For complete examples with proper ABIs and transaction handling, see examples/00_setup_approvals.py.

Order Management

The SDK supports two order types:

  • GTC (Good-Till-Cancelled): Uses price + size parameters
  • FOK (Fill-Or-Kill): Uses maker_amount (total USDC to spend/receive)

Create GTC Orders

from limitless_sdk.orders import OrderClient
from limitless_sdk.types import Side, OrderType

# Setup order client (userData fetched automatically from profile)
order_client = OrderClient(
    http_client=http_client,
    wallet=account,
)

# Get token ID from market
token_id = str(market.tokens.yes)  # or market.tokens.no

# Create BUY GTC order
order = await order_client.create_order(
    token_id=token_id,
    price=0.50,      # Minimum acceptable price
    size=5.0,        # Number of shares
    side=Side.BUY,
    order_type=OrderType.GTC,
    market_slug=market.slug
)

print(f"Order ID: {order.order.id}")
print(f"Status: {order.order.status}")

Create FOK Orders

FOK (Fill-Or-Kill) orders either execute immediately and completely or are cancelled. They use maker_amount instead of price/size parameters.

Parameter Semantics:

  • BUY orders: maker_amount = total USDC to spend (e.g., 10.0 = $10 USDC)
  • SELL orders: maker_amount = number of shares to sell (e.g., 18.64 shares)
# FOK BUY order - spend $10 USDC
order = await order_client.create_order(
    token_id=token_id,
    maker_amount=10.0,   # Spend $10 USDC
    side=Side.BUY,
    order_type=OrderType.FOK,
    market_slug=market.slug
)

# FOK SELL order - sell 18.64 shares
order = await order_client.create_order(
    token_id=token_id,
    maker_amount=18.64,  # Sell 18.64 shares
    side=Side.SELL,
    order_type=OrderType.FOK,
    market_slug=market.slug
)

# Check if filled
if order.maker_matches and len(order.maker_matches) > 0:
    print(f"FILLED: {len(order.maker_matches)} matches")
else:
    print("NOT FILLED (cancelled)")

Cancel Orders

# Cancel single order by ID
await order_client.cancel(order_id)

# Cancel all orders for a market
await order_client.cancel_all(market_slug)

Portfolio

Get Positions

from limitless_sdk.portfolio import PortfolioFetcher

portfolio_fetcher = PortfolioFetcher(http_client)

# Get positions
positions = await portfolio_fetcher.get_positions()

# Access CLOB positions
clob_positions = positions['clob']
for position in clob_positions:
    print(f"Market: {position['market']['title']}")
    print(f"Size: {position['size']}")

# Access points
print(f"Points: {positions['accumulativePoints']}")

WebSocket Support

Subscribe to real-time orderbook updates:

from limitless_sdk.websocket import WebSocketClient, WebSocketConfig

# Setup WebSocket
config = WebSocketConfig(
    url="wss://ws.limitless.exchange",
    auto_reconnect=True,
    reconnect_delay=1.0
)
ws_client = WebSocketClient(config=config)

# Event handlers
@ws_client.on('connect')
async def on_connect():
    print("Connected")

@ws_client.on('orderbookUpdate')
async def on_orderbook_update(data):
    orderbook = data.get('orderbook', data)
    best_bid = orderbook['bids'][0]['price']
    best_ask = orderbook['asks'][0]['price']
    print(f"Bid: {best_bid:.4f} | Ask: {best_ask:.4f}")

# Connect and subscribe
await ws_client.connect()
await ws_client.subscribe('subscribe_market_prices', {'marketSlugs': [market_slug]})

Error Handling

The SDK provides APIError for all API-related errors:

from limitless_sdk.api import APIError

try:
    order = await order_client.create_order(...)
except APIError as e:
    print(f"Status: {e.status_code}")
    print(f"Error: {e}")  # Prints raw API response JSON

Retry Mechanism

Use the @retry_on_errors decorator for custom retry logic:

from limitless_sdk.api import retry_on_errors

@retry_on_errors(
    status_codes={500, 429},
    max_retries=3,
    delays=[1, 2, 3],
    on_retry=lambda attempt, error, delay: print(f"Retry {attempt+1}/3")
)
async def fetch_data():
    return await http_client.get("/endpoint")

Logging

Enable debug logging to see request headers and details:

from limitless_sdk.types import ConsoleLogger, LogLevel

logger = ConsoleLogger(level=LogLevel.DEBUG)
http_client = HttpClient(base_url="...", logger=logger)

Architecture

The SDK is organized into modular components:

Core Components

  • HttpClient: Low-level HTTP client with API key authentication and retry logic
  • OrderSigner: EIP-712 message signing for order creation
  • RetryableClient: Auto-retry wrapper with configurable retry strategies

Domain Components

  • MarketFetcher: Market data retrieval (markets, orderbooks)
  • OrderClient: Order creation/cancellation with automatic signing
  • PortfolioFetcher: Portfolio and positions data
  • WebSocketClient: Real-time orderbook updates

Type System

The SDK uses Pydantic models for type safety:

  • UserProfile: User account information
  • Side: BUY / SELL enum
  • OrderType: GTC / FOK enum
  • LogLevel: DEBUG / INFO / WARN / ERROR enum
  • Market: Market metadata and configuration

Examples

See the examples/ directory for complete working examples:

  • 01_authentication.py - API key authentication with portfolio data
  • 02_create_buy_gtc_order.py - Create BUY GTC order
  • 03_cancel_gtc_order.py - Cancel orders (single or all)
  • 04_create_sell_gtc_order.py - Create SELL GTC order
  • 05_create_buy_fok_order.py - Create BUY FOK order
  • 06_create_sell_fok_order.py - Create SELL FOK order
  • 06_retry_handling.py - Custom retry logic with @retry_on_errors
  • 07_auto_retry_second_sample.py - Auto-retry with RetryableClient
  • 08_websocket_events.py - Real-time orderbook updates

Development

Setup

git clone https://github.com/limitless-labs-group/limitless-exchange-ts-sdk.git
cd limitless-sdk
pip install -e ".[dev]"

Testing

pytest

Linting

ruff check .
mypy limitless_sdk/

License

MIT License - see LICENSE file for details.

Support

For questions or issues:

Key Features

Venue Caching System

The SDK automatically caches venue data (exchange and adapter contract addresses) to optimize performance when creating multiple orders for the same market.

How it works:

# Fetch market once
market_fetcher = MarketFetcher(http_client)
market = await market_fetcher.get_market("bitcoin-2024")

# Venue data is now cached automatically
# {
#   exchange: "0xa4409D988CA2218d956BeEFD3874100F444f0DC3",  # for order signing
#   adapter: "0x5a38afc17F7E97ad8d6C547ddb837E40B4aEDfC6"    # for NegRisk approvals
# }

# Create order client (userData fetched automatically from profile on first order)
order_client = OrderClient(http_client, wallet)

# Venue is fetched from cache (no API call)
# User data is fetched automatically on first order creation
order1 = await order_client.create_order(
    token_id=str(market.tokens.yes),
    price=0.50,
    size=5.0,
    side=Side.BUY,
    order_type=OrderType.GTC,
    market_slug=market.slug
)

# Still using cached venue data and user data
order2 = await order_client.create_order(
    token_id=str(market.tokens.no),
    price=0.30,
    size=10.0,
    side=Side.BUY,
    order_type=OrderType.GTC,
    market_slug=market.slug
)

Performance benefits:

  • Eliminates redundant /venues/:slug API calls
  • Faster order creation (cache hit vs network request)
  • Reduced API rate limit usage

Debug logging: Enable debug mode to see venue cache operations:

logger = ConsoleLogger(level=LogLevel.DEBUG)
http_client = HttpClient(base_url="...", logger=logger)

# You'll see:
# [Limitless SDK] Venue cached for order signing {
#   slug: 'bitcoin-2024',
#   exchange: '0xa4409D988CA2218d956BeEFD3874100F444f0DC3',
#   adapter: '0x5a38afc17F7E97ad8d6C547ddb837E40B4aEDfC6',
#   cacheSize: 1
# }
# [Limitless SDK] Venue cache hit { slug: 'bitcoin-2024', exchange: '0xa4...' }

Token ID Extraction

CLOB markets use a tokens object for YES/NO positions:

# Get YES token ID
token_id = str(market.tokens.yes)

# Get NO token ID
token_id = str(market.tokens.no)

Raw API Responses

The SDK returns raw API responses without heavy parsing, allowing direct access to all fields:

# Markets response
markets = await market_fetcher.get_markets()
total = markets['totalCount']
data = markets['data']

# Positions response
positions = await portfolio_fetcher.get_positions()
clob = positions['clob']
points = positions['accumulativePoints']

Order Type Parameters

  • GTC orders: Use price + size parameters

    price=0.50,  # Minimum acceptable price (0-1 range)
    size=5.0     # Number of shares to buy/sell
    
  • FOK orders: Use maker_amount parameter (semantics differ by side)

    # BUY: Total USDC to spend
    maker_amount=10.0  # Spend $10 USDC to buy shares
    
    # SELL: Number of shares to sell
    maker_amount=18.64 # Sell 18.64 shares for USDC
    

Changelog

v1.0.0

Release Date: January 2026

This is the first stable, production-ready release of the Limitless Exchange Python SDK, designated as a Long-Term Support (LTS) version. This release consolidates all features and improvements from pre-release versions into a stable, well-documented, and thoroughly tested SDK.

Core Features

  • 🔐 Authentication & Security

    • API key authentication with X-API-Key header
    • EIP-712 message signing for order creation
    • OrderSigner for cryptographic order signing operations
    • AuthenticationError for authentication failure handling
    • Secure API key management from environment variables
  • 📊 Market Data Access

    • MarketFetcher with intelligent venue caching system
    • Active markets retrieval with pagination and sorting
    • Market-specific data fetching (slug-based)
    • Real-time orderbook data
    • Automatic venue data caching for performance optimization
    • Cache-aware market operations (eliminates redundant API calls)
  • 📋 Order Management

    • OrderClient for comprehensive order operations
    • GTC Orders (Good-Till-Cancelled): price + size parameters
    • FOK Orders (Fill-Or-Kill): maker_amount parameter
      • BUY: maker_amount = total USDC to spend
      • SELL: maker_amount = number of shares to sell
    • Automatic EIP-712 order signing with venue.exchange integration
    • Dynamic venue resolution from cache or API
    • Order cancellation (single order and batch operations)
    • Maker match tracking and order status monitoring
  • 💼 Portfolio Management

    • PortfolioFetcher for position tracking
    • CLOB position data retrieval
    • User history access
    • Accumulative points tracking
    • Portfolio-wide analytics
  • 🌐 WebSocket Support

    • WebSocketClient for real-time orderbook updates
    • Event-based subscription system with decorators
    • Auto-reconnect functionality with configurable delays
    • Typed event handlers for orderbook updates
    • Connection lifecycle management
  • 🔄 Retry & Error Handling

    • @retry_on_errors decorator with customizable retry logic
    • RetryableClient for automatic retry on transient failures
    • Configurable delays and maximum retry attempts
    • Status code-based retry strategies
    • Comprehensive APIError exception hierarchy (AuthenticationError, RateLimitError, ValidationError)
  • 📝 Logging & Debugging

    • ConsoleLogger with configurable log levels (DEBUG, INFO, WARN, ERROR)
    • Enhanced debug logging for venue operations
    • Venue cache monitoring (hits/misses)
    • Request/response logging with header visibility
    • Performance tracking and observability
  • 🛡️ Token Approval System

    • Complete token approval setup guide
    • CLOB market approval workflows
    • NegRisk market dual-approval requirements
    • Web3 integration examples
    • ERC-20 (USDC) and ERC-1155 (Conditional Tokens) support

Performance & Optimization

  • Venue Caching: Automatic venue data caching eliminates redundant API calls
  • Connection Pooling: Efficient HTTP client with aiohttp connection pooling
  • Async/Await: Full async support for optimal performance
  • Session Reuse: Persistent HTTP sessions for improved performance
  • Custom Headers: Global and per-request header configuration

Documentation & Examples

  • Comprehensive README: 650+ lines covering all features

  • 9 Working Examples:

    1. 00_setup_approvals.py - Token approval setup
    2. 01_authentication.py - API key authentication with portfolio data
    3. 02_create_buy_gtc_order.py - GTC BUY orders
    4. 03_cancel_gtc_order.py - Order cancellation
    5. 04_create_sell_gtc_order.py - GTC SELL orders
    6. 05_create_buy_fok_order.py - FOK BUY orders
    7. 06_create_sell_fok_order.py - FOK SELL orders
    8. 06_retry_handling.py - Custom retry logic
    9. 07_auto_retry_second_sample.py - Auto-retry patterns with RetryableClient
    10. 08_websocket_events.py - Real-time WebSocket events
  • Documentation Quality Improvements:

    • Accurate FOK order parameter documentation (BUY vs SELL semantics)
    • Clear GTC order price parameter explanations
    • Comprehensive venue system documentation
    • Token approval requirements by market type
    • Best practices for venue caching and performance

Architecture

  • Modular Design: Clean separation of concerns with focused components
  • Type Safety: Full Pydantic model integration for type validation
  • Extensibility: Easy to extend with custom authentication or signing logic
  • Standards Compliance: Follows Python async best practices

Quality Assurance

  • Production-ready code quality
  • Comprehensive error handling
  • Well-documented public APIs
  • Consistent coding patterns
  • Validated against live Base mainnet

Breaking Changes from Pre-Release

None - this is the first stable release. All pre-release versions (v0.x) were development versions leading to this LTS release.


Pre-Release Versions

The following versions were development releases leading to v1.0.0:

v0.3.1 (Pre-release)

  • Venue caching system implementation
  • Enhanced debug logging
  • Venue system documentation

v0.3.0 (Pre-release)

  • Modular architecture refactor
  • WebSocket support
  • Enhanced authentication system
  • HTTP client improvements
  • Order system enhancements

v0.2.0 (Pre-release)

  • Added additional_headers parameter to HttpClient
  • Global and per-request header configuration
  • RetryableClient for automatic retry on transient failures
  • WebSocket support for real-time updates
  • Retry decorator (@retry_on_errors)
  • Comprehensive examples directory
  • Fixed license configuration in pyproject.toml

v0.1.0 (Pre-release)

  • Initial release
  • API key authentication with X-API-Key header
  • EIP-712 signing for order creation
  • Market data access
  • GTC and FOK order support
  • Portfolio tracking

LTS Support Policy

v1.0.0 LTS will receive:

  • Security updates and critical bug fixes
  • Compatibility maintenance with Limitless Exchange API
  • Community support and issue resolution
  • Documentation updates and improvements

For production deployments, we recommend using the LTS version for stability and long-term support.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

limitless_sdk-1.0.2.tar.gz (62.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

limitless_sdk-1.0.2-py3-none-any.whl (64.5 kB view details)

Uploaded Python 3

File details

Details for the file limitless_sdk-1.0.2.tar.gz.

File metadata

  • Download URL: limitless_sdk-1.0.2.tar.gz
  • Upload date:
  • Size: 62.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for limitless_sdk-1.0.2.tar.gz
Algorithm Hash digest
SHA256 adc6489d8d8f344158a176917373d86b0158c3961c6c99221cf224895e422dfd
MD5 8cb0e1ad69d89b11f92644602d6066a7
BLAKE2b-256 a613d324ce8a6b62c243024d6f5d9bb01818f6ce8762413bdd5c65460af44126

See more details on using hashes here.

File details

Details for the file limitless_sdk-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: limitless_sdk-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 64.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for limitless_sdk-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c4c94d5a2e79495a65108c8b20745d36b4de77289a11ba48c8eacfc58c1da1e5
MD5 8209371e307d74d46facef6420f71ca4
BLAKE2b-256 7429d50df6b3dc65cadd04f28f3ff21f790f70a0801656f966bb0eacf25c7ee1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page