The Polymarket subgraphs are deprecated. On April 28, 2026 Polymarket migrated to its CLOB V2 contracts and stopped using subgraphs; Goldsky, which hosts them, now states that the existing public subgraph endpoints “will return incomplete or incorrect data.” This guide documents the replacement — Goldsky Turbo Pipelines on the v2 Polymarket datasets — and retains the legacy subgraph reference for anyone maintaining pre-April-2026 code.
Deprecation Status and What to Use Instead
The break was not gradual. Polymarket’s CLOB V2 upgrade replaced the Exchange contracts and swapped collateral from USDC.e to pUSD on April 28, 2026. The subgraphs index the old contracts, so anything they return after that date is partial at best. Goldsky’s Polymarket documentation carries the notice directly:
On April 28, 2026, Polymarket migrated to a v2 set of contracts and is no longer using subgraphs going forward. Existing public subgraph endpoints will return incomplete or incorrect data.
If you are still querying a api.goldsky.com/.../subgraphs/... endpoint for Polymarket data, your numbers are wrong. Treat this as a correctness bug, not a deprecation warning.
The replacement is Turbo Pipelines, which stream Goldsky-maintained v2 datasets into a sink you control rather than serving GraphQL queries. Four datasets are currently published:
| Dataset | Replaces | What it carries |
|---|---|---|
polymarket.order_filled (recommended) | Orders subgraph (OrderFilled) | Per-fill rows: user_id, asset, price, amount_usdc, amount_shares, side, order_type (maker/taker), fee, builder |
polymarket.orders_matched | Orders subgraph (OrderMatched) | Taker-level matches — one row per taker order rather than per fill |
polymarket.user_balances | Positions subgraph (UserBalance) | Current outcome-token balances by owner_address and token_id |
polymarket.user_positions | PNL subgraph (UserPNL) | Position size plus avg_price, realized_pnl, total_bought |
Two gaps worth planning around: there is no direct replacement for the Activity subgraph (splits, merges, redemptions) or the Open Interest subgraph in the published dataset list. For redemption and settlement activity, the Data API’s GET /activity endpoint has reported redemptions per outcome since August 10, 2026 — see the Polymarket API guide. For open interest you will need to derive it from position data or use the Data API.
Migrating a Query to a Pipeline
The model is different: subgraphs were pull-based GraphQL, pipelines are push-based streaming into your own database or webhook. A pipeline is a YAML file applied through the Goldsky CLI:
name: polymarket-fills
resource_size: s
sources:
order_filled:
type: dataset
dataset_name: polymarket.order_filled
version: 2.0.0
start_at: earliest
transforms:
large_fills:
type: sql
primary_key: id
sql: |
SELECT id, block_number, block_timestamp, transaction_hash,
user_id, asset, side, price, amount_usdc, amount_shares
FROM order_filled
WHERE amount_usdc > 1000
sinks:
alerts:
type: webhook
from: large_fills
url: https://api.example.com/polymarket/orders
one_row_per_request: true
Deploy with goldsky turbo apply polymarket-fills.yaml, validate with goldsky turbo validate, and inspect live rows with goldsky turbo inspect.
Three practical constraints. Backfills support fast scan on a block_number range filter but not on timestamps, so express historical windows in block numbers. Volume is substantial — Goldsky notes user positions can run to roughly 1.2B entities to backfill and 150M monthly to maintain, so check the pricing calculator before backfilling everything. And unlike the old subgraphs, this requires an account and CLI auth; there is no anonymous public endpoint.
If You Only Need Current Data
Most agents querying the subgraphs did not actually need on-chain indexing. Before building a pipeline, check whether the REST APIs cover you — GET /positions on the Data API now also exposes grossInitialValue and entryFeesUsdc for fee-inclusive cost basis, plus an includeArchived filter. See the Polymarket API guide and the rate limits guide. Pipelines are the right tool for full history, custom analytics, and warehouse replication — not for “what does this wallet hold right now.”
Legacy Subgraph Reference (Historical)
Everything below describes the pre-April-2026 architecture. It is preserved for teams reading or porting old code. Do not build new integrations against it — the endpoints still respond, which is precisely what makes them dangerous.
Subgraph Reference
Polymarket splits its on-chain data across five purpose-built subgraphs. Each one indexes a specific domain of activity from the Polymarket smart contracts on Polygon.
| Subgraph | Data | Key Entities |
|---|---|---|
| Positions | User token balances | UserBalance, Condition, Market |
| Orders | Order book and trade events | OrderFilled, OrderMatched, GlobalStats |
| Activity | Splits, merges, redemptions | Split, Merge, Redemption, NegRiskEvent |
| Open Interest | Per-market and global OI | MarketCondition, GlobalOI |
| PNL | User position P&L | UserPNL, Position |
All five subgraphs share the same query method: send a POST request with a JSON body containing your GraphQL query to the Goldsky-hosted endpoint. The orders subgraph endpoint, for example, looks like this:
https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/0.0.1/gn
Each subgraph has its own endpoint URL following the same pattern, with the subgraph name and version in the path.
Positions Subgraph
The Positions subgraph indexes user token balances across all Polymarket markets. Every time a wallet holds outcome tokens (YES or NO shares), this subgraph tracks the balance. Key entities include UserBalance (the core record linking a user address to a token balance), Condition (the on-chain condition representing a market outcome), and Market (the parent market structure).
Use this subgraph when you need to know what a specific wallet holds, aggregate positions across markets, or build portfolio-tracking tools.
Orders Subgraph
The Orders subgraph captures every order book event that settles on-chain. OrderFilled records individual fill events with maker, taker, asset IDs, and amounts. OrderMatched provides a higher-level view of matched orders. GlobalStats aggregates platform-wide trading metrics like total volume and number of trades.
This is your go-to subgraph for historical trade analysis, volume tracking, and building trade feeds.
Activity Subgraph
The Activity subgraph tracks CTF (Conditional Token Framework) operations that happen outside the order book. Split events occur when a user splits collateral into outcome tokens. Merge events record the reverse – combining outcome tokens back into collateral. Redemption events capture users redeeming winning tokens after market resolution. NegRiskEvent entities track operations specific to Polymarket’s negative-risk market type.
This subgraph is essential for understanding the full lifecycle of positions beyond simple trading.
Open Interest Subgraph
The Open Interest subgraph provides both per-market and global open interest data. MarketCondition entities track OI for individual market conditions, while GlobalOI provides platform-wide totals. Open interest reflects the total value of outstanding positions in a market and is a key indicator of market depth and participant commitment.
PNL Subgraph
The PNL subgraph calculates realized and unrealized profit and loss at the wallet level. UserPNL entities aggregate P&L across a user’s positions, while Position entities break it down by individual market. This subgraph handles the math of tracking cost basis, realized gains from trades and redemptions, and unrealized gains on open positions.
Common Queries
The following queries demonstrate the most frequently used patterns across the subgraphs. Replace placeholder values (wallet addresses, condition IDs) with real data from your application.
Get User Positions by Wallet
Query the Positions subgraph to retrieve all token balances for a specific wallet address. This returns every outcome token the wallet currently holds or has held.
{
userBalances(where: { user: "0xYOUR_WALLET_ADDRESS" }) {
id
balance
netBalance
condition {
id
questionId
}
}
}
The balance field shows the raw token balance, while netBalance accounts for any pending operations. The condition relationship links each balance to the specific market outcome it represents, with questionId mapping to the Polymarket market.
Get Recent Trades
Query the Orders subgraph to fetch the most recent trade events. This returns fills in reverse chronological order.
{
orderFilleds(first: 100, orderBy: timestamp, orderDirection: desc) {
id
maker
taker
makerAssetId
takerAssetId
makerAmountFilled
takerAmountFilled
timestamp
}
}
The makerAssetId and takerAssetId fields identify which outcome tokens were exchanged. The makerAmountFilled and takerAmountFilled fields indicate the amounts on each side of the trade. Use the timestamp field for time-series analysis.
Get Market Open Interest
Query the Open Interest subgraph to retrieve open interest for a specific market condition.
{
marketConditions(where: { conditionId: "CONDITION_ID" }) {
id
openInterest
conditionId
}
}
The conditionId corresponds to the on-chain condition identifier for a market. You can obtain condition IDs from the Gamma API or the Positions subgraph.
Querying in Python
Here is a complete Python example that queries the Orders subgraph for recent trades and prints the results.
import requests
SUBGRAPH_URL = "https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/0.0.1/gn"
query = """
{
orderFilleds(first: 10, orderBy: timestamp, orderDirection: desc) {
id
maker
taker
makerAmountFilled
timestamp
}
}
"""
response = requests.post(SUBGRAPH_URL, json={"query": query})
data = response.json()["data"]
for trade in data["orderFilleds"]:
print(f"Trade {trade['id']}: {trade['makerAmountFilled']} at {trade['timestamp']}")
The same pattern works for any subgraph – change the URL and the query to match the subgraph you need. No authentication headers are required. Error handling should check for response.status_code and the presence of an errors key in the JSON response.
Pagination
GraphQL subgraphs enforce result limits on queries. The default maximum per request is typically 1,000 entities. For larger datasets, you need pagination.
Skip-based pagination uses the first and skip parameters. This is simpler but becomes slow for large offsets because the subgraph must still process all skipped records:
{
orderFilleds(first: 1000, skip: 2000, orderBy: timestamp, orderDirection: desc) {
id
timestamp
}
}
Cursor-based pagination with id_gt is more efficient for iterating through large result sets. After each batch, pass the last id you received to fetch the next page:
{
orderFilleds(first: 1000, where: { id_gt: "LAST_ID" }, orderBy: id) {
id
timestamp
makerAmountFilled
}
}
For production systems processing large amounts of historical data, cursor-based pagination is strongly recommended. It avoids the performance penalty of skip-based pagination and handles new records being added between queries more gracefully.
Tip: When paginating, always include orderBy: id to ensure deterministic ordering. If you order by timestamp, records with identical timestamps may appear inconsistently across pages.
Bitquery Alternative
Bitquery provides a third-party GraphQL API that covers Polymarket trading data from a different angle. Where the native subgraphs give you raw on-chain events, Bitquery offers analytics-level queries with built-in aggregations, filtering, and enrichment.
Bitquery’s Polymarket coverage includes:
- Trades – Individual trade records with token metadata and USD values.
- Settlements – Market resolution events and payouts.
- Market lifecycle – Creation, trading, and settlement phases.
- Wallet analytics – Aggregated activity per wallet across markets.
Bitquery also offers Kafka streaming for real-time data, which can serve as an alternative to Polymarket’s native WebSocket API for on-chain events.
Key differences from native subgraphs:
- Requires an API access token (free tier available).
- Provides pre-computed aggregations that would require multiple subgraph queries.
- Covers data across multiple chains and protocols, not just Polymarket.
- Kafka streaming adds a real-time dimension not available from subgraphs alone.
Use Bitquery when you need cross-market analytics, pre-built aggregations, or real-time streaming of on-chain events. Use the native subgraphs when you need the most granular, lowest-latency access to specific on-chain data.
When to Use Subgraph vs REST APIs
Polymarket’s data ecosystem spans REST APIs, WebSockets, and on-chain subgraphs. Each tool serves a different purpose. Choosing the right one depends on what data you need and how you intend to use it.
| Use Case | Best Tool |
|---|---|
| Real-time prices and orderbook | REST API or WebSocket |
| Order placement and trading | REST API (CLOB) |
| Market discovery and search | Gamma API (REST) |
| User token balances (on-chain) | Positions subgraph |
| Historical trade events | Orders subgraph |
| CTF operations (split/merge/redeem) | Activity subgraph |
| Open interest tracking | Open Interest subgraph |
| Wallet-level P&L | PNL subgraph |
| Cross-market analytics | Bitquery |
General rule: If you need to take action (place orders, cancel orders), use the REST API. If you need to read on-chain state or historical on-chain events, use the subgraphs. If you need pre-computed analytics or real-time event streaming, consider Bitquery.
The subgraphs and REST APIs are complementary. A typical trading bot might use the REST API for order execution, WebSockets for real-time price feeds, the Positions subgraph for portfolio tracking, and the PNL subgraph for performance reporting.
FAQ
What data is available in the Polymarket subgraphs?
Five subgraphs cover: Positions (user token balances), Orders (order book and trade events), Activity (splits, merges, redemptions), Open Interest (per-market and global OI), and PNL (user position profit/loss). All provide on-chain data not available through REST APIs.
How do I query the Polymarket subgraph?
Send a POST request with a GraphQL query to the Goldsky-hosted endpoint. For example, the orders subgraph endpoint is https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/0.0.1/gn. Use standard GraphQL query syntax. No API key or authentication is required.
When should I use the subgraph instead of the REST API?
Use the subgraph for on-chain data like token balances, CTF operations (splits/merges/redemptions), historical open interest, and wallet-level P&L. Use REST APIs for real-time trading, order placement, and current market data. The two are complementary – most production systems use both.
What is the Bitquery alternative for Polymarket data?
Bitquery provides a GraphQL API for Polymarket trading data including trades, settlements, market lifecycle, and wallet analytics. It also offers Kafka streaming for real-time data. It requires an API access token. It is useful as a complementary data source or when you need analytics-level queries that would require multiple subgraph requests to assemble.
See Also
- Polymarket API Guide – Full REST API reference
- Polymarket Gamma API Deep Dive – Market discovery and price history
- Polymarket WebSocket Guide – Real-time streaming alternative
- py_clob_client Reference – Python SDK methods
- Polymarket Rate Limits Guide – REST API rate limits
- Prediction Market API Reference – Cross-platform comparison
This guide is maintained by AgentBets.ai. Found an error or API change we missed? Let us know on Twitter.
Not financial advice. Built for builders.
