How to Integrate Polymarket Trading with Outcome Tokens in AI-Trader

AI-Trader treats Polymarket as a spot-like paper-trading market, using Polymarket's public Gamma API for discovery and CLOB for pricing, while handling simulated execution and bookkeeping internally.

The AI-Trader framework from HKUDS supports decentralized prediction market trading by mapping Polymarket outcome tokens to a unified trading interface. Unlike traditional spot markets, Polymarket requires resolution of human-readable outcomes (e.g., Yes/No) to specific ERC-20 token IDs before trading. This guide explains the complete integration workflow using the actual source implementation.

Discovering Markets via the Gamma API

Polymarket market discovery happens entirely outside AI-Trader. According to the [Polymarket skill] documentation, agents must query Polymarket's public Gamma API directly to obtain market definitions.

The endpoint https://gamma-api.polymarket.com/markets returns market metadata including the question, slug, outcome labels, and the critical clobTokenIds array that links each outcome to its on-chain token.

import requests

def resolve_market(slug):
    """Resolve a Polymarket market via Gamma and return token_id/outcome."""
    resp = requests.get(
        "https://gamma-api.polymarket.com/markets",
        params={"slug": slug, "limit": "1"},
    )
    data = resp.json()[0]
    outcomes = data["outcomes"]
    token_ids = data["clobTokenIds"]
    # Assume we want the first outcome (e.g., 'Yes')

    return token_ids[0], outcomes[0]

Resolving References to Outcome Token IDs

Once you have market data, you must map the human-readable outcome to its concrete token_id. The [price_fetcher] module contains two key utilities for this resolution.

Extracting tokens from market data: The helper _polymarket_extract_tokens (lines 302‑312 in price_fetcher.py) parses the outcomes and clobTokenIds arrays from the Gamma response, returning a structured list of {token_id, outcome} pairs.

Resolving trade references: When a trade request supplies a market reference—whether as a slug, conditionId, or raw token_id—the function _polymarket_resolve_reference (lines 315‑369 in price_fetcher.py) deterministically resolves the exact token_id and outcome. This function caches results for fast repeated look-ups, preventing redundant API calls during high-frequency trading scenarios.

Fetching Live Price Data from the CLOB

After resolving the token ID, AI-Trader fetches the current market price from Polymarket's Central Limit Order Book (CLOB). The function _get_polymarket_mid_price (lines 720‑746 in price_fetcher.py) queries https://clob.polymarket.com/book to retrieve the best bid and ask.

It computes the mid-price between bid/ask spread, validates the value against outliers, and falls back to Gamma-provided outcome prices when the CLOB endpoint is unavailable or illiquid. This ensures the paper-trading simulation always has a valid reference price for PnL calculations.

Submitting Trades to the Signals Endpoint

With the token_id and current price established, you submit trades to AI-Trader's /signals endpoint. The [routes_signals] handler enforces Polymarket-specific constraints at lines 75‑94 and 119‑130, validating that:

  • The action is either "buy" or "sell" (short/cover actions are explicitly rejected at lines 110‑113 in [services])
  • The token_id is present for all Polymarket trades (enforced at lines 190‑195 in [services])

Required Payload Structure

{
  "market": "polymarket",
  "symbol": "will-btc-be-above-120k-on-june-30",
  "action": "buy",
  "outcome": "Yes",
  "token_id": "123456789",
  "price": 0,
  "quantity": 20,
  "executed_at": "now"
}

Key fields:

  • market: Must be the literal string "polymarket"
  • symbol: The market slug or conditionId
  • outcome: Human-readable label (e.g., Yes, No)
  • token_id: The concrete CLOB token ID (optional only if the outcome uniquely identifies a single token, though [services] enforces its presence at lines 190‑195)
  • action: Only "buy" or "sell" permitted
  • price: Set to 0—AI-Trader fetches the live price automatically via _get_polymarket_mid_price
  • quantity: Amount of outcome tokens to trade
  • executed_at: Use "now" for immediate execution

Complete Python Client Example

import requests

BASE_URL = "https://ai-trader.example.com"  # replace with your AI-Trader host

SIGNALS_ENDPOINT = f"{BASE_URL}/signals"

def submit_polymarket_trade(slug, action, quantity):
    token_id, outcome = resolve_market(slug)
    payload = {
        "market": "polymarket",
        "symbol": slug,
        "action": action,  # "buy" or "sell"

        "outcome": outcome,
        "token_id": token_id,
        "price": 0,  # ignored – server fetches live price

        "quantity": quantity,
        "executed_at": "now",
    }
    r = requests.post(SIGNALS_ENDPOINT, json=payload)
    r.raise_for_status()
    return r.json()

# Example usage

print(submit_polymarket_trade("will-btc-be-above-120k-on-june-30", "buy", 20))

Direct cURL Alternative


# 1) Resolve the market

curl "https://gamma-api.polymarket.com/markets?slug=will-btc-be-above-120k-on-june-30"

# 2) Submit the trade to AI-Trader

curl -X POST https://ai-trader.example.com/signals \
  -H "Content-Type: application/json" \
  -d '{
        "market": "polymarket",
        "action": "buy",
        "symbol": "will-btc-be-above-120k-on-june-30",
        "outcome": "Yes",
        "token_id": "123456789",
        "price": 0,
        "quantity": 20,
        "executed_at": "now"
      }'

Position Management and Auto-Settlement

When the [routes_signals] handler validates and accepts a payload (lines 218‑238), it forwards the request to the generic trade handler in [services] (lines 190‑213). This service layer persists positions indexed by both token_id and outcome, ensuring accurate tracking of distinct prediction market positions.

Settlement handling: Resolved Polymarket markets are automatically settled by a background task in tasks.py. This task polls the Gamma API for the resolved flag and settlement price, then updates open positions accordingly. This eliminates manual intervention for expired markets while maintaining accurate PnL attribution.

Summary

  • Market Discovery: Query gamma-api.polymarket.com directly; AI-Trader does not proxy discovery
  • Token Resolution: Use _polymarket_resolve_reference in price_fetcher.py (lines 315‑369) to map slugs/outcomes to token_ids
  • Price Fetching: _get_polymarket_mid_price (lines 720‑746) computes mid-prices from the CLOB or falls back to Gamma data
  • Trade Constraints: Submit only buy/sell actions to /signals with required fields market, symbol, outcome, and token_id
  • Validation: routes_signals.py (lines 75‑94) and services.py (lines 190‑213) enforce Polymarket-specific rules including token_id presence and short-sale prohibition
  • Settlement: Background tasks in tasks.py handle automatic resolution of expired markets

Frequently Asked Questions

What is the difference between the Gamma API and the CLOB endpoint?

The Gamma API (gamma-api.polymarket.com) provides static market metadata including questions, slugs, and token IDs. The CLOB (clob.polymarket.com/book) provides dynamic order-book data including live bid/ask prices. AI-Trader uses Gamma for discovery and token resolution, while using CLOB for real-time price fetching.

Why are short and cover actions blocked for Polymarket?

According to services.py lines 110‑113, AI-Trader rejects short and cover actions because Polymarket outcome tokens are spot assets representing discrete event probabilities. Unlike perpetual contracts or margin markets, prediction market tokens cannot be shorted in the traditional sense—you can only sell tokens you already own (position reduction) or buy new ones.

Is the token_id field always required in the trade payload?

Yes. While the resolution logic in price_fetcher.py can sometimes infer a token ID from the outcome name alone, the validation logic in services.py lines 190‑195 explicitly requires token_id to be present in the payload for all Polymarket trades. This prevents ambiguity in markets with multiple outcomes or similar naming.

How does AI-Trader handle market resolution and settlement?

A background task defined in tasks.py periodically scans open Polymarket positions. When the Gamma API indicates a market has resolved: true with a final settlement price, the task automatically updates the position's exit price and realized PnL. This emulates the automatic redemption of outcome tokens at resolution without requiring manual trade closure.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →