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 Type | Source |
|---|---|
| order.created | Fulfillment |
| order.shipped | Fulfillment |
| sale.recorded | Rewards |
| document.signed | Sign |
| ticket.created | Support |
| stock.low | Inventory |
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:
| Attempt | Delay | Total Elapsed |
|---|---|---|
| 1 (initial) | Immediate | 0s |
| 2 | 30 seconds | 30s |
| 3 | 2 minutes | ~2.5 min |
| 4 | 15 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.