Skip to main content

Events Module

Enable real-time communication between modules and external systems with event publishing and webhooks.

Overview

The Events module provides a cross-module event bus:

  • Publish events from any module
  • Subscribe to event types
  • Webhook delivery to external URLs
  • Event history and replay
  • Delivery tracking and retry

Key Features

Event Publishing

Any module can publish events to the bus:

  • Typed Events - Structured event payloads per module
  • Event History - Full audit trail of all events
  • Event Replay - Re-deliver past events for recovery
  • Delivery Tracking - Monitor webhook delivery status with automatic retries

Webhook Subscriptions

Subscribe external systems to PROIGN events:

  • HMAC-signed payloads for security
  • Configurable event type filtering
  • Automatic retry with exponential backoff
  • Delivery logs and failure alerts

Event Types

Common event types across modules:

Event TypeSource
order.createdFulfillment
order.shippedFulfillment
sale.recordedRewards
document.signedSign
ticket.createdSupport
stock.lowInventory

Subscriptions

Create subscriptions to receive events:

{
  "event_type": "order.shipped",
  "target_module": "external",
  "webhook_url": "https://your-app.com/webhooks/proign",
  "secret": "your-webhook-secret",
  "filter": {
    "shipping_method": "express"
  }
}

Webhook Delivery

Events are delivered with:

  • HMAC signature in header for verification
  • Automatic retry on failure (up to 5 attempts)
  • Exponential backoff
  • Delivery status tracking

Signature Verification

// Verify webhook signature
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return signature === `sha256=${expected}`;
}

API Endpoints

Base URL: https://app.proign.com/[tenant]/events/api

Events

GET    /api/[tenant]/events                 # List events with filters
POST   /api/[tenant]/events                 # Publish event (authenticated)

Subscriptions

GET    /api/[tenant]/subscriptions          # List subscriptions
POST   /api/[tenant]/subscriptions          # Create subscription (admin)

Public (Module-to-Module)

POST   /api/p/[tenant]/events               # Publish event (rate-limited, no auth)

The public endpoint is used for internal module-to-module communication. It is rate-limited and does not require JWT authentication, making it suitable for server-to-server calls.

Request Examples

Publish Event

POST /api/[tenant]/events
Content-Type: application/json
Authorization: Bearer <jwt>

{
  "type": "order.shipped",
  "source": "fulfillment",
  "data": {
    "order_id": "ord_abc123",
    "tracking_number": "1Z999AA10123456784",
    "carrier": "ups",
    "shipped_at": "2026-02-21T10:30:00Z"
  }
}

// Response (201 Created)
{
  "data": {
    "id": "evt_xyz789",
    "type": "order.shipped",
    "source": "fulfillment",
    "created_at": "2026-02-21T10:30:01Z",
    "deliveries": 2
  }
}

Create Subscription

POST /api/[tenant]/subscriptions
Content-Type: application/json
Authorization: Bearer <admin-jwt>

{
  "event_types": ["order.shipped", "order.delivered"],
  "target": "webhook",
  "webhook_url": "https://your-app.com/webhooks/proign",
  "secret": "whsec_your_signing_secret",
  "active": true
}

// Response (201 Created)
{
  "data": {
    "id": "sub_def456",
    "event_types": ["order.shipped", "order.delivered"],
    "webhook_url": "https://your-app.com/webhooks/proign",
    "active": true,
    "created_at": "2026-02-21T10:00:00Z"
  }
}

Webhook Payload Format

// Your webhook endpoint receives:
POST https://your-app.com/webhooks/proign
Content-Type: application/json
X-Proign-Signature: sha256=a1b2c3d4e5f6...
X-Proign-Event: order.shipped
X-Proign-Delivery-Id: del_ghi789

{
  "id": "evt_xyz789",
  "type": "order.shipped",
  "tenant_id": "acme-corp",
  "source": "fulfillment",
  "created_at": "2026-02-21T10:30:01Z",
  "data": {
    "order_id": "ord_abc123",
    "tracking_number": "1Z999AA10123456784",
    "carrier": "ups",
    "shipped_at": "2026-02-21T10:30:00Z"
  }
}

Retry Policy

Failed webhook deliveries are retried with exponential backoff:

AttemptDelayTotal Elapsed
1 (initial)Immediate0s
230 seconds30s
32 minutes~2.5 min
415 minutes~17.5 min
5 (final)1 hour~1 hr 18 min

A delivery is considered failed if the endpoint returns a non-2xx status code or does not respond within 10 seconds. After all retries are exhausted, the delivery is marked as failed and an alert is logged.

Event Replay

Re-deliver past events for debugging or recovery:

# Replay a single event to all subscribers
POST /api/[tenant]/events/evt_xyz789/replay

# Replay all events of a type within a time range
POST /api/[tenant]/events/replay
{
  "event_type": "order.shipped",
  "from": "2026-02-20T00:00:00Z",
  "to": "2026-02-21T00:00:00Z"
}

Events are retained for 90 days and can be replayed at any time within that window. Replayed events include an X-Proign-Replay: true header so your endpoint can distinguish them from original deliveries.

Related