Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kalshi & Polymarket API Engine

A unified REST API server that aggregates prediction market data from Kalshi and Polymarket, providing access to real-time prices, market metadata, historical time series, order books, and event-level data for forecasting and trading models.

Project Summary

This API engine provides a single interface to access prediction market data from two major platforms: Kalshi and Polymarket. It exposes unified endpoints that normalize data from both platforms, making it easy to build forecasting models, trading algorithms, or analytical tools that work across multiple prediction markets.

Target Markets: All open prediction markets on Kalshi and Polymarket, including political events, sports outcomes, economic indicators, and more.

Features

  • Unified API: Single set of endpoints for both Kalshi and Polymarket
  • Real-time Prices: Get current market prices and bid/ask spreads
  • Market Metadata: Access market titles, descriptions, categories, and status
  • Historical Data: Retrieve time series data for price analysis
  • Order Books: Access order book depth and liquidity information
  • Event-Level Data: Get event groupings and related markets
  • Auto-Detection: Automatically detects which platform a market belongs to
  • Platform Filtering: Optionally filter by specific platform

Quick Setup & Run Instructions

Prerequisites

  • Python 3.8 or higher
  • API credentials for Kalshi (and optionally Polymarket)

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd kalshi-apis
  2. Create a virtual environment (recommended):

    python -m venv venv
    # On Windows:
    venv\Scripts\activate
    # On macOS/Linux:
    source venv/bin/activate
  3. Install dependencies:

    pip install -r requirements.txt
  4. Set up API credentials:

    Create a .env file in the project root (copy from .env.example if available):

    cp .env.example .env

    Then edit .env and add your API credentials (see "Obtaining API Keys" below).

Running the Server

Start the FastAPI server:

uvicorn app.main:app --reload

The API will be available at:

Obtaining API Keys

Kalshi API Keys

  1. Log in to your Kalshi account
  2. Navigate to Account SettingsProfile Settings
  3. Scroll to the API Keys section
  4. Click "Create New API Key"
  5. IMPORTANT: Save both the Key ID and the RSA Private Key immediately
    • The private key is shown only once and cannot be retrieved later
    • Copy the entire private key including the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- lines
  6. Add them to your .env file:
    KALSHI_KEY_ID=your_key_id_here
    KALSHI_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----
    your_private_key_here
    -----END RSA PRIVATE KEY-----
    

For detailed instructions, see Kalshi API Documentation.

Polymarket API Keys (Required for Trades/Orderbook)

Polymarket's CLOB API endpoints (trades and orderbook) require authentication. Market metadata and prices are available without authentication, but historical trades and orderbook data require API credentials.

To get Polymarket API credentials:

  1. Log in to your Polymarket account
  2. Navigate to Builder ProfileBuilder Keys
  3. Click "+ Create New"
  4. Save the three values: apiKey, secret, and passphrase
  5. You also need your Polygon wallet private key (the private key of the wallet you use with Polymarket)
  6. Add them to your .env file:
    POLYMARKET_API_KEY=your_api_key_here
    POLYMARKET_SECRET=your_secret_here
    POLYMARKET_PASSPHRASE=your_passphrase_here
    POLYMARKET_POLYGON_PRIVATE_KEY=your_polygon_wallet_private_key_here
    

Note:

  • Market metadata and prices work without authentication (using public Gamma API)
  • Historical trades (/history) and orderbook (/orderbook) require authentication
  • The Polygon private key is used to sign requests (EIP-712 signature)
  • Keep your private key secure and never commit it to version control

For detailed instructions, see Polymarket API Documentation.

API Endpoints

Health Check

  • GET /api/v1/health - Check API status and platform availability

Markets

  • GET /api/v1/markets - List all open markets (supports ?platform=kalshi or ?platform=polymarket filter)
  • GET /api/v1/markets/{market_id}/price - Get real-time price for a market
  • GET /api/v1/markets/{market_id}/metadata - Get market metadata
  • GET /api/v1/markets/{market_id}/history - Get historical time series
  • GET /api/v1/markets/{market_id}/orderbook - Get order book data
  • GET /api/v1/markets/{market_id}/events - Get event-level data

Example Requests

# Get all markets
curl http://localhost:8000/api/v1/markets

# Get markets from Kalshi only
curl http://localhost:8000/api/v1/markets?platform=kalshi

# Get price for a specific market
curl http://localhost:8000/api/v1/markets/POLITICS-TRADE-2024-11-05/price

# Get market metadata
curl http://localhost:8000/api/v1/markets/POLITICS-TRADE-2024-11-05/metadata

Design Decisions

Technology Choices

  • FastAPI: Chosen for its async support, automatic OpenAPI documentation, type safety with Pydantic, and excellent performance
  • Kalshi Python SDK: Uses the official Kalshi SDK for reliable authentication and API access
  • Requests Library: Used for Polymarket API calls (public endpoints don't require special SDK)
  • Pydantic Models: Standardized data models ensure consistent API responses across platforms

Architecture

  • Unified API Approach: Single set of endpoints that aggregate both platforms, making it easier for clients to consume data without platform-specific logic
  • Modular Structure: Separate client wrappers for each platform (app/kalshi/, app/polymarket/) for maintainability
  • Data Normalization: Utility functions normalize platform-specific data formats into standardized schemas
  • Environment Variables: Secure credential management without hardcoding sensitive information
  • Graceful Degradation: API continues to work even if one platform's credentials are missing

Data Normalization

The API normalizes data from both platforms into consistent formats:

  • Market identifiers are preserved but responses include platform information
  • Price data is standardized (yes/no prices, volume, timestamps)
  • Order books are normalized to a common bid/ask structure
  • Historical data uses consistent timestamp and price formats

Dependencies

  • fastapi (0.104.1) - Web framework for building APIs
  • uvicorn (0.24.0) - ASGI server for running FastAPI
  • python-dotenv (1.0.0) - Environment variable management
  • kalshi (1.0.0) - Official Kalshi Python SDK
  • requests (2.31.0) - HTTP client for Polymarket API calls
  • pydantic (2.5.0) - Data validation and settings management

Known Limitations

  1. Polymarket Market Data:

    • Markets List: Working via Gamma API (gamma-api.polymarket.com/markets)
    • Market Metadata: Working (fetches from markets list)
    • Market Price: Working (extracted from market data)
    • Market Events: Working (fetches from Gamma API, but may return empty for old markets)
    • Market History/Trades: Requires authentication - CLOB API /trades endpoint returns 401 Unauthorized without API credentials. Returns empty data gracefully when authentication is missing.
    • Orderbook: May require authentication - CLOB API /book endpoint may require credentials. Returns empty data gracefully when authentication is missing.

    Current Status:

    • Kalshi integration: Fully functional
    • Polymarket integration: Markets, metadata, prices, and events work without authentication
    • Polymarket history and orderbook: Require API credentials (see "Obtaining API Keys" section)

    Workarounds:

    • The API gracefully handles missing Polymarket credentials by returning empty data for protected endpoints
    • For full Polymarket functionality (trades/orderbook), add API credentials to .env file
    • See "Obtaining API Keys" section for instructions on getting Polymarket Builder API credentials
  2. Authentication: Kalshi requires valid API credentials. The API will fail gracefully if credentials are missing, but Kalshi endpoints will be unavailable.

  3. Market ID Format: Market IDs differ between platforms:

    • Kalshi uses ticker symbols (e.g., POLITICS-TRADE-2024-11-05)
    • Polymarket uses UUIDs or slugs
    • The API attempts auto-detection, but specifying the platform parameter is recommended for reliability
  4. Rate Limiting: Both platforms may implement rate limiting. The current implementation doesn't include rate limiting logic - this should be added for production use.

  5. Historical Data Format: Historical data formats vary between platforms and may require additional normalization for specific use cases.

  6. Error Handling: Some platform-specific errors may not be fully normalized. Check the raw_data field in responses for platform-specific information.

  7. Events Endpoint for Old Markets: The /api/v1/markets/{market_id}/events endpoint may return empty results for old or archived markets. Polymarket's events API only returns recent/active events (typically the last 100-1000 events). Markets from previous years (e.g., 2023) may not appear in the events list because:

    • The events API is paginated and primarily returns current/active events
    • Archived or closed events may not be included in the default response
    • Old markets may not be associated with any events in the current events list

    Workaround: For testing, use recent market IDs. The events endpoint works correctly for current markets.

  8. Kalshi SDK History Method: The Kalshi SDK may not have a consistent method name for fetching market history across different SDK versions. The implementation tries multiple method names (get_market_history, get_trades, get_market_trades), but if none are available, it returns an empty history array instead of raising an error. This allows graceful degradation but means some markets may show no history even if data exists.

  9. Polymarket Market Lookup Performance: When looking up a specific Polymarket market by ID, the implementation searches through paginated results (up to 20 pages, 1000 markets per page). This can be slow for markets that appear later in the pagination. The search stops once the market is found, but worst-case performance may require checking up to 20,000 markets.

  10. Platform Auto-Detection Edge Cases: When the platform parameter is not specified, the API tries both platforms and returns the first one with valid data. However, if both platforms return empty data (e.g., empty price arrays, empty orderbooks), the API may return empty data from the first platform tried (Kalshi) instead of trying the second platform. This is intentional to prevent unnecessary API calls, but may result in missed data.

  11. Empty Responses Without Errors: Some endpoints may return empty arrays or null values without raising errors. This is normal behavior and does not indicate an error:

  • History endpoints (/history): May return empty data_points arrays if:
    • No trades have occurred yet for the market
    • Historical data is not available for that market
    • The market is new and hasn't accumulated trading history
  • Orderbook endpoints (/orderbook): May return empty bids and asks arrays if:
    • No active orders exist for the market
    • The market is temporarily inactive
    • The market has low liquidity
  • Events endpoints (/events): May return empty arrays if:
    • The market is not associated with any events
    • The market is too old (see limitation #7)
  • Price endpoints (/price): May return null for price fields if:
    • No trades have occurred yet
    • The market hasn't opened for trading
  • This is by design to allow graceful degradation. Always check for empty data or null values in your client code before using the response.
  1. Pagination Limits:

    • Polymarket markets endpoint: Limited to searching 20 pages (20,000 markets max) when looking up a specific market
    • Kalshi markets endpoint: Limited by the limit parameter (max 1000 per request)
    • Events endpoint: Limited to 100-1000 events per request depending on the platform
    • For larger datasets, multiple requests with pagination parameters may be needed
  2. Request Timeouts: Polymarket API requests have a 10-second timeout. Slow network connections or API delays may cause timeouts. The implementation doesn't retry failed requests automatically.

  3. Optional Fields: Many response fields are optional and may be None:

    • Price fields (yes_price, no_price) may be None if no trades have occurred
    • end_date, description, category may be missing for some markets
    • volume, open_interest may be None or 0 for inactive markets
    • Always check for None values before using these fields in calculations
  4. Python Version Compatibility: The project requires Python 3.10+ (due to FastAPI and Pydantic v2 requirements). Python 3.13 compatibility has been tested, but older Python versions may have issues with dependency versions.

  5. SDK Version Dependencies:

    • kalshi-python>=1.0.0 is required for API key authentication
    • SDK method names and response formats may vary between versions
    • The implementation includes fallbacks for different SDK versions, but some features may not work with older SDK versions

Sample Output

Market List Response

{
  "markets": [
    {
      "market_id": "POLITICS-TRADE-2024-11-05",
      "platform": "kalshi",
      "title": "Will the election outcome be decided by Nov 5?",
      "status": "open",
      "end_date": "2024-11-05T23:59:59Z"
    }
  ],
  "total": 1,
  "platform": null
}

Price Data Response

{
  "market_id": "POLITICS-TRADE-2024-11-05",
  "platform": "kalshi",
  "yes_price": 0.65,
  "no_price": 0.35,
  "last_price": 0.65,
  "volume": 125000,
  "open_interest": 50000
}

Repository Structure

kalshi-apis/
├── app/
│   ├── __init__.py
│   ├── main.py              # FastAPI application
│   ├── config.py             # Configuration management
│   ├── kalshi/
│   │   ├── __init__.py
│   │   └── client.py         # Kalshi API client wrapper
│   ├── polymarket/
│   │   ├── __init__.py
│   │   └── client.py         # Polymarket API client wrapper
│   ├── models/
│   │   ├── __init__.py
│   │   └── schemas.py        # Pydantic data models
│   └── utils/
│       ├── __init__.py
│       └── normalizers.py    # Data normalization utilities
├── examples/
│   └── sample_query.py       # Sample usage script
├── .env.example              # Environment variable template
├── .gitignore                # Git ignore rules
├── requirements.txt          # Python dependencies
├── README.md                 # This file
└── index.html               # Project submission HTML site

License

This project is provided as-is for educational and research purposes.

Support

For issues or questions:

About

Unified REST API for Kalshi and Polymarket prediction markets. Access real-time prices, market metadata, historical time series, order books, and event-level data through a single interface. Built with FastAPI.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages