Developer platform

Webhooks

Signed event delivery to your HTTPS endpoint.

Register up to 5 webhooks per wallet for any of the event types, optionally filtered to one squad. The signing secret (whsec_…) is shown once at creation and on rotation.

Delivery

BodyJSON
{ "id": "<event id>", "type": "order.filled", "created_at": "…", "squad_id": "…", "data": { … } }

Headers: Wisp-Event-Id, Wisp-Delivery-Id, Wisp-Timestamp and Wisp-Signature: t=<unix>,v1=<hex>, where the hex is HMAC-SHA256 of ${t}.${rawBody} with your secret. data matches the event payload from /events.

  • At-least-once; order is not guaranteed. Dedupe on Wisp-Event-Id.
  • Success is any 2xx within 10 seconds. Redirects are not followed; at most 1 KB of your response is stored.
  • Retries after 1m, 5m, 30m, 2h and 6h (6 attempts). Implemented, not load-tested.
  • A webhook is disabled after 10 consecutive deliveries that failed every attempt; the reason is shown on the Developers page.
  • Reject a Wisp-Timestamp more than 5 minutes from your clock. The server doesn't enforce this; your receiver does.

Verify a signature

import crypto from "node:crypto";

// rawBody: the exact request body string. header: the Wisp-Signature value.
export function verifyWisp(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const got = Buffer.from(parts.v1 ?? "", "hex");
  const want = Buffer.from(expected, "hex");
  return got.length === want.length && crypto.timingSafeEqual(got, want);
}

URL rules

HTTPS only. The hostname is resolved and private, loopback and link-local addresses are rejected, including 169.254.169.254 and IPv6 equivalents.

Last updated October 11, 2026

Wisp runs in a sandbox today: paper trading on live market data. Experimental software, not financial advice.

Follow @wispcapital on X