Qbox
Documentación

Nivel 1 · Conectado

Los avisos

Qué llega, cómo se comprueba su firma y los reintentos.

Te avisamos al momento de lo que pasa, con un POST a la dirección que pongas en tu área (https://), en JSON.

Un aviso
{
  "id": "evt_01jb7q8m2z9wk4c6n3d5h7f2qa",
  "type": "facility.reviewed",
  "createdAt": "2026-10-26T08:20:00Z",
  "connectionId": "6f1c…",
  "data": {
    "facilityId": "madrid-01",
    "decision": "returned",
    "reasons": [{ "code": "photos", "message": "Fotos" }],
    "message": "Sube fotos del interior."
  }
}

Qué llega

AvisodataCuándo
connection.created{connectionId, operator, scopes}Una gestora te da permiso
connection.revoked{connectionId}Lo retira
facility.linked{facilityId, status}La gestora dice si un centro es uno que ya tenía o es nuevo
facility.reviewed{facilityId, decision, reasons, message}El equipo lo publica, lo devuelve con sus motivos o lo retira
facility.issues{facilityId, issues}Lo que le falta a la ficha
lead.createdLa solicitudUna solicitud nueva, si la gestora las quiere en tu software
test.ping{}Desde tu área o con POST /webhooks/test

Su firma

Cada aviso lleva la cabecera Qbox-Signature: t=<segundos Unix>,v1=<firma>. La firma es el HMAC-SHA256, en hexadecimal, de <t>.<cuerpo tal cual>, con el secreto de los avisos de tu área (whsec_…). Comprueba la firma antes de usar el aviso, con el cuerpo sin tocar, y rechaza los de más de 5 minutos. Mientras cambias el secreto llegan dos v1=, una con cada secreto: vale con que coincida una.

import { createHmac, timingSafeEqual } from 'node:crypto';

export function isValid(rawBody, header, secret) {
  const parts = header.split(',').map((part) => part.trim().split('='));
  const t = Number(parts.find(([key]) => key === 't')?.[1]);
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest();
  return parts.some(([key, value]) => {
    if (key !== 'v1') return false;
    const given = Buffer.from(value, 'hex');
    return given.length === expected.length && timingSafeEqual(given, expected);
  });
}

Los reintentos

  • Responde con un 2xx en menos de 10 segundos. Si no, se reintenta a los 1, 5, 15 y 60 minutos, y después cada hora durante un día. Desde tu área puedes reintentar uno a mano.
  • Descarta los repetidos por su id. El orden no está garantizado: mira createdAt.
  • Solo a direcciones https:// públicas, sin redirecciones.

La prueba de la firma

En tu área, «Probar la firma» te manda dos avisos: uno bien firmado, que tienes que aceptar (2xx), y otro con una firma falsa, que tienes que rechazar (4xx). Es una de las pruebas de la certificación.

¿Dudas? Escríbenos a team@findqbox.com.