# Где запрашивать данные Polymarket через GraphQL

> Ни у одного из трёх REST API Polymarket нет GraphQL-эндпоинта. Доступ через GraphQL существует, но работает он с открытыми сабграфами, размещёнными на стороне, — а индексируют они ончейн-события, а не текст рынков и живые цены, за которыми чаще всего и приходят.

- Источник: https://papaproxy.net/ru/blog/polymarket-graphql-api.php
- Опубликовано: 2026-08-09
- Автор: Alex Young
- Рубрика: API и данные · Блог PapaProxy.net

---

## Ключевые выводы

- Документированная первосторонняя поверхность Polymarket — Gamma, CLOB и Data API — это HTTP плюс вебсокет-каналы CLOB; GraphQL-эндпоинт на август 2026 года не документирован ни для одного из трёх хостов.
- Доступ через GraphQL даёт открытый сабграф Polymarket, который, по документации, может разместить кто угодно, а авторитетный справочник по полям — файл `schema.graphql` в публичном репозитории.
- Работа разнесена по сабграфам — позиции, стакан, активность, открытый интерес и P&L, — доступным на публичных эндпоинтах Goldsky, где URL фиксирует конкретную версию, либо через шлюз The Graph с API-ключом; документированный Free Plan на 100 000 запросов в месяц принадлежит именно The Graph, а не Goldsky.
- Перед историческим бэкфиллом проверьте, какие контракты биржи индексирует развёртывание: публичный манифест по-прежнему перечисляет исходный CTF Exchange, тогда как торговля переехала на более новый, — старое развёртывание может быть неполным.
- Перечисленные сабграфы не заменяют ни Gamma для каноничного текста рынка, ни CLOB для живого стакана, — поэтому продукты на сабграфах присоединяют Gamma по condition ID.
- Код 200 не означает, что запрос удался: проверяйте ещё и поле `errors`, а листайте курсором (`id_gt`), а не глубоким `skip`, при `first` не больше 1 000.
- Сторонние GraphQL-индексаторы вроде Bitquery — самостоятельные поставщики со своими схемами, хранением и ценами, а не GraphQL-версии собственных API Polymarket.

## У REST API нет GraphQL-эндпоинта

На август 2026 года [три REST API Polymarket](/ru/blog/polymarket-three-apis.php) — Gamma, CLOB и Data API — описаны как HTTP-интерфейсы в стиле REST: пути, параметры запроса, JSON-ответы, схема OpenAPI на каждый эндпоинт. Ни для одного из трёх хостов GraphQL-эндпоинт не документирован, и маршрута `/graphql` на `gamma-api.polymarket.com` или `clob.polymarket.com` вы не найдёте. Обратите внимание на точность формулировки: CLOB не сводится к схеме «запрос-ответ» — у него есть [официальные вебсокет-каналы рынка и пользователя](/ru/blog/polymarket-websocket-api.php); отсутствует везде именно документированная GraphQL-поверхность.

Сказать это прямо стоит потому, что поисковый спрос предполагает обратное. Люди ищут GraphQL-эндпоинт для рынков в Gamma или GraphQL-схему рынков, которую можно проинтроспектировать, и уходят с ощущением, что документация неполна. Она полна: HTTP- и вебсокет-поверхности и есть всё, что предлагает первая сторона. Вместо GraphQL там существует отдельный, действительно GraphQL-образный слой, построенный на индексации блокчейна, и в документации разработчика Polymarket у него свой раздел.

Различие важнее, чем кажется, потому что слои хранят разные данные. Первосторонние API отдают то, что знают системы самой Polymarket: вопросы рынков, слаги, теги, изображения, стаканы, текущие цены, позиции кошельков с посчитанным P&L. Слой сабграфов отдаёт то, что записал блокчейн: условия, переводы токенов, сделки, сплиты, мерджи, редемпшены, позиции, выведенные из ончейн-событий. Кое-что есть в обоих. А вот то, чего от GraphQL хотят чаще всего, — заголовок рынка и его живая цена — не то, для хранения чего построены перечисленные сабграфы.

## Что индексируют сабграфы

Официальная позиция коротка: Polymarket написала и открыла исходники сабграфа, который через GraphQL-интерфейс отдаёт агрегатные расчёты и индексацию событий по объёму, пользовательским позициям, рынкам и ликвидности, обновляется в реальном времени и — вот деталь, определяющая всё дальнейшее — **может быть размещён кем угодно**. Схема лежит в файле `schema.graphql` в публичном репозитории, и именно она авторитетна по составу полей.

На практике работа разнесена по нескольким сабграфам, а не по одному. Собственная документация Polymarket для агентов перечисляет набор, размещённый на Goldsky:

| Сабграф | Что индексирует |
| --- | --- |
| `positions-subgraph` | Балансы токенов пользователей |
| `orderbook-subgraph` | События стакана и сделок |
| `activity-subgraph` | Сплиты, мерджи, редемпшены |
| `oi-subgraph` | Открытый интерес по рынкам и глобально |
| `pnl-subgraph` | Прибыль и убыток по позициям |

Эндпоинты следуют фиксированному шаблону — `https://api.goldsky.com/api/public/project_.../subgraphs/<имя>/<версия>/gn`, — причём версия зафиксирована для каждого сабграфа, поэтому URL, скопированный из годовалого туториала, может указывать на версию, которая уже не соответствует текущей схеме. Проверяйте версию, прежде чем доверять найденному в сети запросу.

Альтернативный хост — децентрализованная сеть: сабграф в The Graph запрашивается через шлюз `https://gateway.thegraph.com/api/{api-key}/subgraphs/id/{id}`, для которого нужен API-ключ из Graph Explorer. Обратите внимание, чья это бесплатная квота: Goldsky отдаёт публичные эндпоинты сабграфов Polymarket, которым ключ не нужен, а 100 000 запросов в месяц — это документированный Free Plan именно у The Graph, за которым идёт платный тариф с оплатой по использованию. Отсюда и практическая причина предпочесть шлюз для всего, что вы намерены держать в проде: публичный эндпоинт, которым вы не управляете, может измениться или исчезнуть, а у запроса с ключом есть квота, о которой можно рассуждать, и платный уровень, в который можно вырасти.

Поскольку сабграф открыт и размещаем кем угодно, есть и третий вариант — поднять его самостоятельно. Превышение бесплатной квоты причиной для этого не является: для этого существует платный тариф. Self-hosting оправдывает себя, когда нужна изменённая схема, полный контроль над индексацией, гарантированные свойства данных или отсутствие сторонней зависимости в пути данных.

**Одна оговорка перед любым историческим бэкфиллом.** Публичный манифест сабграфа Polymarket по-прежнему перечисляет исходный контракт CTF Exchange среди индексируемых, тогда как текущая торговая система работает на более новом развёртывании биржи. Сабграф видит только те контракты, которые названы в его манифесте, поэтому старое развёртывание — включая зафиксированную версию Goldsky, скопированную из туториала, — может не содержать полной свежей истории сделок. Развёртывания, знающие о V2, существуют. Прежде чем доверять бэкфиллу, проверьте, какие контракты биржи индексирует конкретное развёртывание, и сверьте его свежие данные с REST-источником, которому вы уже доверяете.

**Сторонние GraphQL-сервисы — отдельная категория.** Провайдеры вроде Bitquery тоже индексируют активность Polymarket и отдают её через GraphQL, иногда с метаданными рынков и агрегациями, которых в официальных сабграфах нет. Это независимые продукты со своими схемами, глубиной хранения, аутентификацией и ценами — не GraphQL-версии Gamma, CLOB или Data API и не поддерживаются Polymarket. Полезно, но оценивать их следует как поставщиков, а не как официальную поверхность.

## Как написать запрос к рынкам и ценам

Вот рабочий GraphQL-запрос к рынкам — точнее, честная версия этой задачи. К публичному эндпоинту Goldsky, ключ не нужен:

BashКопировать код

```bash
curl -X POST \
  https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/0.0.1/gn \
  -H "Content-Type: application/json" \
  -d '{"query": "query { orderbooks(first: 5) { id tradesQuantity scaledCollateralVolume } }"}'
```

Запустите — и форма ответа объяснит название раздела. Вы получите `id` (идентификатор токена или условия), число сделок и объём. Вы не получите «Произойдёт ли X до декабря?», потому что этой строки в блокчейне никогда не было. То же с ценами: сабграф знает исполненные сделки, а не текущие лучшие бид и аск, стоящие в стакане CLOB.

Поэтому реалистичный конвейер использует оба слоя, соединяя их по condition ID:

PythonКопировать код

```python
import requests

GOLDSKY = ("https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw"
           "/subgraphs/positions-subgraph/0.0.7/gn")
GAMMA = "https://gamma-api.polymarket.com"

# Поля ниже соответствуют сущности UserPosition в публичном schema.graphql.
# Развёртывания различаются — сначала прогоните интроспекцию внизу.
QUERY = """
query Positions($first: Int!, $lastId: String!) {
  userPositions(first: $first, where: { id_gt: $lastId }, orderBy: id) {
    id
    user
    tokenId
    amount
    avgPrice
    realizedPnl
    totalBought
  }
}
"""

def gql(url, query, variables=None):
    r = requests.post(url, json={"query": query, "variables": variables or {}}, timeout=30)
    r.raise_for_status()                          # уровень HTTP
    payload = r.json()
    if payload.get("errors"):                     # уровень GraphQL — 200 не значит успех
        raise RuntimeError(payload["errors"])
    return payload["data"]

def all_positions(page=500):                      # курсорная пагинация, без глубокого skip
    last_id, out = "", []
    while True:
        rows = gql(GOLDSKY, QUERY, {"first": page, "lastId": last_id})["userPositions"]
        if not rows:
            return out
        out.extend(rows)
        last_id = rows[-1]["id"]

def market_title(condition_id):                   # каноничный текст — Gamma, а не сабграф
    r = requests.get(f"{GAMMA}/markets", params={"condition_ids": condition_id}, timeout=15)
    r.raise_for_status()
    rows = r.json()
    return rows[0]["question"] if rows else None

# Проверить схему того развёртывания, которое вы реально вызываете:
INTROSPECT = '{ __type(name: "UserPosition") { fields { name type { name kind } } } }'
print(gql(GOLDSKY, INTROSPECT))
```

На что смотреть. Успешный HTTP-статус не гарантирует успешной GraphQL-операции: ответ может прийти с кодом `200` и массивом `errors` в теле, поэтому проверяйте оба уровня — `raise_for_status()` для одного и поле `errors` для другого. Пагинация здесь курсорная, а не через `skip`: `first` ограничен индексатором тысячей, а большие значения `skip` работают медленно, тогда как проход по `id_gt` от последней увиденной строки остаётся быстрым на любой глубине. И самое важное — сначала выполните интроспекцию. Имена полей различаются между развёртываниями и версиями сабграфов (опубликованные гайды показывают разные схемы для одного и того же эндпоинта), поэтому единственный авторитет — схема того развёртывания, которое вы вызываете.

Чего пример не делает: нет политики ретраев, нет кеширования обращений к Gamma (заголовки не меняются, им место в локальном хранилище) и нет обработки лимитов ни для одного из слоёв.

## Сабграф или REST: как выбирать

Выбор здесь на самом деле не между GraphQL и REST API как стилями — вопрос в том, в каком слое лежит ваш ответ.

| Что нужно | Слой |
| --- | --- |
| Вопрос рынка, слаг, теги, изображения, даты | REST (Gamma) |
| Живой стакан, текущая цена, midpoint | REST (CLOB) |
| Текущие позиции кошелька с посчитанным P&L | REST (Data API) — самый простой путь |
| Историю сделок и агрегаты объёма | Сабграф |
| Сплиты, мерджи, редемпшены как события | Сабграф |
| Открытый интерес во времени | Сабграф |
| Произвольную агрегацию по ончейн-истории | Сабграф |

Для текущих позиций кошелька самый простой REST-путь — [эндпоинт Data API `/positions`](/ru/blog/polymarket-data-api-positions.php). Два правила покрывают большинство случаев. Если данные — это текущее значение, которое считает сама Polymarket, REST и проще, и свежее. Если данные историчны, событийны по форме или требуют агрегации, которой ни один REST-эндпоинт не предлагает, инструмент — сабграф: ровно для этого индексатор и нужен.

Насчёт «GraphQL или SDK»: это тоже не альтернативы. Клиенты Polymarket оборачивают REST-поверхности, а сообщество добавляет поверх тех же эндпоинтов клиентов к сабграфам — это избавляет от написания HTTP-обвязки, но не меняет содержимого слоёв. SDK, предлагающий «GraphQL-клиент» рядом с клиентами CLOB, Gamma и Data, оборачивает ровно то разделение, которое описано здесь.

Одна практическая асимметрия определяет многие архитектуры: перечисленные сабграфы Polymarket не заменяют ни Gamma как каноничный источник читаемых метаданных, ни CLOB как живой стакан. Поэтому почти любой продукт для пользователей, построенный на данных сабграфа, всё равно ходит в Gamma, чтобы отрисовать заголовки. Закладывайте этот join сразу: разрешайте condition ID в заголовки один раз, кешируйте — и позвольте GraphQL-слою делать то, в чём он хорош.

Именно на REST-половине действуют поадресные лимиты из [руководства по лимитам Polymarket](/ru/blog/polymarket-api-rate-limits.php) — 300 запросов за 10 секунд у `/markets`, 150 у `/positions`, — и именно в них упирается широкий бэкфилл или загруженный дашборд. Квоты сабграфов существуют отдельно и привязаны к вашему API-ключу, а не к адресу. Если ограничением становится REST-половина конвейера, наши [прокси для криптопроектов](/ru/individual.php) — это выделенные IPv4-адреса, статичные на весь срок плана, к каждому из которых применяется своя документированная квота; GraphQL-половина при этом масштабируется квотой запросов, так что обе половины считаются независимо.
