Configurar un webhook
En Webhooks del dashboard, confirma la habilitación de tu cuenta, registra la URL HTTPS de tu servidor, selecciona tasas y eventos, y guarda el secretowhsec_… en la configuración privada. Es distinto de tu API Key. Los avisos no consumen consultas de la API.
El esquema descrito aquí usa el aviso de tasa simplificado: delivery_type identifica pruebas y previous_mid es el valor anterior. El idioma del sitio no cambia el payload ni la firma.
Planes y límites
Gratis e Inicio no incluyen webhooks. Los pausados cuentan para el límite; el webhook de prueba no. El tope mensual de avisos se reinicia el día 1 UTC, separado del ciclo de consultas de la API. Cuentan cambios de tasa y eventos de cuenta; no reintentos, pruebas,
sync, recovery ni probe. Al agotarlo se bloquea Binance, incluidas sus sincronizaciones y recuperaciones; BCV, paralelo y avisos de cuenta continúan.
El panel avisa al 80 %, 95 % y 100 % del cupo de avisos. Un cambio a un plan sin webhooks los pausa sin borrarlos. Si el nuevo límite es menor, se priorizan los más antiguos. Al recuperar un plan compatible se pueden reactivar los pausados por el plan; las nuevas suscripciones no se seleccionan automáticamente.
Mercados y frecuencia
Los cuatro mercados sonreference (USD), eur_reference (EUR), parallel (USD) y binance (USD). Los demás mercados se consultan por API. BCV y paralelo avisan al detectar cambios; Binance respeta el intervalo del plan y envía el valor más reciente que haya cambiado. No se envía cada movimiento intermedio ni se garantiza una hora exacta.
Sincronización
Al crear, reactivar o cambiar URL, tasas o cabeceras se envía el valor actual, como máximo una vez por mercado y webhook cada 15 minutos. Editar solo la descripción no dispara esta sincronización. El cupo agotado sigue bloqueando Binance.Sobre y datos
El sobre contieneid, type, timestamp, delivery_type y data. timestamp identifica el evento y permanece igual en los reintentos. El esquema actual no incluye el booleano test: identifica pruebas con delivery_type === "test".
Respuesta ilustrativa: las cifras y fechas no son cotizaciones actuales.
rate.updated requiere market, mid y updated_at. ask, bid, previous_mid y change_pct se omiten si no hay dato. effective_date aparece para BCV. change_pct compara con el valor anterior del mercado, no necesariamente con el último que recibiste. type, base, best, vs_reference_pct, source_changed y el objeto previous ya no forman parte de data; la base de eur_reference es EUR, la de los otros tres es USD.
Los planes en JSON usan códigos como
free, lite, hobby, indie y pro. No traduzcas valores ni campos al cambiar el idioma.
Tipo de envío
Procesa tipos conocidos de acuerdo con tu aplicación. Las alertas de movimiento se disparan solo con
change; sync, probe y recovery pueden repetir el mismo valor. Un tipo desconocido o ausente se registra para revisión y no se interpreta automáticamente como un cambio.
Cabeceras
HTTP no distingue mayúsculas en cabeceras. Las cabeceras
cotizave-* no están firmadas: selecciona el secreto mediante una configuración de confianza y luego verifica. Toma decisiones sobre type y delivery_type del cuerpo verificado.
Verificar, persistir y responder
Responde2xx antes de 10 segundos después de verificar y guardar el evento de forma duradera. Si falla la persistencia, devuelve 503 para permitir reintento. No respondas 200 antes de guardarlo ni uses una cola solo en memoria.
Este adaptador Node.js usa el verificador de la sección siguiente. Debes implementar secretFor con tus secretos privados y persistOnce con una transacción y una restricción única por webhook y evento. Un duplicado ya persistido debe resolverse sin error; un fallo real de almacenamiento debe rechazar la promesa. Configura express.raw para esta ruta antes de cualquier parser JSON y limita el tamaño del body.
webhook-handler.mjs
updated_at más reciente, comparando timestamps y coordinando actualizaciones concurrentes. La firma no sustituye la deduplicación.
Firma HMAC-SHA256
Se firma la secuencia de byteswebhook-id + "." + webhook-timestamp + "." + cuerpo original. La clave es el secreto sin whsec_, decodificado de base64. No reserialices JSON ni traduzcas contenido antes de verificar. Rechaza una diferencia de reloj mayor que 300 segundos y compara firmas en tiempo constante. Acepta cualquiera de las firmas válidas durante una rotación. El formato sigue Standard Webhooks.
0, 1h, 24h o 7d; con 0 deja de firmar. Durante la convivencia llegan dos firmas. Cada receptor puede usar su secreto vigente dentro de esa ventana.
Vector de prueba local
Este secreto es público y sirve únicamente para tests. Usa el timestamp indicado comonow al probar. Los bytes del body deben coincidir exactamente; cambiar contenido, espacios o acentos invalida la firma.
signature-vector.json
Reintentos y pausa
2xx confirma entrega. Errores de red, 408, 429 y 5xx pueden reintentarse hasta cuatro intentos: inmediato, después de 10 s, 30 s y 2 min, con variación de hasta ±20 %. Para 429/5xx, un Retry-After puede ampliar la espera hasta 2 min; si pide más, se detienen los reintentos de ese aviso. Otros 4xx y redirecciones 3xx fallan sin reintento. 410 pausa inmediatamente un webhook real.
El ID y el body permanecen iguales entre intentos; el timestamp de envío y la firma se renuevan. Un aviso de tasa más reciente puede reemplazar uno pendiente, que no podrá reenviarse. Tras un fallo se realizan comprobaciones con el valor actual cada 5 min; al recuperarse se sincronizan las tasas pendientes. Los eventos de cuenta no generan comprobaciones.
Se permite como máximo un envío en curso por tasa y webhook; no hay orden entre tasas. Con 6 fallos consecutivos y al menos 10 min fallando se pausa el webhook; un 2xx reinicia la cuenta. Reactívalo desde el panel tras corregir tu receptor, sujeto a los límites de sincronización. Los tests no activan pausa automática.
URL y cabeceras propias
La URL debe usar HTTPS y puerto 443, un dominio que resuelva a una IP pública, sin credenciales ni fragmento, hasta 2.048 caracteres. No se permiten IP literales, localhost, dominios internos/locales ni dominios de Cotizave. Registra la URL final: no se siguen redirecciones. Puedes configurar hasta tres cabeceras, con nombres HTTP válidos de hasta 64 caracteres y valores ASCII visibles de hasta 1 KB. Se reservan cabeceras de transporte y seguridad, incluidashost, content-type, content-length, user-agent, cookies y los prefijos webhook-, cotizave-, proxy- y cf-. El panel valida los nombres. Un token propio no sustituye HMAC.
Webhook de prueba
El webhook de prueba solo recibe envíos solicitados o reenviados al entorno de prueba, condelivery_type: test. Tiene su propio secreto e historial; no consume el cupo de avisos ni recibe cambios reales automáticamente. Un reenvío de prueba recibe un ID nuevo. La prueba de tasa usa una cotización actual; si no existe devuelve 409 quote_unavailable sin enviar.