Skip to main content

Batch Prices

POST /v1/prices/batch
Returns live prices for multiple markets in a single request. Much more efficient than calling GET /v1/markets/{id} individually.

Request

curl -X POST https://api.polysimulator.com/v1/prices/batch \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"market_ids": ["0x1a2b3c...", "0x4d5e6f..."]}'
FieldTypeRequiredDescription
market_idsstring[]YesArray of condition_ids (max 50)

Batch Size Limits

The maximum number of markets per request depends on your API key’s rate limit tier:
TierMax market_ids per request
free5
pro20
enterprise50
Exceeding your tier’s limit returns a 400 error.

Response

[
  {
    "condition_id": "0x1a2b3c...",
    "buy": "0.65",
    "sell": "0.35",
    "outcomes": [
      {"label": "Yes", "price": "0.65", "token_id": "71321..."},
      {"label": "No", "price": "0.35", "token_id": "71322..."}
    ],
    "source": "redis_cache"
  },
  {
    "condition_id": "0x4d5e6f..."
  }
]
FieldTypeDescription
condition_idstringThe requested market ID
buystring | nullYes outcome price (0–1). Absent when price unavailable.
sellstring | nullNo outcome price (0–1). Absent when price unavailable.
outcomesarrayPer-outcome {label, price, token_id} breakdown
sourcestring | nullPrice source: redis_cache, gamma_api, clob_book
Markets with unavailable prices return only the condition_id field — all price fields will be absent. This can happen when a market is newly listed and hasn’t been cached yet.

Use Cases

  • Portfolio valuation: Fetch current prices for all your positions at once
  • Watchlist monitoring: Track prices for markets you’re interested in
  • Batch strategies: Evaluate multiple markets before submitting batch orders
import requests

API_KEY = "ps_live_..."
BASE = "https://api.polysimulator.com"
headers = {"X-API-Key": API_KEY}

# Fetch prices for all open positions
positions = requests.get(
    f"{BASE}/v1/account/positions",
    headers=headers,
    params={"status": "OPEN"},
).json()

market_ids = [p["market_id"] for p in positions]

prices = requests.post(
    f"{BASE}/v1/prices/batch",
    headers=headers,
    json={"market_ids": market_ids},
).json()

for p in prices:
    if p.get("buy") is not None:
        print(f"{p['condition_id'][:16]}: Yes={p['buy']}, No={p['sell']}")
    else:
        print(f"{p['condition_id'][:16]}: price unavailable")

Error Handling

StatusMeaning
400market_ids missing, empty, or exceeds tier batch size limit
401Invalid or expired API key
429Rate limit exceeded — check Retry-After header
import time

resp = requests.post(
    f"{BASE}/v1/prices/batch",
    headers=headers,
    json={"market_ids": market_ids},
)

if resp.status_code == 200:
    prices = resp.json()
    for p in prices:
        if p.get("buy") is not None:
            print(f"{p['condition_id'][:16]}: {p['buy']}")
elif resp.status_code == 400:
    print(f"Bad request: {resp.json().get('message', resp.json())}")
elif resp.status_code == 429:
    retry_after = int(resp.headers.get("Retry-After", 1))
    time.sleep(retry_after)
Markets with unavailable prices return only the condition_id field — all price fields will be absent. Always check for the presence of buy/sell before using them.

Next Steps