Webhooks

Receive real-time notifications when important events happen in your gateway. Webhooks are delivered via HTTP POST with HMAC-signed payloads and durable retry logic.

Supported Events

quota.warning

Triggered when a user reaches 90% of their monthly request quota. Includes current usage and limit.

quota.exceeded

Triggered when the monthly quota is fully consumed. Requests will be rejected until the next billing cycle.

circuit.open

Triggered when a circuit breaker opens due to backend failures. Includes route ID and failure count.

circuit.closed

Triggered when a circuit breaker recovers and closes. Includes route ID and recovery time.

api_key.created

Triggered when a new API key is created. Includes key metadata (never the key itself).

api_key.revoked

Triggered when an API key is revoked due to abuse or manual action.

Payload Format

All webhook payloads follow this structure:

{
  "event": "quota.warning",
  "userId": 42,
  "data": {
    "currentUsage": 90000,
    "limit": 100000,
    "percentage": 90
  },
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Security

  • HMAC Signature — Every webhook includes an X-Nolxy-Signature header containing an HMAC-SHA256 signature of the payload, signed with your webhook secret.
  • SSRF Protection — Webhook URLs are validated against internal IP ranges, metadata endpoints, and localhost to prevent SSRF attacks.
  • Secret Generation — A unique cryptographic secret is generated for each webhook endpoint. Use it to verify payload authenticity.

Delivery & Retry

Webhooks are processed by a dedicated BullMQ worker with durable delivery:

  • 3 retry attempts with exponential backoff (5s, 10s, 20s)
  • Last 100 completed deliveries are retained for debugging
  • Last 1,000 failed deliveries are retained for investigation
  • Delivery status is visible in the dashboard under Webhook Deliveries

Verification Example

Verify the webhook signature in your handler:

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Plan Requirements

Webhooks are available on Starter plans and above.