Spectra
Explorar docs

webhooks

Firmar requests

Cómo firmar tus POSTs al webhook con HMAC-SHA256 para que Spectra los verifique.


Cada POST a un webhook de Spectra debe llevar una firma HMAC-SHA256 del body. Requests sin firma o con firma inválida se rechazan con 401 Unauthorized.

La firma

X-Spectra-Signature: sha256=<hex>
X-Spectra-Timestamp: <unix-ms>

La firma se computa sobre <timestamp>.<body> (separados por punto):

import hmac, hashlib, time
secret = b"<bytes de tu secret>"
ts = str(int(time.time() * 1000))
body = '{"action":"buy","symbol":"BTCUSDT","qty":1}'
mac = hmac.new(secret, f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
headers = {
  "X-Spectra-Signature": f"sha256={mac}",
  "X-Spectra-Timestamp": ts,
  "Content-Type": "application/json",
}

Por qué el timestamp

Incluir el timestamp en el payload firmado liga el mensaje a un momento. Un mensaje capturado y replayado tras la ventana de 5 min falla la verificación — ver Replay.

Verificación server-side

El worker de Spectra:

  1. Lee X-Spectra-Timestamp. Rechaza si falta o tiene > 5 min.
  2. Lee X-Spectra-Signature. Rechaza si falta o malformado.
  3. Recomputa HMAC sobre <timestamp>.<body> con el secret.
  4. Compara con igualdad constant-time. Rechaza ante mismatch.
  5. Valida el schema del body (ver Schema).
  6. Envía al bróker.

Errores comunes

  • Firmar el body sin el prefijo de timestamp.
  • Usar == en lugar de comparación constant-time en tu propio servidor (riesgo de timing attack; no es problema de Spectra pero vale la pena hacerlo bien si proxeas nuestro webhook).
  • Enviar JSON con whitespace distinto al firmado — firma siempre los bytes exactos que vas a hacer POST.