Skip to main content

Endpoints

Instruments & Symbols

MethodEndpointDescription
POST/v1/refdata/symbolsList all symbols
POST/v1/refdata/instrumentsList instruments (filter by symbols in body)
POST/v1/refdata/metadataGet instrument metadata

Sports Data

MethodEndpointDescription
GET/v1/refdata/sportsList all sports with metadata
GET/v1/refdata/sports/teamsList teams with optional filtering
GET/v1/refdata/sports/teams/providerGet teams by provider-specific IDs
See Sports Reference Data for detailed documentation.
No Participant ID RequiredThese endpoints only require Auth0 JWT authentication with read:instruments scope. You do not need to provide the x-participant-id header or complete KYC onboarding to access reference data.
No GET endpoint for single instrumentTo get a single instrument, use POST /v1/refdata/instruments with {"symbols": ["SYMBOL-NAME"]} in the body.

Filtering Instruments

The /v1/refdata/instruments endpoint supports configurable query parameters to filter and paginate results.

Request Parameters

ParameterTypeDescription
pageSizeint32Results per page (default: 50, max: 1000)
pageTokenstringPagination cursor from previous response
symbolsstring[]Filter by exact instrument symbols
productIdstringFilter by exact product ID
tradableFilterenumTRADABLE_FILTER_TRADABLE, TRADABLE_FILTER_NON_TRADABLE, or TRADABLE_FILTER_ALL
statesenum[]Filter by instrument states (multiple values = OR logic)
eventSeriesstringFilter by event series (e.g., cbb, nfl, nba)
eventCategorystringFilter by event category (e.g., SPR, POL, CUL)
clearingSymstringFilter by clearing symbol (e.g., AEC-NFL, AEC-BASKETBALL)
startTimeGtestringInstruments starting on or after date (format: YYYY-MM-DD)
startTimeLtestringInstruments starting on or before date
endTimeGtestringInstruments expiring on or after date
endTimeLtestringInstruments expiring on or before date
All parameter names accept both camelCase and snake_case (e.g., eventSeries and event_series are equivalent). This is standard protobuf JSON serialization behavior.
Protobuf Enum CautionThe states and tradableFilter parameters use protobuf enums. Unrecognized values (typos, made-up states, etc.) silently map to the default enum value and return misleading results — they do not error or return empty. Only use the exact values documented here.

Response Fields

FieldTypeDescription
instrumentsarrayList of matching instruments
nextPageTokenstringToken for next page (empty if no more results)
eofbooleanTrue when no more results

Pagination

Use pageSize and pageToken to paginate through large result sets.
# First page
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pageSize": 100}'

# Next page (use nextPageToken from previous response)
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pageSize": 100, "pageToken": "eyJvIjoxMDB9"}'

Filtering by State

Filter instruments by their current trading state using the states parameter.
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "states": ["INSTRUMENT_STATE_OPEN"],
    "pageSize": 100
  }'
You can specify multiple states to match any of them:
{
  "states": ["INSTRUMENT_STATE_OPEN", "INSTRUMENT_STATE_SUSPENDED"],
  "pageSize": 100
}

Filtering by Series

Filter instruments by series (e.g., NFL, NBA, US Presidential):
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_series": "nba",
    "states": ["INSTRUMENT_STATE_OPEN"],
    "pageSize": 1000
  }'

Filtering by Category

Filter instruments by category (e.g., SPR for sports, POL for politics):
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_category": "SPR",
    "states": ["INSTRUMENT_STATE_OPEN"],
    "pageSize": 1000
  }'

Combining Filters

You can combine multiple filters:
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "eventSeries": "nfl",
    "eventCategory": "SPR",
    "clearingSym": "AEC-NFL",
    "states": ["INSTRUMENT_STATE_OPEN"],
    "pageSize": 1000
  }'

Advanced Filtering

The filter parameter supports two approaches that can be used independently or combined. When both are provided, results must match both conditions (AND). Option A: whereClause — A SQL-like string expression:
curl -X POST "https://api.preprod.polymarketexchange.com/v1/refdata/instruments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "whereClause": "symbol LIKE '\''aec-nfl-%'\'' AND state = '\''INSTRUMENT_STATE_OPEN'\''"
    }
  }'
Supported operators: =, LIKE (with % wildcard), AND Supported columns:
ColumnNotes
stateInstrument state enum values
symbolExact match or LIKE pattern
event_seriese.g., 'cbb', 'nfl'
event_categorye.g., 'SPR'
clearing_syme.g., 'AEC-BASKETBALL'
clearing_housee.g., 'QCC'
product_idProduct identifier
Do not use instrument_product, outcome_type, or event_subcategory in whereClause — these cause HTTP 500 errors. The column event_id is accepted but returns 0 results for known values.
Option B: fieldFilters — Structured, type-safe filters:
{
  "filter": {
    "fieldFilters": [
      {
        "field": "event_series",
        "operator": "FILTER_OPERATOR_EQ",
        "stringValue": "nfl"
      },
      {
        "field": "state",
        "operator": "FILTER_OPERATOR_IN",
        "stringList": {
          "values": ["INSTRUMENT_STATE_OPEN", "INSTRUMENT_STATE_PREOPEN"]
        }
      }
    ]
  }
}
Each field filter has a field name, an operator, and a typed value (stringValue or stringList). Multiple entries are ANDed together. The same columns supported in whereClause work in fieldFilters. Available operators:
OperatorDescriptionValue field
FILTER_OPERATOR_EQExact matchstringValue
FILTER_OPERATOR_INMatch any in liststringList ({"values": [...]})
FILTER_OPERATOR_LIKESQL LIKE pattern (% wildcard)stringValue

Instrument Data

Each instrument includes:
FieldTypeDescription
symbolstringUnique trading symbol
tickSizedoubleMinimum price increment
baseCurrencystringBase currency (e.g., "USD")
multiplierdoubleContract multiplier
minimumTradeQtystring (int64)Minimum order quantity
startDateDateMarket start date ({year, month, day})
expirationDateDateExpiration date
terminationDateDate or nullTermination date (null when not set)
tradingScheduleTradingHours[]Trading schedule segments (empty array when none)
descriptionstringHuman-readable instrument description
clearingHousestringClearing house code (e.g., "QCC")
minimumUnaffiliatedFirmsstring (int64)Minimum unaffiliated firms requirement
nonTradablebooleanWhether instrument is non-tradable
jsonAttributesstringAdditional JSON attributes (empty when unused)
productIdstringProduct identifier
priceLimitPriceLimitPrice limits ({low, high, lowSet, highSet, ...})
orderSizeLimitOrderSizeLimit or nullOrder size limits (null when not set)
expirationTimeTimeOfDayExpiration time of day ({hours, minutes, seconds})
tradeSettlementPeriodstring (int64)Settlement period
statestring (enum)Current instrument state (e.g., "INSTRUMENT_STATE_OPEN")
priceScalestring (int64)Price scale divisor for converting integer prices to decimals
fractionalQtyScalestring (int64)Fractional quantity scale
settlementCurrencystringReserved for future use
settlementPriceScalestring (int64)Reserved for future use
metadatamap<string,string>Key-value metadata (sports league, market category, game IDs, etc.)
eventAttributesEventAttributesEvent resolution details ({question, payoutValue, ...})
createTimestring (Timestamp)Instrument creation time (RFC 3339)
updateTimestring (Timestamp)Last update time (RFC 3339)
Integer Fields Encoded as Strings in JSONFields typed as int64 in the protocol buffer definition (such as minimumTradeQty, priceScale, fractionalQtyScale, priceLimit.low, priceLimit.high) are serialized as strings in JSON responses per the proto3 JSON specification. Parse these values as numbers in your client code.For example, "priceScale": "100" is the string "100", not the number 100.

Instrument States

Primary State Flow

State                                              Description
PENDINGInitial state for a newly created instrument which has not yet begun trading.
OPENIn this state, the instrument is open for continuous order entry and matching.
CLOSEDIn this state, orders can not be entered, modified, or canceled, and no matching occurs. Any existing Day orders will be expired.
EXPIREDAn instrument moves to this state when its Expiration Date/Time is reached. In this state, any resting orders are expired and no new orders can be entered.
TERMINATEDWhen an instrument’s Termination Date is reached, the order book is removed from the matching engine, orders are canceled, and positions are closed. Historical data will still remain in Polymarket US ledgers.

Exception States

State                                              Description
SUSPENDEDOrders can be canceled but no matching occurs, and no order entry or modification is allowed.
HALTEDThis state is similar to SUSPENDED, with the exception that orders cannot be canceled.

Other Possible States

State                                              Description
PREOPENOrders can be entered and modified, but no matching occurs. When the instrument transitions to an OPEN state, the orders entered during PREOPEN will match at a single opening price that is automatically determined by an algorithm that is designed to maximize the volume traded at the open.
MATCH_AND_CLOSE_AUCTIONThis state is similar to PREOPEN, with the exception that matching will occur upon the transition of this state to any other state. This state is useful if you want matching to occur at the end of the state, but you don’t want the instrument to be open after.

Price Scale

Prices in the API are represented as integers. Divide by priceScale to get decimal prices:
decimal_price = int_price / instrument.price_scale
# Example: 52500 / 1000 = $52.50
Cache Reference DataInstrument metadata changes infrequently. Cache reference data locally and refresh periodically (e.g., daily or on startup) rather than fetching for every request.

Usage Notes

  • Reference data is static during a trading session
  • Use /v1/refdata/instruments to get priceScale for price conversions
  • Instrument states change based on market schedule