Продукты
Безлимитные прокси от $19/мес Ротационные прокси от $49/мес ISP прокси от $33/мес Персональные прокси от $3.50/мес UDP прокси от $5/мес Попробовать прокси
По целям
Парсинг и данные ИИ-сервисы Соцсети и мессенджеры Медиа и развлечения Все задачи →
Цены
Полная таблица цен Все 20 стран Гарантия возврата
Ресурсы
Блог MCP-сервер Инструкции по настройке Частые вопросы Для бизнеса О сервисе Партнёрская программа
Русский
English Русский
← Блог PapaProxy.net

Как синхронизироваться со временем сервера Binance API

Подписанные запросы несут таймстамп, и Binance отклоняет их по двум разным правилам: больше 1 000 мс вперёд относительно биржевых часов или старше вашего recvWindow. Расширить вы можете только второе.

API и данные · Автоматизация 1 августа 2026 4 минуты Alex Young Alex Young Технический специалист
Ключевые выводыGET /api/v3/time (вес 1, без ключа) возвращает serverTime в миллисекундах — часы, по которым оценивается каждый подписанный запрос.
  • GET /api/v3/time (вес 1, без ключа) возвращает serverTime в миллисекундах — часы, по которым оценивается каждый подписанный запрос.
  • Правило приёма несимметрично: жёсткий допуск в 1 000 мс для таймстампов впереди биржевых часов и recvWindow для отставших — 5 000 мс по умолчанию, 60 000 мс максимум.
  • Расширение recvWindow никогда не лечит вариант -1021 про «1000ms ahead» — это проблема часов; а Binance рекомендует держать окно в пределах 5 000 мс, потому что оно же работает окном для replay-атаки.
  • Мерьте офсет часов с компенсацией круга: наивная разность serverTime - localTime завышала расхождение примерно на 134 мс с наших немецких адресов и на 11 мс с японских — это половина круга, а не сломанные часы.

Краткое содержание подготовлено с помощью ИИ.

Как читать часы биржи

Эндпоинт серверного времени — самый простой вызов в API: GET /api/v3/time стоит 1 вес, не требует ключа и возвращает единственное поле serverTime в миллисекундах. Именно по этому числу оценивается каждый подписанный запрос.

Ошибка кроется в том, как это число сравнивают со своим. Очевидный способ — вычесть локальное время из ответа и назвать разницу расхождением часов — незаметно вкладывает в результат вашу сетевую задержку: ответ, который вы держите в руках, сгенерирован где-то за Тихим океаном и потратил половину круга на дорогу обратно. Мерьте так, как это делает NTP: возьмите вызов в скобки из локальных отметок времени и скомпенсируйте полёт.

Python
import time, requests

def clock_offset(base="https://api.binance.com", samples=10):
    offsets = []
    for _ in range(samples):
        t0 = time.time() * 1000
        server = requests.get(f"{base}/api/v3/time").json()["serverTime"]
        t1 = time.time() * 1000
        offsets.append(server - (t0 + t1) / 2)   # середина отрезка гасит круг
        naive = server - t1                       # что показал бы наивный метод
    offsets.sort()
    return offsets[len(offsets) // 2], naive      # медианный офсет, последний наивный замер

offset, naive = clock_offset()
print(f"истинный офсет: {offset:+.0f} мс   наивная оценка: {naive:+.0f} мс")

На что смотреть: скомпенсированная медиана — ваше реальное расхождение часов, и на любом хосте с работающим NTP она укладывается в несколько десятков миллисекунд. Разрыв между двумя напечатанными числами — чистая география. Мы прогнали это со своей сети в июле 2026-го: с японских адресов наивный метод завышал офсет примерно на 11 мс, с немецких — примерно на 134 мс, то есть почти ровно на половину круга, замеренного для этих регионов. Европейский сервер, «продиагностированный» наивным методом, выглядит как машина со сломанными часами, хотя часы у него в порядке.

Отсюда два практических правила. Дисциплинируйте часы хоста через NTP (chrony или systemd-timesyncd), а не правкой таймстампов в коде; и если офсет всё же применяете, мерьте его периодически в фоне, а не перед каждым запросом — иначе вы тратите вес и добавляете круг в критический путь ради информации, которая меняется медленно.

Как recvWindow решает, принять ли запрос

Каждый подписанный запрос несёт timestamp и может нести параметр recvWindow, который сообщает бирже, как долго эта подпись остаётся действительной. Документированную логику приёма стоит прочитать буквально, потому что она несимметрична:

Код
if (timestamp < (serverTime + 1000) && (serverTime - timestamp) <= recvWindow) {
  // обработать запрос
} else {
  // отклонить запрос
}

Читаем слева направо. Первое условие — допуск «в будущее», и это жёсткие 1 000 мс, которые не настраиваются: запрос с таймстампом больше чем на секунду впереди биржевых часов будет отклонён при любых настройках. Второе условие — допуск «в прошлое», и вот это уже recvWindow: 5 000 мс по умолчанию, 60 000 мс максимум.

Эта асимметрия объясняет самый частый впустую потраченный вечер в интеграциях с Binance. Ошибка -1021 приходит в двух вариантах: «Timestamp for this request was 1000ms ahead of the server's time» и «Timestamp for this request is outside of the recvWindow». Выглядят они как одна проблема, но это не так. Расширение recvWindow ничего не даёт первому сообщению — спешащие часы лечатся часами. Помогает оно только со вторым, где запрос действительно шёл слишком долго между подписью и приходом.

Отсюда вопрос, насколько широким его ставить. Рекомендация самой Binance в документации эндпоинта серверного времени — держать recvWindow небольшим, 5 000 мс или меньше, и причина здесь в безопасности, а не в производительности: окно определяет, как долго перехваченный запрос остаётся пригодным к повтору, так что 60-секундное окно — это 60 секунд возможности для replay-атаки, которые вы выдали себе сами. Считайте максимум аварийной мерой для по-настоящему плохого канала, а не значением по умолчанию. И помните, на что окно расходуется: задержка тратится из него. Подписанный ордер из Европы сжигает около 135 мс бюджета только на дорогу до Токио, ещё до того, как движок что-то сделает — внутри 5 000 мс это комфортно, но означает, что канал с редкими многосекундными зависаниями даст отказы по таймстампу, которые выглядят случайными, но таковыми не являются.

Как проверить связь до того, как винить часы

Прежде чем грешить на часы, потратьте десять секунд на доказательство связи. Эндпоинт ping — GET /api/v3/ping, вес 1, пустой JSON в ответе — отвечает на один вопрос: способна ли эта машина вообще достучаться до этого API? Запустите его, затем вызов времени, затем свой подписанный запрос: первый упавший шаг и скажет, какой слой чинить.

Bash
curl -s -o /dev/null -w "%{http_code}\n" https://api.binance.com/api/v3/ping   # доступность?
curl -s https://api.binance.com/api/v3/time                                     # часы?

Ping падает или отдаёт неожиданный статус — проблема в сети, хосте или правомочности для вашего региона, и никакие таймстампы её не вылечат. Ping проходит, а подписанные вызовы падают с -1021 — вот теперь часы законный подозреваемый, и замер офсета выше покажет, расхождение это или всего лишь расстояние. Ping и time проходят оба, а подписанные вызовы падают с -1022 — это подпись, а не часы: строка параметров, которую вы подписали, не совпадает с отправленной.

Есть ещё одна причина держать эту лесенку в стартовой процедуре, а не в памяти. Отказы по таймстампу кучкуются вокруг событий, никак не связанных с кодом: виртуалка, поднятая из паузы; хост контейнера с уплывающими часами; воркер, передеплоенный в другой регион. Логирование скомпенсированного офсета и времени круга при старте, рядом с исходящим IP, превращает каждое из них в однострочный диагноз вместо вечера отладки.

Расстояние — та часть, которую действительно можно заложить в проект. На ордерном пути каждая миллисекунда между подписью и приходом тратится сразу из двух бюджетов: из recvWindow, который решает, примут ли запрос, и из проскальзывания, которое решает, сколько он стоит. Поэтому активные трейдеры выносят точку выхода поближе к матчинг-движку в Токио — и ровно для этого используют наши прокси для Binance: выделенные IPv4-адреса с выбором страны, статичные на весь срок плана, чтобы адрес из правил IP whitelisting оставался тем адресом, с которого вы подключаетесь.