# Чем различаются лимиты DexScreener по эндпоинтам

> Единого лимита у DexScreener нет. У каждого маршрута он свой, и все они делятся на два уровня — 60 запросов в минуту и 300, — причём дешёвый уровень покрывает ровно те эндпоинты, которые хочется опрашивать чаще всего.

- Источник: https://papaproxy.net/ru/blog/dexscreener-rate-limits.php
- Опубликовано: 2026-08-09
- Автор: Alex Young
- Рубрика: Лимиты и производительность · Блог PapaProxy.net

---

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

- Единого лимита нет: маршруты стоят либо на 60, либо на 300 запросах в минуту.
- Кураторские списки получают 60, а всё, что ключуется уже известным адресом, — 300.
- Обнаружение идёт по дефицитному уровню, а обогащение по щедрому — обратно тому, что закладывают в большинство схем.
- Пачка до 30 адресов в `/tokens/v1/` поднимает теоретический потолок до 9 000 адресов токенов в минуту вместо 300.
- Публичный справочник бесплатен и без ключа, а самостоятельного апгрейда в нём нет, но условия использования упоминают платную версию с лимитами, определяемыми при оформлении.
- Документация не описывает ни код ошибки, ни заголовки, ни сброс окна, ни область действия счётчика: считайте у себя и по каждому эндпоинту.
- Условия разрешают коммерческое использование, но запрещают конкурирующие продукты и перепродажу API третьим лицам.

## Два лимита, а не один

Документация по лимитам указывает число в описании каждого эндпоинта, а не на отдельной странице, — поэтому и упускают, что лимитов два. Лимит запросов в минуту целиком зависит от того, какой маршрут вы вызываете:

| Уровень | Маршруты |
| --- | --- |
| **60 запросов/мин** | `/token-profiles/latest/v1`, `/token-profiles/recent-updates/v1`, `/community-takeovers/latest/v1`, `/ads/latest/v1`, `/token-boosts/latest/v1`, `/token-boosts/top/v1`, `/orders/v1/{chainId}/{tokenAddress}`, `/metas/trending/v1`, `/metas/meta/v1/{slug}` |
| **300 запросов/мин** | `/latest/dex/pairs/{chainId}/{pairId}`, `/latest/dex/search`, `/token-pairs/v1/{chainId}/{tokenAddress}`, `/tokens/v1/{chainId}/{tokenAddresses}` |

Одна оговорка, прежде чем строить вокруг этой таблицы конфиг: справочник правят на месте, и маршруты добавлялись и исчезали без смены версии. Считайте список снимком и сверяйте его с живым справочником перед релизом. Сами два числа — 60 и 300 — держатся стабильно.

И заметьте, что документация утверждает, а что нет. В описании каждого эндпоинта указан его собственный лимит; нигде не сказано, черпают ли маршруты с одинаковым числом из общего ведра или считаются независимо. Деление 60/300 удобно для разговора об API, но это не документированное утверждение об устройстве ограничителя.

У этого разделения есть внутренняя логика, стоит её заметить. Уровень 60 в минуту — это всё, что возвращает *кураторский список*: профили, бусты, реклама, community takeovers, трендовые меты, — где данные меняются медленно, а все вызывающие получают один и тот же ответ. Уровень 300 в минуту — всё, что ключуется адресом, который у вас уже есть. DexScreener щедр там, где ваши запросы конкретны, и скуп там, где они широкие.

Это переворачивает экономику, которую обычно предполагают. Обнаружение — поиск нового — идёт по дефицитному бюджету, а обогащение, то есть оценка и измерение найденного, — по щедрому. Любая схема, которая агрессивно опрашивает ленту обнаружения и скупо запрашивает пары, устроена наоборот. Если ваша цель — [новые пары через API](/ru/blog/dexscreener-new-pairs.php), двухэтапная схема — опрос профилей на 60, обогащение на 300 — как раз то, что описывает эта таблица.

Одно число для перспективы: 60 запросов в минуту — это раз в секунду, и именно этот потолок вам позволено закладывать в план независимо от того, как часто на самом деле меняются данные. А вот на стороне запросов число в минуту значит куда больше — и здесь в дело вступает группировка.

## Какие маршруты сидят на 60

Проще запомнить закономерность, чем список: если маршрут возвращает список, который вы не параметризовали, он на уровне 60. Профили latest и recent-updates, community takeovers, реклама, оба буст-маршрута, трендовые меты, мета по слагу — ни один не принимает фильтр по сети, возрасту или размеру, поэтому все получают по сути одну и ту же нагрузку, и 60 вызовов в минуту с запасом хватает, чтобы держать её свежей.

Единственный маршрут этого уровня, не являющийся кураторским списком, — `/orders/v1/{chainId}/{tokenAddress}`: он проверяет оплаченные заказы по конкретному токену и параметризован, но всё равно ограничен шестьюдесятью. Если ваш конвейер проверяет статус заказов по каждому токену, именно этот эндпоинт упрётся в лимит первым, а не запросы пар вокруг него.

Публичный лимит API действует без всякого ключа: каждый маршрут в справочнике — неаутентифицированный GET, и рядом с опубликованными числами 60 и 300 не описано никакого самостоятельного пути апгрейда. Но это не вся картина. Условия использования API от DexScreener прямо говорят, что пользователь может выбрать между бесплатной и платной версией API Services, причём спецификации — в том числе ограничение частоты и число запросов в секунду — определяются при оформлении. То есть «бесплатный тариф» разумно описывает то, что открывает публичный справочник, но не доказывает отсутствия более высокого уровня: если нужен запас, это разговор с DexScreener, а не параметр, который можно отправить.

## Как уместить 30 адресов в один вызов

Вот рычаг, который меняет арифметику проекта. `/tokens/v1/{chainId}/{tokenAddresses}` принимает, дословно по справочнику, один или несколько адресов токенов через запятую — **до 30 адресов** — и возвращает пары по всем сразу одним ответом. И относится он к уровню 300 в минуту.

Перемножим: 30 адресов × 300 вызовов в минуту = **9 000 адресов токенов в минуту** с одного вызывающего против 300, если запрашивать по одному адресу через `/token-pairs/v1/{chainId}/{tokenAddress}`. Тридцатикратная разница ценой одного `join`.

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

```python
import requests

BASE = "https://api.dexscreener.com"
HEAD = {"Accept": "application/json"}

def chunks(items, size=30):                 # документированный потолок: 30 адресов на вызов
    for i in range(0, len(items), size):
        yield items[i:i + size]

def pairs_for_tokens(chain_id, addresses):
    out = []
    for batch in chunks(addresses):
        r = requests.get(f"{BASE}/tokens/v1/{chain_id}/{','.join(batch)}",
                         headers=HEAD, timeout=15)
        if r.status_code == 429:            # не документировано, но обработать стоит
            raise RuntimeError("упёрлись в лимит — отступить и повторить")
        r.raise_for_status()
        out.extend(r.json() or [])
    return out

# 90 токенов → 3 вызова вместо 90
pairs = pairs_for_tokens("solana", token_list)
print(len(pairs), "пар из", len(token_list), "токенов")
```

На что смотреть: разбиение на части — это и есть весь смысл, а потолок пачки жёсткий, ровно 30; отправите 31 — полагаетесь на неопределённое поведение. Учтите и то, что один токен может вернуть несколько пар, поэтому длина ответа не совпадёт с длиной входа: ключуйте результаты по `pairAddress`, а не рассчитывайте на соответствие один к одному.

Чего пример намеренно не делает: нет отступления, нет ретраев, нет контроля параллелизма. Добавьте это до запуска на большом списке — при 300 вызовах в минуту наивный цикл с параллельными воркерами пересечёт черту быстро.

Арифметика планирования следует напрямую — с одной честной пометкой: это **теоретические минимумы при опубликованном лимите**, в предположении 300 равномерно доступных вызовов в минуту и отсутствия всплесковых или глобальных ограничителей, которых документация не описывает:

| Токенов под наблюдением | Вызовов за цикл | Теоретический минимум обновления |
| --- | --- | --- |
| 300 | 10 | 2 секунды |
| 1 000 | 34 | 7 секунд |
| 5 000 | 167 | 34 секунды |
| 9 000 | 300 | 60 секунд |

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

## Что происходит при упоре в лимит

Здесь честный ответ таков: документация об этом не говорит. Справочник задаёт числа и форму ответа `200` для каждого маршрута; он не определяет ни кода состояния при превышении, ни того, сообщают ли какие-либо заголовки об остатке бюджета, ни того, как сбрасывается окно, ни — что важнее всего — на что именно ключуется счётчик.

Проектируйте с учётом этой неопределённости, а не в обход неё:

**Считайте на своей стороне.** Раз ни одно поле ответа не документировано как индикатор остатка, единственный надёжный бюджет — собственный счётчик; и пока вы не измерили обратное, считайте по каждому эндпоинту отдельно, а не по уровню, потому что документация нигде не говорит, делят ли маршруты с одинаковым числом общее ведро. Счётчик считайте авторитетным, а любую ошибку — подтверждением того, что предел уже пройден.

**Обрабатывайте 429, но не полагайтесь на него.** Общепринятый ответ — HTTP 429, и сниппет выше его проверяет, — но поскольку он не документирован, не стройте логику в расчёте на то, что придёт заголовок `Retry-After` с полезным значением. Экспоненциальный откат с джиттером, ведомый вашим собственным счётчиком, переживёт любое фактическое поведение сервера.

**Следите и за задержкой, а не только за кодами.** Некоторые площадки сначала троттлят и лишь потом отклоняют, и клиент, который алертит только на коды ошибок, будет выглядеть здоровым, пока его данные устаревают. Снимайте p95 длительности запроса по каждому маршруту.

**Не предполагайте область действия.** Ключа нет, а значит, нет и аккаунта, к которому можно привязать расход, — то есть счётчик может ключеваться только на что-то сетевого уровня. Но справочник этого не утверждает, не обещает независимого бюджета каждому адресу и не описывает модель всплесков. Измерьте фактическое поведение, прежде чем проектировать парк вокруг предположения о нём.

Последний пункт — то место, где появляется инфраструктура, и только после того, как исчерпаны программные рычаги: группируйте по 30, кешируйте ленты профилей вместо повторного опроса, опрашивайте обнаружение не чаще, чем меняются данные, и обогащайте по адресам, а не широким обходом. За этими рычагами — если ваши замеры подтвердят, что отдельные вызывающие действительно получают отдельные бюджеты, — наши [персональные прокси](/ru/individual.php) дают выделенные IPv4-адреса, статичные на весь срок плана, по одному на воркера, чтобы всплеск одной задачи не съедал квоту другой. И прочитайте условия использования API до масштабирования — они конкретны, а не расплывчаты: коммерческое использование разрешено, но нельзя строить и продвигать продукт, чья основная цель — прямая конкуренция с DexScreener, и нельзя перепродавать, сублицензировать или иначе предоставлять API Services третьим лицам.
