Webhooks

Receive real-time notifications when events happen in your account.

How Webhooks Work
  1. Register a webhook endpoint URL in your Portal or via the API
  2. Select the events you want to receive
  3. We send an HTTP POST request to your URL when events occur
  4. Your server validates the signature and processes the event
  5. Return a 2xx status code to acknowledge receipt
Retry Policy
Failed deliveries are retried up to 5 times with exponential backoff (5min, 30min, 2hr, 12hr, 24hr)
Timeout
Your endpoint must respond within 30 seconds or the delivery will be marked as failed
Ordering
Events are sent in order, but your handler should be idempotent in case of retries

Webhook Payload

All webhook payloads follow a consistent structure:

{
  "id": "evt_abc123def456",
  "type": "order.created",
  "timestamp": "2026-04-18T14:30:00Z",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "orderNumber": "ORD-1713456789-ABCD12",
    "status": "PENDING",
    "totalAmount": 1520.00,
    "currency": "USD",
    "items": [
      {
        "productId": "prod_123",
        "productName": "Premium CBD Oil",
        "quantity": 5,
        "unitPrice": 99.99
      }
    ],
    "shippingAddress": {
      "firstName": "John",
      "lastName": "Smith",
      "city": "Austin",
      "state": "TX",
      "country": "US"
    },
    "createdAt": "2026-04-18T14:30:00Z"
  },
  "tenant": {
    "id": "ten_abc123",
    "name": "Acme Wellness"
  }
}
FieldTypeDescription
idstringUnique event identifier
typestringEvent type (e.g., order.created)
timestampdatetimeWhen the event occurred (ISO 8601)
dataobjectEvent-specific payload data
tenantobjectTenant information (id and name)

Signature Verification

All webhook payloads are signed using HMAC-SHA256. Always verify signatures to ensure requests are from Regen Therapy.

Signature Header

The signature is sent in the X-Regen-Signature header:

t=1713451800,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
  • t = Unix timestamp when the signature was generated
  • v1 = HMAC-SHA256 signature
import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const timestamp = signature.split(',')[0].split('=')[1];
  const receivedSig = signature.split(',')[1].split('=')[1];
  
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');
  
  // Timing-safe comparison
  return crypto.timingSafeEqual(
    Buffer.from(receivedSig),
    Buffer.from(expectedSig)
  );
}

// Express.js example
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-regen-signature'];
  const payload = req.body.toString();
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(payload);
  
  switch (event.type) {
    case 'order.created':
      handleOrderCreated(event.data);
      break;
    case 'order.shipped':
      handleOrderShipped(event.data);
      break;
    // ... handle other events
  }
  
  res.status(200).send('OK');
});

Events Catalog

Complete list of webhook events you can subscribe to:

Orders Events
EventDescription
order.createdA new order has been placed
order.updatedAn order has been modified
order.confirmedOrder has been confirmed (payment received)
order.processingOrder is being prepared for shipment
order.shippedOrder has been shipped
order.deliveredOrder has been delivered
order.cancelledOrder has been cancelled
order.refundedOrder has been refunded
Inventory Events
EventDescription
inventory.adjustedInventory quantity was manually adjusted
inventory.low_stockProduct fell below reorder point
inventory.out_of_stockProduct is out of stock
inventory.restockedProduct was restocked
Commissions Events
EventDescription
commission.accruedCommission was earned on an order
commission.adjustedCommission amount was adjusted
commission.payout.scheduledPayout has been scheduled
commission.payout.completedPayout has been sent
commission.payout.failedPayout failed to process
Shipping Events
EventDescription
shipment.createdShipment has been created
shipment.picked_upShipment was picked up by carrier
shipment.in_transitShipment is in transit
shipment.deliveredShipment was delivered
shipment.exceptionDelivery exception occurred
Returns Events
EventDescription
return.requestedReturn has been requested
return.approvedReturn has been approved
return.receivedReturned items received
return.completedReturn has been completed
Tenant Events
EventDescription
tenant.createdNew tenant account created
tenant.activatedTenant account activated
tenant.suspendedTenant account suspended
tenant.updatedTenant settings updated
Best Practices

Return 200 Quickly

Acknowledge receipt immediately and process events asynchronously. Use a queue for heavy processing.

Handle Duplicates

Use the event ID to detect and handle duplicate deliveries. Your handlers should be idempotent.

Use HTTPS

Always use HTTPS endpoints. We do not send webhooks to HTTP URLs.

Monitor Failures

Set up monitoring for webhook failures. Check the delivery logs in your portal regularly.