Лимиты и ограничения частоты
Ваши возможности ограничивают две независимые вещи: сколько поисков в день разрешает тариф и как часто могут приходить запросы. И то и другое сообщается в каждом ответе, так что клиент может сам выдерживать темп и не провоцировать ошибку, чтобы узнать, где проходят границы.
Ограничение частоты: десять запросов в минуту
Ограничение общее для всего аккаунта - для 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 часа после использования.
- Поиск расходует одну единицу лимита поисков.
- Поиск с
snippets=1вместо этого расходует одну единицу лимита фрагментов. /v1/accountничего не расходует.
Когда лимит исчерпан, запрос отклоняется с
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-Truncated | true, если ограничение глубины тарифа убрало часть строк. |
Статистика использования
/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 - он сообщает не только расход, но и сами лимиты.