Лимиты и ограничения частоты

Ваши возможности ограничивают две независимые вещи: сколько поисков в день разрешает тариф и как часто могут приходить запросы. И то и другое сообщается в каждом ответе, так что клиент может сам выдерживать темп и не провоцировать ошибку, чтобы узнать, где проходят границы.

Ограничение частоты: десять запросов в минуту

Ограничение общее для всего аккаунта - для API и MCP-сервера вместе: десять вызовов в минуту, каким бы путём они ни пришли. Одиннадцатый запрос в пределах этого окна сразу получает ответ 429 too_many_requests с заголовком Retry-After, в котором указано, через сколько секунд освободится место. То же число есть в теле ответа как error.retry_after.

HTTP/2 429
Retry-After: 18

{ "error": { "code": "too_many_requests",
             "message": "At most 10 requests per minute.",
             "retry_after": 18 } }

Подождите Retry-After секунд и повторите запрос. Ничего не израсходовано, лимит не тронут.

API никогда не держит соединение открытым, чтобы вас притормозить. Старые адреса выгрузки так делают - ждут по секунде до полуминуты, прежде чем отказать, - и это одна из причин, по которым появился API.

Суточный лимит

Тариф разрешает определённое число поисков в день и определённое число запросов с фрагментами в день - они считаются отдельно. Оба лимита сбрасываются в ближайшую полночь по UTC, а не через 24 часа после использования.

Когда лимит исчерпан, запрос отклоняется с 429 quota_exceeded или 429 snippet_quota_exceeded; в ответе указаны лимит, сколько уже израсходовано и сколько осталось до сброса. Исчерпанный лимит фрагментов не мешает обычным поискам.

Глубина выдачи

Тариф также определяет, до какого места в рейтинге результаты остаются открытыми, - disclosed_positions в /v1/account. Строки ниже этой границы не заменяются пустыми, а просто не попадают в ответ, и если такие были, то truncated в теле равно true, а в заголовках стоит X-Truncated: true.

В этом главное различие между API и сайтом. Когда у посетителя сайта кончается лимит, сайт незаметно переходит на глубину бесплатного тарифа и показывает меньше - для человека, который смотрит на страницу, это нормально. Скрипт же этого не заметит, поэтому API не урезает ответ, а отказывает.

Как узнать текущее состояние

Каждый ответ на запрос с ключом содержит пять заголовков:

ЗаголовокЧто означает
X-RateLimit-LimitСколько поисков разрешено сегодня.
X-RateLimit-RemainingСколько поисков осталось на сегодня.
X-RateLimit-ResetВремя сброса суточного лимита в формате Unix time.
X-Snippets-LimitСколько запросов с фрагментами разрешено сегодня.
X-Snippets-RemainingСколько запросов с фрагментами осталось на сегодня.

В ответах с результатами есть ещё три:

ЗаголовокЧто означает
X-Total-ResultsСколько сайтов совпало во всём индексе.
X-Returned-ResultsСколько строк в этом ответе.
X-Truncatedtrue, если ограничение глубины тарифа убрало часть строк.

Статистика использования

/v1/account даёт полную картину за один вызов и ничего не расходует:

curl -H "Authorization: Bearer $KEY" https://api.publicwww.com/v1/account
{
  "plan": "enterprise",
  "plan_until": 1819461840,
  "full_access": true,
  "quota": {
    "searches": { "limit": 300, "used": 12, "resets_at": 1787961600 },
    "snippets": { "limit": 100, "used": 3,  "resets_at": 1787961600 }
  },
  "limits": {
    "disclosed_positions": 4294967295,
    "disclosed_positions_snippets": 4294967295,
    "max_per_page": 1000000,
    "max_per_page_snippets": 10000
  }
}

Прежний адрес https://publicwww.com/profile/api_status.xml?key=... отдаёт те же счётчики в XML и по-прежнему работает. Он относится к старым адресам; в новом коде используйте /v1/account - он сообщает не только расход, но и сами лимиты.

Далее Ошибки