Skip to content

Response drift: polymarket — orderPriceMinTickSize absent from Gamma API; tick_size only in CLOB book #800

@realfishsam

Description

@realfishsam

Exchange

polymarket

Severity

MEDIUM

What Our Normalizer Expects

core/src/exchanges/polymarket/utils.ts:130 reads market.orderPriceMinTickSize from the Gamma API market object and maps it to UnifiedMarket.tickSize:

// utils.ts ~line 130
tickSize: market.orderPriceMinTickSize,

No fallback is present for this field.

What The Live API Returns

The Gamma API events endpoint (gamma-api.polymarket.com/events) does not include orderPriceMinTickSize on nested market objects. The field tick_size exists only in the CLOB order book response:

// Gamma API market fields (no orderPriceMinTickSize):
markets[].spread: int
markets[].rewardsMinSize: int
markets[].rewardsMaxSpread: int

// CLOB /book response (tick_size IS present here):
tick_size: str        ← present in CLOB response, not extracted by normalizer
min_order_size: str   ← also present in CLOB response, not extracted

Endpoints tested:

  • GET https://gamma-api.polymarket.com/events?limit=1
  • GET https://clob.polymarket.com/book?token_id={token_id}

Impact

MEDIUM: UnifiedMarket.tickSize will be undefined for all Polymarket markets fetched from the Gamma API. The CLOB order book response contains the correct tick_size but the normalizer doesn't extract it at that call site. This means order placement UI cannot enforce tick-size rounding, potentially causing rejected orders.

Suggested Fix

Two options:

  1. Extract tick_size from the CLOB /book response in normalizeOrderBook and surface it alongside order book data.
  2. In fetchRawMarkets, also fetch the CLOB book for a sample token to capture tick_size, or use the market's spread field as a proxy.

The simpler fix is option 1 — map tick_size from the CLOB response since it's already fetched:

// In normalizeOrderBook (normalizer.ts)
tickSize: raw.tick_size ? parseFloat(raw.tick_size) : undefined,
minOrderSize: raw.min_order_size ? parseFloat(raw.min_order_size) : undefined,

Found by automated response shape drift audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    response-driftLive API response shape differs from normalizer expectations

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions