BotRadixBotRadixDocumentación

Tiempo real y webhooks

Webhooks firmados, cómo verificarlos y el estado del endpoint de streaming.

Ver en Markdown

Los webhooks entregan a tu servidor los eventos de la cuenta de tu wallet en cuanto BotRadix los indexa desde la cadena, para que no tengas que consultar sin parar.

Crear un webhook#

Los webhooks se gestionan con una sesión de desarrollador (ver API: visión general y autenticación):

bash
curl -X POST https://app.botradix.com/api/dex/developer/webhooks \
  -H "Authorization: Bearer $DEVELOPER_SESSION" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/botradix/webhook","events":["order.filled","position.changed","liquidation"]}'
ReglaValor
URLHTTPS en el puerto 443 u 8443, sin credenciales incrustadas, hasta 512 caracteres y resolviendo a IP públicas
LímiteHasta 8 webhooks activos por wallet
EventosUna lista de nombres de evento, o ["*"] para todos. Por defecto: transaction.confirmed y transaction.reverted
Secretosigning_secret (empieza por brx_whsec_) se devuelve una sola vez, al crear el webhook
BajaDELETE /api/dex/developer/webhooks/{webhook_id} desactiva la suscripción

Eventos#

EventoCuándo
order.acceptedUna orden fue aceptada en cadena
order.filledUna orden se ejecutó por completo
order.partially_filledUna orden se ejecutó en parte
order.cancelledUna orden fue cancelada
position.changedUna posición se abrió, aumentó, redujo, cerró o invirtió
liquidationUna posición fue liquidada
funding.charged / funding.creditedSe pagó o se cobró funding
collateral.changedUn depósito o un retiro cambió tu colateral
transaction.confirmed / transaction.revertedUna transacción conocida por BotRadix alcanzó la finalidad, con éxito o sin él
chain.reorgUna reorganización de la cadena cambió datos ya notificados
transaction.pendingSolo como corrección tras una reorganización (con revoked_event_id)

liquidation.warning se acepta en las suscripciones pero está reservado: hoy no se emite.

Nota

Los eventos transaction.* se envían para transacciones cuyo hash conoce BotRadix: las enviadas por el relay o por el ejecutor delegado, y aquellas cuyo hash comunicaste a /api/dex/actions/receipt.

Entrega#

Cada entrega es un POST HTTPS con un cuerpo JSON:

json
{ "id": "…", "type": "position.changed", "created_at": 1790950000, "data": { … } }
CabeceraContenido
X-BotRadix-EventTipo de evento
X-BotRadix-Event-IDID único y estable del evento (hasta 96 caracteres, igual que id en el cuerpo). Úsalo para descartar duplicados
X-BotRadix-TimestampHora Unix (segundos) de este intento de entrega
X-BotRadix-Signaturev1= seguido de la firma HMAC-SHA256 en hexadecimal
User-AgentBotRadix-DEX-Webhook/1.0
  • La entrega es al menos una vez: un mismo evento puede llegar más de una vez. Descarta duplicados por X-BotRadix-Event-ID.
  • Responde con cualquier código 2xx en menos de 4 segundos. No se siguen redirecciones.
  • Una entrega fallida se reintenta hasta 4 intentos en total, esperando 2, 4 y 8 segundos.
  • Los eventos pueden llegar desordenados; usa created_at y los propios datos para ordenarlos.

Verificar la firma#

La firma es un HMAC-SHA256 de timestamp + "." + cuerpo_sin_procesar, con tu signing_secret completo como clave. Verifícala siempre contra el cuerpo sin procesar, antes de interpretar el JSON, y rechaza marcas de tiempo antiguas.

javascript
// Node.js (en Express, usa express.raw({ type: "application/json" }) en esta ruta)
import crypto from "node:crypto";

export function verifyBotRadixWebhook(rawBody, headers, secret, toleranceSeconds = 300) {
  const timestamp = headers["x-botradix-timestamp"];
  const received = headers["x-botradix-signature"] || "";
  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;
  const expected = "v1=" + crypto.createHmac("sha256", secret).update(`${timestamp}.`).update(rawBody).digest("hex");
  return received.length === expected.length && crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
}
python
# Python
import hashlib, hmac, time

def verify_botradix_webhook(raw_body: bytes, headers, secret: str, tolerance: int = 300) -> bool:
    timestamp = headers.get("X-BotRadix-Timestamp", "")
    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > tolerance:
        return False
    expected = "v1=" + hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(headers.get("X-BotRadix-Signature", ""), expected)

Stream Server-Sent Events#

GET /api/dex/v1/stream?pair_id={id}&interval=1m está definido como un stream privado con snapshots de mercado y de cuenta y eventos de ciclo de vida, un latido cada 12 segundos y reanudación con Last-Event-ID. Aún no está activado en el servicio público y responde 503 REALTIME_STREAM_ASYNC_WORKER_REQUIRED. Mientras tanto, usa webhooks para los eventos de cuenta y los endpoints de lectura para los datos de mercado. Esta página se actualizará cuando se active.

Última actualización: 2026-10-12