Tutorial

Webhooks for License Events: Real-Time Integration Guide

TOT
Traffic Orchestrator Team
Engineering
March 15, 2026 11 min read 657 words
Share

Webhooks turn your licensing system from passive to proactive. Instead of customers polling your API to check license status, you push events to their systems in real time. License activated? Webhook. Payment failed? Webhook. License about to expire? Webhook.

Which Events to Send

Not every internal state change needs a webhook. Focus on events that trigger actions in your customer's systems:

EventWhenCustomer Action
license.createdNew license provisionedConfigure application, enable features
license.activatedLicense activated on a domainLog activation, update internal records
license.expiring7 days before expirationShow renewal prompt to end user
license.expiredLicense expiresDisable premium features
license.renewedPayment processed, license extendedRe-enable features
license.revokedLicense manually or auto-revokedDisable all features immediately
license.upgradedPlan tier changedEnable new features, adjust limits
domain.addedNew domain authorizedUpdate domain whitelist
domain.removedDomain de-authorizedRevoke access for that domain
payment.failedSubscription payment failsShow payment update prompt

Webhook Payload Structure

Use a consistent payload structure across all events. Include enough context for the customer to process the event without making additional API calls.

{
  "id": "evt_a1b2c3d4e5f6",
  "type": "license.activated",
  "created": "2026-03-15T14:30:00Z",
  "data": {
    "licenseKey": "TO-****-****-****-F6A8",
    "plan": "professional",
    "domain": "app.customer.com",
    "activationsUsed": 3,
    "activationLimit": 10,
    "expiresAt": "2027-03-15T00:00:00Z",
    "features": ["analytics", "api-access", "custom-domains"]
  }
}

Delivery: Reliability Matters

At-Least-Once Delivery

Webhooks can fail — the customer's server might be down, overloaded, or misconfigured. Implement retry logic to ensure events are delivered:

  1. Attempt 1 — Immediate
  2. Attempt 2 — 1 minute later
  3. Attempt 3 — 5 minutes later
  4. Attempt 4 — 30 minutes later
  5. Attempt 5 — 2 hours later
  6. Attempt 6 — 24 hours later (final)

After all retries fail, disable the webhook endpoint and notify the customer via email.

Idempotency

Because you retry, customers may receive the same event multiple times. Include a unique event ID so customers can deduplicate:

// Customer's webhook handler — idempotent processing
app.post('/webhooks/traffic-orchestrator', async (req, res) => {
  const eventId = req.body.id
  
  // Check if already processed
  if (await db.webhookEvents.findOne({ eventId })) {
    return res.status(200).json({ received: true }) // Already processed
  }
  
  // Process the event
  await handleLicenseEvent(req.body)
  
  // Mark as processed
  await db.webhookEvents.insert({ eventId, processedAt: new Date() })
  
  res.status(200).json({ received: true })
})

Security: Don't Trust, Verify

HMAC Signatures

Sign every webhook payload with a shared secret using HMAC-SHA256. The customer verifies the signature to ensure the event came from your system, not an attacker.

// Your system: sign the payload
const crypto = require('crypto')
const signature = crypto
  .createHmac('sha256', webhookSecret)
  .update(JSON.stringify(payload))
  .digest('hex')

// Send with signature header
headers['X-Signature-SHA256'] = signature

// Customer's system: verify the signature
const expectedSignature = crypto
  .createHmac('sha256', process.env.WEBHOOK_SECRET)
  .update(rawBody)
  .digest('hex')

if (signature !== expectedSignature) {
  return res.status(401).json({ error: 'Invalid signature' })
}

Timestamp Verification

Include a timestamp in the signed payload and reject events older than 5 minutes. This prevents replay attacks where an attacker captures a valid webhook and replays it later.

IP Allowlisting

Publish the IP addresses your webhooks originate from. Customers can allowlist these IPs in their firewalls for defense in depth.

Customer Dashboard

Give customers a webhook management interface:

  • Endpoint configuration — Set the URL, select which events to receive
  • Secret management — View and rotate the signing secret
  • Event log — See recent deliveries with status, response code, and payload
  • Test button — Send a test event to verify their endpoint works
  • Retry control — Manually retry failed deliveries

Performance Considerations

  • Async delivery — Never block your main API on webhook delivery. Use a queue.
  • Timeout — Set a 5-second timeout for customer endpoints. If they don't respond, mark it as failed and retry.
  • Circuit breaker — If a customer's endpoint fails 10 times in a row, disable it and notify them.
  • Rate limiting — Don't overwhelm customers with events. Batch rapid-fire events (e.g., bulk imports).

Getting Started

Traffic Orchestrator includes webhook support out of the box. Configure your endpoint in the portal, select your events, and start receiving real-time license updates. HMAC signing, retry logic, and event logging are all built in.

TOT
Traffic Orchestrator Team
Engineering

The engineering team behind Traffic Orchestrator, building enterprise-grade software licensing infrastructure used by developers worldwide.

Was this article helpful?
Get licensing insights delivered

Engineering deep-dives, security advisories, and product updates. Unsubscribe anytime.

Share this article
Free Plan Available

Ship licensing in your next release

5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.

2-minute setup No credit card Cancel anytime