Два источника действительно реального времени, а третий — нет, и это стоит знать до того, как проектировать вокруг них. Котировки приходят потоком по server-sent events по мере ответа провайдеров. Кросс-провайдерский фид курсов пересобирается каждые несколько секунд. Статус ордера опрашивается: вебхуков пока нет, поэтому push-слой, который видят ваши пользователи, поднимаете вы.
/v1/partner/quotes-sse— первое предложение за 200–400 мс, поток закрывается сам./v1/export/rates.xml— лучший исполнимый курс по направлению, без ключа, всегда свежий.- Ордера: опрос раз в 5–10 секунд или один синхронный refresh.
- Price alerts строятся на фиде курсов, статусные — на цикле опроса.
Три источника, три ритма
| Источник | Ритм | Ключ | Для чего |
|---|---|---|---|
GET /v1/partner/quotes-sse | Push в рамках запроса. События: offer, private_route, provider_error, ping, done. Закрывается по timeout_ms — по умолчанию и максимум 5000. | да | Живой калькулятор, чекаут — всё, где ждёт пользователь. |
GET /v1/export/rates.xml | Пересобирается каждые несколько секунд и кэшируется. | нет | Табло курсов, мониторинги, price alerts, виджеты «1 BTC = …». |
GET /v1/partner/orders/{id} | Опрос раз в 5–10 с; наш поллер обновляет каждый открытый ордер раз в 10 с. | да | Таймлайны статусов, уведомления, сверка. |
POST /v1/partner/orders/{id}/refresh | Синхронно, не чаще раза в 5 с. | да | «Я отправил» — один немедленный ответ, а не более частый цикл. |
Фид отдаёт исполнимый курс, а не индекс. Каждый
<item> — лучший кросс-провайдерский курс по направлению с
minamount, maxamount и признаком
floating/fixed. Алерт на его основе срабатывает по
числу, по которому пользователь действительно может обменять, — чего не даёт
биржевой тикер.
Чтение потока
const res = await fetch(sseURL, {
headers: { "X-API-Key": key, Accept: "text/event-stream" },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
let buf = "";
for (;;) {
const { value, done } = await reader.read();
if (done) break;
buf += value;
let i;
while ((i = buf.indexOf("\n\n")) !== -1) { // один SSE-фрейм
const frame = buf.slice(0, i); buf = buf.slice(i + 2);
const event = /^event:\s*(.+)$/m.exec(frame)?.[1];
const data = JSON.parse(/^data:\s*(.+)$/m.exec(frame)?.[1] ?? "null");
if (event === "offer") render(data); // рисуйте сразу по приходу
if (event === "provider_error") log(data); // в лог, но не на экран
if (event === "done") rerank(data.deviations); // финальный рейтинг нарисованного
}
}
Как собрать price alerts
-
Опрашивайте фид, а не эндпоинт котировок
/v1/export/rates.xmlотдаётся без ключа, кэшируется и покрывает все направления сразу — одного запроса хватает на все ваши алерты. Отдельная котировка на пару каждого пользователя — верный способ попасть под троттлинг провайдеров. -
Сравнивайте по направлению вместе с лимитами
Алерт на BTC → USDTTRC20 имеет смысл только внутри
minamountиmaxamount. Храните оба значения рядом с порогом, чтобы не уведомлять человека о курсе, которым он не сможет воспользоваться. -
Гасите дребезг до уведомления
Курсы колеблются. Требуйте, чтобы порог держался два чтения подряд, и перевзводите алерт только после отхода курса на запас — иначе спокойный рынок пришлёт сотню уведомлений.
-
Превращайте алерт в предложение
Как только пользователь решил действовать, считайте нормальную котировку через
/quotesили/quotes-sse: фид говорит о том, что было доступно несколько секунд назад, а исполнимо только предложение — и то пять минут.
Статусные алерты устроены зеркально: один цикл опроса на открытый ордер и ваша собственная рассылка туда, где слушают пользователи, — websocket, ваш собственный вебхук или сообщение в Telegram.
Что не в реальном времени
| Чего нет | Что делать вместо этого |
|---|---|
| Вебхуков по статусу ордера | Опрашивать раз в 5–10 секунд до финального статуса и рассылать пользователям самим. Если вебхуки меняют вашу интеграцию — скажите нам: их приоритет определяется спросом. |
| Постоянного websocket | Стриминговые эндпоинты — это SSE в рамках одного запроса котировки; они закрываются сами в пределах пяти секунд. |
| Истории курсов и свечей | Фид отдаёт текущий лучший курс. Историю для графиков храните у себя. |
| Price alerts как готового сервиса | Пороги, хранение и уведомления — ваши; API даёт число, с которым они сравниваются. |
| Постоянных потоков курса по каждому провайдеру | Предложения приходят по провайдерам внутри потока котировок, но отдельного постоянного фида на провайдера нет. |
Кто на этом работает
- Мониторинги и агрегаторы, читающие
rates.xmlв формате, который они и так разбирают. - Боты-алерты — Telegram, Discord, почта — срабатывающие по исполнимому курсу, а не по биржевому тикеру.
- B2B-партнёры с дашбордами, раздающие статусы ордеров своих клиентов из одного цикла опроса.
- Кошельки и калькуляторы, где число на экране должно двигаться, пока пользователь думает.
Вопросы
Присылает ли SwapZilla вебхуки при смене статуса ордера?
Пока нет. Статус читается опросом GET /v1/partner/orders/{id} раз в 5–10 секунд до финального, а наш собственный поллер и так обновляет каждый открытый ордер раз в десять секунд. Приоритет вебхуков определяется спросом партнёров, поэтому об интеграции, которой они нужны, стоит сказать.
Стриминговый эндпоинт — это websocket?
Нет, это server-sent events поверх обычного HTTP-запроса, привязанные к одной котировке: предложения приходят по мере ответа провайдеров, ping держит прокси живыми, а поток закрывается сам по timeout_ms — 5000 мс по умолчанию и по максимуму.
Как часто меняется фид курсов?
/v1/export/rates.xml пересобирается каждые несколько секунд и кэшируется, поэтому опрашивать его чаще бессмысленно. Он публикует лучший кросс-провайдерский курс по направлению с минимальной и максимальной суммой и типом курса в формате мониторингов.
Можно собрать price alerts без API-ключа?
Сам фид публичный: /v1/export/rates.xml ключа не требует, как и /v1/assets с /v1/validate-address. Ключ нужен в тот момент, когда алерт превращается в настоящую котировку или ордер.
Почему не котировать пару каждого пользователя по таймеру?
Потому что провайдеры ограничат повторные котировки задолго до того, как это сделает SwapZilla. Фид и существует ради того, чтобы наблюдение за ценой стоило одного запроса на всех, а котировки оставались на момент, когда пользователь готов обменивать.
Насколько свеж только что прочитанный статус?
Не старше примерно десяти секунд: фоновый поллер обновляет каждый открытый ордер с этим интервалом. Если пользователь только что сказал «я отправил», POST /v1/partner/orders/{id}/refresh синхронно сходит к провайдеру и вернёт обновлённый ордер — вызывайте его один раз, а не в цикле.
Что ещё собирают на этом же ключе
- Ссылки на оплату и инвойсы в криптовалютеОплата по ссылке и инвойсы для фрилансеров и подрядчиков: котировка по сумме счёта, зачисление напрямую на кошелёк получателя.
- Крипто-процессинг и эквайринг для бизнесаЧекаут для магазинов и SaaS: приём 100+ активов, зачисление в одном, сверка по вашему order id.
- API обмена криптовалют, SDK и виджетОбмен внутри кошелька, бота, агрегатора или сайта: стриминг котировок, один вызов на ордер, ваш интерфейс.
- Крипто-payroll для подрядчиков и распределённых командРегулярные выплаты реестру подрядчиков: свой актив и сеть у каждого, точная сумма на руки, сверка по периодам.
- Multi-send: массовые выплаты на множество адресовРазовая веерная рассылка выплат на сотни адресов: кросс-чейн, статус по каждому, безопасные повторы.
- Свой MCP-сервер для ИИ-агентовГотовый swapzilla-mcp одной строкой — или свой, на вашем партнёрском ключе, с белыми списками и лимитами.
Как получить ключ
Зарегистрируйтесь в партнёрском кабинете — партнёрский id и api_key для заголовка X-API-Key выпускаются сразу. Ключ становится рабочим после активации: напишите в @swapzilla_support_bot и коротко опишите интеграцию. Все эндпоинты, поля и статусы — в документации partner API.