Notification webhooks

Stratum can POST your funding-automation events to an HTTPS endpoint you control. The webhook is a notification channel: you enable it for the event types you care about, and Stratum delivers each one as a JSON request you can route into your own tooling, alerts, or dashboards. This is a complement to the in-app and email notifications — not a replacement for the security model around your scoped Bitfinex API key.

1. Enable the webhook channel

Notification delivery is configured per event type and per channel. To start receiving webhooks, send a preference upsert to PUT /api/v1/settings/notifications with the body:

  • type — the event type you want delivered (see the list below).
  • channelWEBHOOK.
  • enabledtrue.
  • webhookUrl — your HTTPS endpoint (maximum 2048 characters).

To see what you currently have configured, GET /api/v1/settings/notifications lists your explicit preferences, and GET /api/v1/settings/notifications/effective returns the merged defaults-plus-overrides view the settings screen renders from — including your webhookUrl and a hasWebhookSecret flag.

2. Endpoint requirements

Your URL must use https. Stratum validates the URL both when you save it and again at delivery time, and rejects endpoints that point at localhost or internal/private network addresses. Redirects are not followed — the request goes to the exact URL you configured. Your endpoint should respond with a 2xx status; any other response is treated as a delivery failure and retried.

3. Event types you can route

The following event types can be delivered to a webhook:

  • RATE_SPIKE, RATE_DROP, RATE_FLOOR_BLOCKED
  • LOAN_EXECUTED, LOAN_EXPIRING, LOAN_EARLY_REPAID, LARGE_EARLY_REPAYMENT, LARGE_LOAN_FILLED
  • STALE_OFFER
  • KILL_SWITCH_ACTIVATED, STRATEGY_PAUSED, STRATEGY_ERROR, STRATEGY_TICK_STALE
  • API_KEY_INVALID, API_KEY_PERMISSIONS_CHANGED
  • PLATFORM_OUTAGE, PLATFORM_RECOVERED, SYSTEM_ALERT
  • LOW_UTILIZATION, IDLE_CASH, FEE_TIER_CHANGED
  • DAILY_DIGEST, WEEKLY_DIGEST, MONTHLY_DIGEST, YEARLY_DIGEST

A few event types are not toggled per channel in settings — HIGH_UTILIZATION, OFFER_FILLED, EARNINGS_MILESTONE, and WITHDRAWAL_DETECTED are managed for you and aren't exposed for webhook opt-in. The periodic digests (DAILY_DIGEST through YEARLY_DIGEST) default to email; enable the webhook channel explicitly if you want them delivered there too.

4. Payload schema

Each delivery is a single JSON object sent with Content-Type: application/json:

  • type — the event type name, e.g. LOAN_EXECUTED.
  • severity — one of INFO, WARNING, or ERROR.
  • title — a short human-readable title.
  • body — a human-readable message.
  • createdAt — an ISO-8601 instant.
  • payload — an object of type-specific fields; it may be empty.
  • userId — your numeric user id.

For example (field values are illustrative only):

  • {"type":"LOAN_EXECUTED","severity":"INFO","title":"Loan executed","body":"A funding offer was filled.","createdAt":"2026-05-31T12:00:00Z","payload":{},"userId":1}

5. Headers

Every request carries:

  • X-Stratum-Type — the event type name (the same value as the body's type).
  • User-AgentStratum/<version> (+https://stratum.money).

When you have a signing secret, each request also includes X-Stratum-Timestamp and X-Stratum-Signature (see signature verification below).

6. Delivery and retries

Stratum waits up to 5 seconds for your endpoint to respond. If a delivery fails — a non-2xx response, a timeout, or a connection error — it is retried with exponential backoff. There are up to 6 delivery attempts in total, with delays of 1 minute, 5 minutes, 15 minutes, 1 hour, and 4 hours between the successive attempts. A scheduler picks up due retries roughly every 60 seconds. Design your endpoint to be idempotent so a retried delivery of the same event is harmless.

7. Signing secret

Webhook preferences are stored per event type, and each one carries its own signing secret. The first time you enable the webhook channel for a given event type, Stratum generates that secret and returns it exactly once — in the response to that upsert request. Save it immediately. After that, the list and effective endpoints only report that a secret exists for that preference (hasWebhookSecret: true); they never return the value again, and there is no way to retrieve it later. Later upserts to the same event type reuse the existing secret rather than generating a new one.

8. Verify the signature

Use the signing secret to confirm a delivery genuinely came from Stratum and wasn't tampered with or replayed. For each signed request:

  • Read X-Stratum-Timestamp (Unix seconds) and X-Stratum-Signature (formatted v1=<hex>).
  • Build the signed string by joining the timestamp and the raw request body with a period: <timestamp>.<raw body>.
  • Compute HMAC-SHA256 over that string using your secret as the key, and hex-encode the result.
  • Compare your hex digest to the value after v1= using a constant-time comparison. Reject the request if it doesn't match.
  • Reject requests whose timestamp is too old for your tolerance to guard against replays.

Compute the HMAC over the exact bytes you received, before any JSON re-serialization.

Related

See the API key quickstart, the security overview, the strategy catalog, and the APR calculator for more on how Stratum automates Bitfinex margin funding.