Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Integration & Development11 min read

Polymarket Gamma API: A Practical Integration and Data Pipeline Guide

Learn how the Polymarket Gamma API structures events and markets, how to page through it reliably, and how to build a reproducible data pipeline around its public endpoints.

TL;DR

The Polymarket Gamma API is the public catalogue layer for Polymarket: it exposes events, markets, tags, series, and sports metadata without authentication, and it is the correct starting point for discovery workflows. It does not serve live order books or execute trades; those responsibilities belong to the CLOB and Data APIs. This article explains the Gamma data hierarchy, shows runnable requests for listing and paging markets, and walks through a reproducible ingestion pipeline with verification and troubleshooting steps. It also covers where Gamma stops and how to measure your own pipeline's behaviour rather than relying on assumed limits.

What the Gamma API Is and Where It Fits

The Polymarket Gamma API is a read-only REST interface at https://gamma-api.polymarket.com that returns indexed metadata about events and markets on Polymarket. It requires no API key for its public read endpoints, which makes it the natural first call in any prediction-market application: you use Gamma to discover what exists, then hand the resulting token identifiers to other services for pricing and execution.

The important architectural point is separation of concerns. Gamma is a catalogue, not a trading venue. It answers questions such as "which markets are active," "what is this event's slug," and "which outcome tokens belong to this market." It does not answer "what is the current best bid" or "place this order." Those belong to the CLOB API, while user positions and trade history belong to the Data API. Treating Gamma as the discovery layer and the other APIs as execution and analytics layers keeps your integration clean and your failure modes isolated.

This guide assumes you have a working HTTP client, basic familiarity with JSON, and a place to persist data such as a database or object store. All examples use placeholders and public read paths; no credentials are required for the operations shown.

  • Gamma: events, markets, tags, series, sports metadata, search.
  • CLOB: order books, prices, order placement and cancellation.
  • Data API: trades, positions, and user-specific activity.
  • Subgraph: direct on-chain queries when you need raw chain state.

The Event and Market Hierarchy

Gamma organises data hierarchically. A series groups related events, such as a recurring sports league or a seasonal set of questions. An event is a page-level concept that usually corresponds to a question on the Polymarket site and can contain one or more markets. A market is the tradable unit and carries the outcome tokens, volume, liquidity, and status fields.

Each market exposes identifiers you will need downstream. The conditionId identifies the market contract, and clobTokenIds is an array of token identifiers for the outcomes, typically Yes and No. When you move from Gamma to the CLOB for pricing, you pass those token identifiers rather than market slugs. Persisting the mapping between slug, conditionId, and token IDs at ingestion time saves repeated lookups later.

Events and markets also carry status fields such as active and closed. These are independent: a market can be active but not closed, closed and inactive, or in transitional states around resolution. Filter on both when you want currently tradable inventory, and record the values you observed so you can reason about changes over time.

Listing Active Events with curl

Start with a minimal request that lists active, open events sorted by recent volume. The response includes a has_more flag and the event objects themselves. Inspect one response by hand before writing any pipeline code so you understand the field names your version of the API returns.

The following command is safe to run against the public endpoint. It does not require authentication and does not mutate state.

curl -s "https://gamma-api.polymarket.com/events?active=true&closed=false&order=volume_24hr&ascending=false&limit=5" \
  | python -m json.tool | head -n 80

Paging Through Markets Without Missing Rows

Gamma supports offset-based pagination with limit and offset, and the response includes has_more. The reliable pattern is to request a page, process it, then increment offset by the number of records actually returned until has_more is false. Do not assume the server returns exactly limit records; the final page is usually short, and filters can reduce page sizes.

A subtle failure mode is offset drift. If you page through a live, volume-sorted list while new events enter the top of the ordering, rows can shift between pages and you may see duplicates or miss records. For snapshot-style ingestion, sort by a stable field such as start_date or id where available, or accept duplicates and deduplicate downstream by market identifier. Gamma also exposes keyset-style endpoints such as markets/keyset and events/keyset; prefer those when you need stable traversal of large result sets.

The Python example below demonstrates a bounded, deduplicating pager. It caps total pages so a runaway loop cannot hammer the endpoint, and it records the identifiers it has already seen.

import time
import requests

BASE = "https://gamma-api.polymarket.com"

def iter_markets(limit=100, max_pages=20, pause=0.5):
    seen = set()
    offset = 0
    for _ in range(max_pages):
        resp = requests.get(
            f"{BASE}/markets",
            params={"active": "true", "closed": "false", "limit": limit, "offset": offset},
            timeout=15,
        )
        resp.raise_for_status()
        batch = resp.json()
        if not batch:
            break
        for market in batch:
            key = market.get("conditionId") or market.get("slug")
            if key and key not in seen:
                seen.add(key)
                yield market
        offset += len(batch)
        time.sleep(pause)

for m in iter_markets():
    print(m.get("slug"), m.get("conditionId"))

Resolving a Single Market by Slug

When you already know a market's slug, fetch it directly instead of scanning lists. The slug endpoint returns the market object, which you can then join to your stored metadata. This is the pattern to use in a webhook handler or a user-facing detail page, where latency matters and a full listing would be wasteful.

The same principle applies to events: the events endpoint accepts a slug parameter and returns the matching event with its nested markets. Use these targeted lookups for read paths and reserve list endpoints for scheduled ingestion.

curl -s "https://gamma-api.polymarket.com/markets?slug=fed-decision-in-october" \
  | python -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d[0] if d else {}, indent=2)[:1200])"

Designing a Reproducible Ingestion Pipeline

A production pipeline around the Gamma API should be boring and observable. Structure it in four stages: fetch, normalise, persist, and verify. In the fetch stage, apply explicit filters and a bounded page count. In normalisation, map Gamma fields to your own schema and extract clobTokenIds into a separate table. In persistence, upsert by conditionId so repeated runs are idempotent. In verification, compare row counts and checksums against the previous run.

Record the request parameters, response status, and record count for every page in a run log. When something looks wrong later, that log is the difference between a five-minute diagnosis and an afternoon of guessing. Store the raw JSON alongside the normalised rows for at least a few runs so you can replay without re-fetching.

Treat rate limits as unknown until you measure them. The public API is shared infrastructure, so build in a conservative pause between pages, honour 429 responses with exponential backoff, and never parallelise aggressively against a shared endpoint. If your workload grows beyond what polite public usage allows, consider a dedicated data layer or your own caching tier rather than increasing request pressure.

  • Upsert on conditionId; keep slug as a secondary key.
  • Persist raw payloads for replay and schema drift detection.
  • Log page parameters, status codes, and row counts per run.
  • Back off on 429 and 5xx; cap retries and alert on exhaustion.

Verifying a Run and Reading the Results Table

After each ingestion run, produce a small results table so you can compare runs at a glance. The table below is a template: fill it with your own observed values. Do not copy numbers from documentation or other articles; the point is to establish a baseline for your environment and your filters.

Run timestampFilter setPages fetchedRecords seenRecords upsertedDuplicates skippedErrorsp95 latency (ms)

A healthy run shows records seen greater than or equal to records upserted, duplicates skipped near zero on a first run and higher on incremental runs, and zero errors. A sudden jump in duplicates usually means offset drift on a sorted list. A drop in records seen with the same filters usually means a filter value changed or the endpoint returned an error page that your client did not raise on.

For latency, measure end-to-end request time in your client and record the 95th percentile per run. Compare it across runs rather than against a fixed target; network path and server load both vary. If you need a stable, low-latency path for adjacent on-chain reads, a managed endpoint from a provider such as the OnFinality RPC service can remove one source of variance, but Gamma itself remains a Polymarket-operated service.

Troubleshooting Common Gamma Integration Problems

Most Gamma issues fall into a few categories. Empty responses usually mean an over-constrained filter combination, such as active=true with closed=true and a narrow tag. Check each filter independently before combining them. Unexpected 404s on slug lookups usually mean the slug changed or the market was renamed; fall back to a search by conditionId if you stored one.

Schema surprises are common when fields are added or nested objects change shape. Defensive parsing, where you read optional fields with defaults and log unknown keys, prevents a single new field from breaking a pipeline. If your client deserialises into strict types, version your models and tolerate unknown properties.

Rate limiting appears as 429 responses, sometimes without a Retry-After header. Implement exponential backoff with jitter, cap concurrency at one request at a time for ingestion, and alert if backoff exceeds a threshold. Persistent 5xx errors should be treated as an outage: pause the run, keep the last good snapshot, and resume from the last committed offset rather than restarting from zero.

  • Empty result: relax filters one at a time.
  • 404 on slug: re-resolve by conditionId or search.
  • Parse error: log the raw payload and unknown keys.
  • 429: back off with jitter; reduce concurrency.
  • 5xx: pause, retain snapshot, resume from checkpoint.

Limits, Tradeoffs, and When to Add Another Layer

Gamma is optimised for discovery, not for high-frequency reads or historical analytics. It gives you current metadata and status, but it is not a time-series store. If you need historical price series, order book depth, or cross-venue comparisons, you will need the CLOB API, the Data API, or a separate analytics layer. Building those joins yourself is reasonable for a focused product and expensive for a broad one.

There is also a freshness tradeoff. Caching Gamma responses reduces load and latency but means your catalogue can lag reality. Choose a cache duration based on how quickly your users need to see new markets; for most discovery UIs, a short cache with background refresh is sufficient. For trading UIs, always confirm price and availability against the CLOB before presenting an actionable quote.

Finally, consider your infrastructure boundary. Gamma is a Polymarket service, but the rest of your stack may read chain state directly. If you are querying Polygon for settlement or balance data, a reliable RPC endpoint matters as much as a reliable catalogue. You can review available networks and endpoint options through the OnFinality networks directory and compare plans on the RPC pricing page before committing to a provider.

Next Steps for a Production Integration

Once your Gamma ingestion is stable, extend it in three directions. First, add a CLOB read path so your application can show live prices next to catalogue metadata. Second, add a Data API path for user positions and trade history if you are building a portfolio view. Third, add monitoring that alerts on ingestion failures, schema drift, and latency regressions rather than waiting for users to report missing markets.

If your application also needs direct chain access for settlement checks or wallet balances, evaluate a dedicated node or managed RPC service so that catalogue reads and chain reads fail independently. You can explore dedicated node options and the broader API service offering to decide whether managed infrastructure fits your reliability targets.

For teams that want a concrete endpoint recommendation rather than a methodology, the RPC Assistant is the right place to ask; this guide deliberately stays at the integration and measurement level so your choices are grounded in your own observed behaviour.

  • Add CLOB pricing alongside Gamma metadata.
  • Add Data API reads for positions and activity.
  • Instrument ingestion with alerts on drift and failure.
  • Separate catalogue and chain infrastructure failure domains.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started