PariflowPariflowBlog
Education
Guides
Research
Tools
Start Trading
Pariflow loading
    BlogDeveloper Guides

    How to Build a Trading Bot for Polymarket

    Artem GoryushinAuthor:Artem Goryushin
    |
    18 min read
    |
    May 25, 2026
    |
    Contributors: Pariflow Research Team

    Table of Contents

    Building a trading bot for Polymarket is not just "call an API and buy Yes." A useful bot needs market discovery, real-time prices, a strategy, risk limits, execution controls, storage, monitoring, and a way to stop itself when data gets stale.

    This guide walks through the practical architecture: how to use the Polymarket API, how to design a bot, what to host, and how the same structure can extend to Kalshi and Pariflow.

    It is written for builders, not for hype. Prediction markets are risky. Automated trading can lose money quickly, especially in thin markets or during breaking news. Start read-only, then paper trade, then use small live limits.

    Core Trading Bot Stack

    A production-ready prediction market bot usually has six parts.

    LayerWhat it doesCommon failure
    Market scannerFinds active markets worth trackingTrades stale, low-liquidity, or closed markets
    Data adapterReads market metadata, books, trades, and positionsMixes inconsistent venue formats
    Signal engineEstimates fair probability and edgeConfuses price movement with value
    Risk engineLimits size, exposure, loss, and stale dataLets one bug scale across many markets
    Execution enginePlaces, cancels, and reconciles ordersCreates partial-fill or duplicate-order risk
    MonitoringLogs decisions and alerts humansFails silently while money is at risk

    For Polymarket specifically, the main API layers are:

    • Gamma API: market discovery, events, tags, comments, sports metadata, search, and public profiles.
    • Data API: positions, trades, user activity, holders, open interest, leaderboards, and analytics.
    • CLOB API: order book data, pricing, midpoints, spreads, price history, order placement, and cancellations.
    • WebSocket channels: live market, user, and sports updates when polling is too slow.

    The official Polymarket docs describe these API domains and their current base URLs: https://gamma-api.polymarket.com, https://data-api.polymarket.com, and https://clob.polymarket.com.

    First, Decide What Kind of Bot You Are Building

    Do not start with code. Start with behavior.

    A bot that "trades everything" is usually just an expensive bug. A first bot should do one narrow job well.

    Good first bot types

    Bot typeWhat it doesWhy it is a good start
    Alert botWatches prices and sends opportunities to Telegram, Slack, or emailRead-only, low-risk, easy to validate
    Spread monitorFinds markets with wide bid-ask spreads or thin booksTeaches market microstructure before execution
    Cross-venue monitorCompares similar events across Polymarket, Kalshi, and PariflowUseful for research and possible arbitrage alerts
    Paper traderRecords hypothetical orders and simulated fillsLets you test strategy quality before live trading
    Small market makerPosts passive orders inside strict limitsTeaches execution but requires real risk controls
    Portfolio risk botWatches current exposure and warns when positions overlapSafer than fully automated trading

    For most teams, the right path is:

    1. Build a scanner.
    2. Add alerts.
    3. Add paper trading.
    4. Add manual approval.
    5. Add limited live execution only after the first four steps are reliable.

    Polymarket API Overview

    Polymarket exposes several API surfaces. Your bot should not treat them as one giant endpoint.

    Gamma API for Market Discovery

    Use the Gamma API when the bot needs to answer questions like:

    • Which markets are active?
    • Which event does this market belong to?
    • What are the outcomes?
    • When does the market close?
    • Is the market order-book enabled?
    • What category or tag does this market belong to?

    Example use cases:

    • sync all active politics markets once every few minutes
    • search for markets containing a specific keyword
    • pull outcome labels and token IDs before subscribing to an order book
    • ignore markets that are closed, inactive, or not order-book enabled

    Basic TypeScript example:

    type PolymarketMarket = {
      id: string
      question: string
      slug?: string
      active?: boolean
      closed?: boolean
      enableOrderBook?: boolean
      endDate?: string
      outcomes?: string
      outcomePrices?: string
    }
    
    export async function findPolymarketMarkets(query: string) {
      const url = new URL("https://gamma-api.polymarket.com/markets")
      url.searchParams.set("closed", "false")
      url.searchParams.set("limit", "25")
      url.searchParams.set("q", query)
    
      const response = await fetch(url)
      if (!response.ok) {
        throw new Error(`Gamma API failed with ${response.status}`)
      }
    
      const markets = (await response.json()) as PolymarketMarket[]
    
      return markets.filter((market) => {
        return market.active && !market.closed && market.enableOrderBook
      })
    }
    

    This is market discovery, not execution. Store the result in your database so your worker does not repeatedly rediscover the same markets during every loop.

    CLOB API for Prices, Books, and Trading

    The CLOB API is where trading logic gets serious. It includes public endpoints for order book and pricing data, plus authenticated endpoints for order management.

    Your bot will commonly need:

    • best bid and best ask
    • midpoint price
    • spread
    • full order book depth
    • last trade price
    • historical price data
    • current open orders
    • order placement
    • order cancellation

    Keep CLOB access behind a small adapter:

    export type NormalizedBookLevel = {
      price: number
      size: number
    }
    
    export type NormalizedOrderBook = {
      venue: "polymarket"
      marketId: string
      tokenId: string
      bids: NormalizedBookLevel[]
      asks: NormalizedBookLevel[]
      bestBid: number | null
      bestAsk: number | null
      spread: number | null
      asOf: string
    }
    
    export interface VenueAdapter {
      searchMarkets(query: string): Promise<unknown[]>
      getOrderBook(tokenId: string): Promise<NormalizedOrderBook>
      getPositions(): Promise<unknown[]>
      previewOrder(input: TradeSignal): Promise<QuotePreview>
      placeOrder(input: TradeSignal): Promise<OrderResult>
      cancelOrder(orderId: string): Promise<void>
    }
    

    Why normalize early? Because later you may want the same strategy to compare Polymarket with Kalshi or Pariflow. Your strategy should not care whether a price came from a crypto-native CLOB, a regulated event-contract exchange, or a Pariflow internal market feed.

    WebSockets for Live Updates

    Polling is fine for a scanner. It is often too slow for execution.

    Use WebSockets when you need:

    • faster order book updates
    • user order/fill updates
    • live sports market changes
    • lower-latency market-making decisions

    Do not assume the WebSocket stream will always be clean. Add:

    • reconnect logic
    • stale data detection
    • subscription tracking
    • heartbeat checks
    • fallback polling for reconciliation

    The bot should stop trading if the book is stale, if reconnects are failing, or if the latest book timestamp is outside your tolerance.

    Suggested Project Structure

    For a Node.js or TypeScript bot:

    polymarket-bot/
      src/
        adapters/
          polymarket.ts
          kalshi.ts
          pariflow.ts
        strategy/
          fair-value.ts
          cross-venue.ts
          market-making.ts
        risk/
          limits.ts
          exposure.ts
          kill-switch.ts
        execution/
          paper-broker.ts
          live-broker.ts
          reconciler.ts
        storage/
          db.ts
          schema.ts
        alerts/
          telegram.ts
          slack.ts
        worker.ts
      .env.example
      Dockerfile
      docker-compose.yml
    

    You can build the same thing in Python. The architectural split matters more than the language.

    Environment Variables

    Never hard-code private keys, API keys, or webhook URLs.

    Use a .env.example like this:

    BOT_MODE="paper"
    
    POLYMARKET_HOST="https://clob.polymarket.com"
    POLYMARKET_PRIVATE_KEY="0x..."
    POLYMARKET_FUNDER_ADDRESS="0x..."
    
    DATABASE_URL="postgresql://user:password@localhost:5432/bot"
    REDIS_URL="redis://localhost:6379"
    
    MAX_ORDER_USD="25"
    MAX_MARKET_EXPOSURE_USD="100"
    MAX_DAILY_LOSS_USD="150"
    MAX_SPREAD_BPS="600"
    STALE_BOOK_MS="5000"
    
    ALERT_WEBHOOK_URL="https://hooks.slack.com/..."
    KILL_SWITCH_FILE="/tmp/polymarket-bot.kill"
    

    Use different keys for development, paper mode, and live mode. If a platform supports limited API scopes, do not give a read-only scanner trading permissions.

    Build the Bot Loop

    A simple bot loop should do four things:

    1. Pull or receive market data.
    2. Generate a signal.
    3. Pass the signal through risk checks.
    4. Record or execute the decision.
    type TradeSignal = {
      venue: "polymarket"
      marketId: string
      tokenId: string
      side: "BUY" | "SELL"
      limitPrice: number
      sizeUsd: number
      fairPrice: number
      edgeBps: number
      reason: string
    }
    
    export async function runBotTick() {
      const markets = await scanner.findCandidateMarkets()
    
      for (const market of markets) {
        const book = await polymarket.getOrderBook(market.tokenId)
        const signal = await strategy.evaluate({ market, book })
    
        if (!signal) continue
    
        const riskDecision = await risk.check(signal)
        if (!riskDecision.allowed) {
          await logger.info("signal_skipped", {
            signal,
            reason: riskDecision.reason,
          })
          continue
        }
    
        if (process.env.BOT_MODE === "paper") {
          await paperBroker.record(signal)
          continue
        }
    
        await execution.placeLimitOrder(signal)
      }
    }
    

    The important part is not the syntax. The important part is that every skipped order has a reason, and every live order passed the same risk gate.

    Strategy Design: Start With Probabilities, Not Vibes

    A prediction-market bot needs a view of fair probability.

    That view can come from:

    • a statistical model
    • manually curated probabilities
    • news signals
    • sports data
    • crypto price data
    • cross-venue prices
    • volatility and liquidity filters
    • a human approval queue

    A simple signal rule might be:

    function evaluateEdge(input: {
      fairPrice: number
      bestAsk: number | null
      minEdgeBps: number
    }) {
      if (input.bestAsk === null) return null
    
      const edge = input.fairPrice - input.bestAsk
      const edgeBps = Math.round(edge * 10_000)
    
      if (edgeBps < input.minEdgeBps) return null
    
      return {
        side: "BUY" as const,
        limitPrice: input.bestAsk,
        edgeBps,
      }
    }
    

    This is intentionally simple. Real strategies need more guards:

    • ignore markets close to settlement unless the strategy is built for resolution risk
    • require minimum liquidity
    • avoid very wide spreads
    • avoid markets where the rules are ambiguous
    • reduce size during breaking news
    • avoid duplicate exposure across correlated markets

    Risk Controls That Matter

    Most bot failures are not prediction failures. They are risk-control failures.

    Use hard limits:

    LimitExample
    Max order sizeNever place an order above $25 in early live testing
    Max market exposureNever risk more than $100 on one market
    Max category exposureCap politics, crypto, sports, or macro separately
    Max daily lossStop trading for the day after a fixed drawdown
    Max stale book ageDo not trade if the book is older than 5 seconds
    Max spreadDo not cross an extremely wide spread
    Max open ordersAvoid hundreds of forgotten live orders

    Add a kill switch:

    import fs from "node:fs/promises"
    
    export async function killSwitchEnabled(path = "/tmp/polymarket-bot.kill") {
      try {
        await fs.access(path)
        return true
      } catch {
        return false
      }
    }
    
    export async function assertCanTrade() {
      if (await killSwitchEnabled()) {
        throw new Error("Kill switch enabled")
      }
    }
    

    The kill switch should cancel open orders and stop new orders. It should be easy for a non-developer operator to trigger.

    Paper Trading Before Live Trading

    Paper trading is not optional.

    Run the bot in paper mode long enough to learn:

    • how often it generates signals
    • how often signals disappear before they could fill
    • how much slippage you would have paid
    • which markets create most errors
    • whether alerts fire when they should
    • whether the strategy still works after fees and spread

    Paper fills should be conservative. If you assume every order fills at the midpoint, you are not testing a bot. You are testing a fantasy.

    Better paper-fill logic:

    • marketable order: fill at visible best ask or bid
    • passive order: fill only if the market trades through your price
    • stale book: no fill
    • insufficient depth: partial fill

    Hosting Options

    A trading bot is usually a worker, not a web page.

    You can host the dashboard on Vercel, but the bot itself is usually better as an always-on process.

    Good hosting choices

    Host typeBest forNotes
    VPSMaximum controlUse Docker Compose, systemd, and direct logs
    Fly.io or Railway workerSimple container deploymentGood for always-on processes
    Render background workerEasy managed deploymentWatch sleep and restart behavior
    Google Cloud Run jobs/workersCloud-native teamsGood secrets and logging
    KubernetesLarger trading systemsOverkill for a first bot

    Dockerfile

    FROM node:22-slim AS base
    WORKDIR /app
    
    COPY package*.json ./
    RUN npm ci --omit=dev
    
    COPY . .
    RUN npm run build
    
    CMD ["node", "dist/worker.js"]
    

    Docker Compose

    services:
      bot:
        build: .
        restart: unless-stopped
        env_file: .env
        depends_on:
          - postgres
          - redis
    
      postgres:
        image: postgres:16
        restart: unless-stopped
        environment:
          POSTGRES_PASSWORD: change-me
        volumes:
          - pgdata:/var/lib/postgresql/data
    
      redis:
        image: redis:7
        restart: unless-stopped
    
    volumes:
      pgdata:
    

    Monitoring Checklist

    Track these metrics:

    • last successful market sync
    • last WebSocket message time
    • open order count
    • order placement errors
    • cancellation errors
    • current exposure
    • daily realized and unrealized P&L
    • stale book skips
    • risk gate rejections
    • process restarts

    Send alerts when:

    • the worker restarts repeatedly
    • the WebSocket disconnects
    • order placement fails
    • open orders exceed your limit
    • daily loss limit is reached
    • the database becomes unavailable
    • a reconciliation job finds unknown orders

    Adapting the Bot to Kalshi

    Kalshi is a different venue, not just another endpoint.

    The architecture can transfer, but the adapter must be separate. Kalshi has its own REST and WebSocket API environment URLs, demo and production environments, and authenticated requests signed with a private key. Its docs also distinguish production and demo credentials, so do not mix keys across environments.

    What can stay shared:

    • strategy engine
    • risk limits
    • logging
    • monitoring
    • normalized market model
    • paper trading logic
    • cross-venue comparison UI

    What must be venue-specific:

    • authentication
    • market IDs and tickers
    • order model
    • order book format
    • settlement rules
    • fees and position accounting
    • rate limits
    • compliance and geography rules

    A useful Kalshi adapter shape:

    export class KalshiAdapter implements VenueAdapter {
      async searchMarkets(query: string) {
        // Call Kalshi market endpoints and normalize result shape.
      }
    
      async getOrderBook(ticker: string) {
        // Normalize bid and ask levels into your internal format.
      }
    
      async placeOrder(signal: TradeSignal) {
        // Sign the request with the Kalshi key and private key.
      }
    }
    

    Kalshi is especially useful for regulated U.S. event contracts, but that also means you should read the contract rules carefully. A market can look similar to a Polymarket market while resolving under different terms.

    Adapting the Bot to Pariflow API, MCP, and CLI

    Pariflow is a strong fit for research and workflow tooling because it can expose market search, live odds, order books, portfolio reads, and quote previews through developer interfaces.

    There are three useful integration modes:

    Pariflow toolBot use case
    APIProduct integrations, dashboards, internal services, and backend workers
    MCPAgent workflows, research assistants, market analysis, and guided operator tools
    CLILocal smoke tests, market inspection, order book checks, and operational scripts

    The Pariflow CLI can be used for developer workflows like:

    npm install -g @pariflow/cli
    
    export PARIFLOW_API_KEY="pf_live_..."
    
    pariflow mcp ping
    pariflow tools list --table
    pariflow market search "F1" --table
    pariflow quote will-team-win --side buy --outcome yes --amount 100
    

    The current Pariflow CLI is intentionally preview-oriented: it can inspect tools, search markets, and preview quotes, but it should not be treated as a blind live-execution button.

    That separation is useful. It lets teams build agent and operator workflows where AI can research, summarize, and preview, while a human or controlled backend service owns final execution.

    Five Bot Examples Worth Building

    1. Cross-Venue Probability Monitor

    This bot tracks the same or similar events across Polymarket, Kalshi, and Pariflow.

    It can:

    • normalize market titles and rules
    • compare implied probabilities
    • flag large gaps
    • show liquidity and spread side by side
    • send alerts when the gap is large enough to review

    This is often better than a fully automated arbitrage bot because it helps humans catch real opportunities without pretending every market is perfectly equivalent.

    2. Resolution Risk Watchdog

    This bot watches markets near settlement.

    It can:

    • track close dates
    • read resolution rules
    • compare official source updates
    • flag ambiguous markets
    • warn before an order is placed close to resolution

    This is useful because many bad trades happen when a trader understands the headline but not the settlement text.

    3. Passive Market-Making Bot

    This bot posts limit orders around a fair value estimate.

    It can:

    • quote only when spread is wide enough
    • cancel when news breaks
    • reduce size near close
    • skip low-depth markets
    • cap inventory per side

    Market making is harder than it looks. Start tiny and expect partial fills.

    4. News-to-Market Assistant

    This bot does not need to trade automatically.

    It can:

    • ingest trusted news feeds
    • map news to related markets
    • summarize what changed
    • estimate which side should move
    • create an operator review card

    This works well with MCP-style workflows because an agent can gather context and prepare a note without being allowed to place trades.

    5. Portfolio Exposure Bot

    This bot watches your positions.

    It can:

    • detect correlated exposure
    • warn if one news event affects many markets
    • reduce duplicate risk
    • flag stale positions
    • suggest exits when liquidity disappears

    Many traders need this more than another entry signal.

    Go-Live Checklist

    Before switching from paper to live:

    1. Run read-only mode for several days.
    2. Run paper mode with realistic fill rules.
    3. Review logs for skipped and accepted signals.
    4. Confirm open orders reconcile correctly after restart.
    5. Confirm kill switch cancels orders.
    6. Set tiny live limits.
    7. Add alerting for stale data and order failures.
    8. Keep secrets outside the repo.
    9. Keep venue adapters separate.
    10. Read the market rules before trading a new category.

    If the bot cannot explain why it placed an order, it should not place the order.

    Useful API References

    • Polymarket API documentation for the current API index and endpoint families.
    • Polymarket market data overview for Gamma, CLOB, and Data API roles.
    • Polymarket CLOB client reference for L2 client methods and authenticated CLOB workflows.
    • Kalshi API environments for production and demo REST/WebSocket URLs.
    • Kalshi API keys for request signing and key management.

    Final Takeaway

    The best first Polymarket bot is not a black-box trading machine. It is a disciplined system that reads markets, normalizes data, explains signals, rejects risky trades, logs decisions, and only executes when the setup is clear.

    Build it in layers:

    1. Scanner.
    2. Alerts.
    3. Paper trading.
    4. Human approval.
    5. Tiny live execution.
    6. Multi-venue adapters.

    Once that foundation is solid, you can extend the same bot architecture to Kalshi and Pariflow without rewriting the strategy from scratch.

    Artem Goryushin

    Artem Goryushin

    Artem is a fintech expert and business analyst focused on prediction markets, trading UX, and financial product strategy.

    Share

    Table of Contents

    Explore

    Explore Markets

    Browse hundreds of prediction markets across politics, crypto, sports, and more.

    View all markets

    More on this

    Top 5 Available Polymarket Alternatives in 2026

    A plain-English guide to the best available Polymarket alternatives in 2026, including Kalshi, Pariflow, Robinhood Event Contracts, ForecastEx through IBKR, and Manifold.

    Platform Reviews13 min read

    What Is a Betting Exchange?

    A betting exchange lets users back and lay outcomes against each other. This guide explains how exchanges work, how liability is calculated, and what to watch before trading.

    Getting Started15 min read

    How Do Prediction Markets Work?

    Learn how prediction markets work step by step: Yes-or-No contracts, implied probability, order books, early exits, settlement, and how traders make or lose money.

    Education16 min read

    List of Prediction Market Platforms in 2026: 5 Real Options Compared

    Need a quick list of prediction market platforms? This guide compares Polymarket, Kalshi, Pariflow, Robinhood Event Contracts, and Manifold, with a fast answer first and a deeper breakdown after.

    Platform Reviews14 min read

    Boost your prediction trading

    Put your knowledge into practice. Start trading on prediction markets with Pariflow today.

    Find market

    Learn

    • What is a Prediction Market
    • How to Trade
    • Trading Strategies
    • Market Analysis
    • Tools & Calculators

    Platform

    • Explore Markets
    • Trending
    • New Markets
    • Create Event

    Company

    • About Us
    • Affiliate Program
    • Terms of Service
    • Privacy Policy

    Connect

    • Twitter
    • Discord
    • Telegram
    • Instagram
    PariflowPariflow

    © 2026 Pariflow. All rights reserved.