Skip to content

Webhooks

Receive real-time notifications for marketplace events via HTTP callbacks.

Overview

Webhooks allow your application to receive automatic notifications when events occur in Automatum. Instead of polling the API, webhooks push data to your endpoint as events happen.

How delivery is handled

You create and configure webhook endpoints through Automatum, but the actual delivery of events — signing requests, retrying failures, and applying backoff — is performed by Automatum’s webhook delivery service, a separate downstream component. The behavior described below (the signature scheme, retry policy, and auto-disable thresholds) reflects that delivery service.

How Webhooks Work

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Event      │────▶│  Automatum  │────▶│  Your       │
│  Occurs     │     │  Webhook    │     │  Endpoint   │
└─────────────┘     └─────────────┘     └─────────────┘


                    ┌─────────────┐
                    │  Retry if   │
                    │  Failed     │
                    └─────────────┘
  1. Event occurs in Automatum (e.g., offer accepted)
  2. The webhook delivery service sends an HTTP POST to your endpoint
  3. Your endpoint processes the event
  4. Returns 2xx status to acknowledge receipt
  5. If failed, the delivery service retries with exponential backoff

Setting Up Webhooks

Create Webhook Endpoint

  1. Navigate to Settings > Webhooks
  2. Click Add Webhook
  3. Configure:
    • Endpoint URL: Your HTTPS endpoint
    • Description: Human-readable name
    • Events: Select events to subscribe
    • Secret: Auto-generated signing secret
  4. Click Create Webhook

Endpoint Requirements

Your webhook endpoint must:

  • Accept HTTP POST requests
  • Use HTTPS (SSL/TLS required)
  • Respond promptly (the delivery service enforces a request timeout)
  • Return 2xx status code on success
  • Be publicly accessible

Example Endpoint (Node.js)

javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = process.env.AUTOMATUM_WEBHOOK_SECRET;

app.post('/webhooks/automatum', (req, res) => {
  // Verify signature
  const signature = req.headers['x-automatum-signature'];
  const payload = JSON.stringify(req.body);
  
  const expectedSignature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');
  
  if (signature !== `sha256=${expectedSignature}`) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process event
  const event = req.body;
  console.log('Received event:', event.type);
  
  switch (event.type) {
    case 'entitlement.created':
      handleEntitlementCreated(event.data);
      break;
    case 'entitlement.updated':
      handleEntitlementUpdated(event.data);
      break;
    case 'private_offer.accepted':
      handleOfferAccepted(event.data);
      break;
    case 'metering.failed':
      handleMeteringFailed(event.data);
      break;
    // Handle other events...
  }
  
  // Acknowledge receipt
  res.status(200).json({ received: true });
});

app.listen(3000);

Example Endpoint (Python)

python
from flask import Flask, request, jsonify
import hmac
import hashlib
import os

app = Flask(__name__)
WEBHOOK_SECRET = os.environ['AUTOMATUM_WEBHOOK_SECRET']

def verify_signature(payload, signature):
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f'sha256={expected}', signature)

@app.route('/webhooks/automatum', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Automatum-Signature')
    
    if not verify_signature(request.data, signature):
        return jsonify({'error': 'Invalid signature'}), 401
    
    event = request.json
    print(f"Received event: {event['type']}")
    
    # Process event based on type
    if event['type'] == 'entitlement.created':
        handle_entitlement_created(event['data'])
    elif event['type'] == 'private_offer.accepted':
        handle_offer_accepted(event['data'])
    elif event['type'] == 'metering.failed':
        handle_metering_failed(event['data'])
    
    return jsonify({'received': True}), 200

if __name__ == '__main__':
    app.run(port=3000)

Webhook Events

The type field is a free-form string; the API does not constrain it to a fixed enum. The only event type demonstrably emitted from within this API is webhook.test (sent by the Send Test Event action). The business-event catalog below (entitlement.*, private_offer.*, customer.*, metering.*) is defined and emitted by Automatum’s webhook delivery service, so treat these names as the delivery service’s contract rather than a guarantee from the API itself.

Test Events

EventDescription
webhook.testSent when you use Send Test Event to verify your endpoint

Entitlement Events

EventDescription
entitlement.createdNew entitlement/contract created
entitlement.updatedEntitlement details updated
entitlement.renewedEntitlement was renewed
entitlement.cancelledEntitlement was cancelled

Private Offer Events

EventDescription
private_offer.createdNew private offer created
private_offer.acceptedCustomer accepted offer

Customer Events

EventDescription
customer.createdNew customer registered
customer.updatedCustomer info updated

Metering Events

EventDescription
metering.submittedUsage report submitted
metering.confirmedMarketplace confirmed receipt
metering.failedUsage report failed

Webhook Payload

Payload Structure

json
{
  "id": "evt_1234567890",
  "type": "private_offer.accepted",
  "created": "2026-01-16T10:30:00Z",
  "data": {
    "id": "offer_abc123",
    "customerId": "cust_xyz789",
    "listingId": "listing_456",
    "vendor": "aws",
    "value": 50000,
    "duration": 12,
    "acceptedAt": "2026-01-16T10:30:00Z"
  },
  "organizationId": "org_123"
}

Common Fields

FieldTypeDescription
idstringUnique event identifier
typestringEvent type
createdstringISO 8601 timestamp
dataobjectEvent-specific data
organizationIdstringYour organization ID

Event-Specific Data

entitlement.created:

json
{
  "id": "ent_abc123",
  "customerId": "cust_xyz789",
  "listingId": "listing_456",
  "details": {
    "subscriptionStatus": "subscribed",
    "entries": [
      {
        "name": "enterprise",
        "units": 1,
        "price": ""
      }
    ],
    "expiration": "2027-01-31T00:00:00Z",
    "startDate": "2026-01-16T10:30:00Z"
  }
}

private_offer.accepted:

json
{
  "id": "offer_abc123",
  "listingId": "listing_456",
  "vendorOfferId": "offer-123456",
  "status": "accepted",
  "details": {
    "summary": {
      "offerName": "Enterprise Deal",
      "customerName": "Acme Corporation"
    }
  }
}

metering.failed:

json
{
  "id": "meter_abc123",
  "listingId": "listing_456",
  "customerId": "cust_xyz789",
  "status": "failed",
  "message": "Error message from marketplace",
  "details": {
    "reportingDate": "2026-01-16",
    "usages": []
  }
}

Security

Signature Verification

The webhook delivery service signs every request with an HMAC-SHA256 signature over the payload, using your webhook secret, and sends it in a header:

X-Automatum-Signature: sha256=abc123...

Always verify signatures to ensure requests are from Automatum. Because signing is performed by the delivery service, verify against the secret shown for your webhook in the dashboard.

Verification Code

javascript
const crypto = require('crypto');

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

Security Best Practices

  1. Always verify signatures - Never trust unverified requests
  2. Use HTTPS - Encrypt data in transit
  3. Rotate secrets - Periodically regenerate webhook secrets
  4. Validate data - Check payload structure and types
  5. Idempotency - Handle duplicate deliveries gracefully

Retry Policy

Retries and backoff are handled by Automatum’s webhook delivery service, not by this API. The delivery service is designed for reliable delivery with the following behavior:

  • Automatic retries: Failed deliveries are retried with exponential backoff
  • Request timeout: Each delivery attempt is subject to a request timeout
  • Failure tracking: Consecutive failures are counted per webhook
  • Auto-disable: A webhook is disabled after a number of consecutive failures
  • Manual retry: Disabled webhooks can be re-enabled and retried from the dashboard

Exact timeout, backoff intervals, and failure thresholds are governed by the delivery service and may change; do not rely on specific values.

Managing Webhooks

View Webhook Logs

  1. Go to Settings > Webhooks
  2. Click on webhook endpoint
  3. View Delivery Logs

Log details include:

  • Timestamp
  • Event type
  • Request payload
  • Response status
  • Response body
  • Duration

Test Webhooks

Send test events to verify setup:

  1. Go to Settings > Webhooks
  2. Click on webhook endpoint
  3. Click Send Test Event
  4. Select event type
  5. Review delivery result

Disable/Enable Webhooks

Temporarily disable without deleting:

  1. Go to webhook settings
  2. Toggle Enabled switch
  3. Webhook paused (events not sent)

Delete Webhooks

Remove webhook permanently:

  1. Go to webhook settings
  2. Click Delete Webhook
  3. Confirm deletion

WARNING

Deleting a webhook stops all event delivery immediately. Events during downtime are not recoverable.

Webhook IP Addresses

If you need to whitelist IPs, Automatum webhooks originate from:

52.XX.XX.XX
52.XX.XX.XX
54.XX.XX.XX

TIP

Contact support@automatum.io for current IP ranges.

Best Practices

1. Respond Quickly

Return 200 immediately, process async (must respond within 10 seconds):

javascript
app.post('/webhook', async (req, res) => {
  // Acknowledge immediately
  res.status(200).send('OK');
  
  // Process asynchronously
  processEventAsync(req.body);
});

2. Handle Duplicates

Events may be delivered more than once:

javascript
const processedEvents = new Set();

function handleEvent(event) {
  if (processedEvents.has(event.id)) {
    return; // Already processed
  }
  processedEvents.add(event.id);
  // Process event...
}

3. Use Queues

For reliability, queue events for processing:

javascript
const Queue = require('bull');
const webhookQueue = new Queue('webhooks');

app.post('/webhook', (req, res) => {
  webhookQueue.add(req.body);
  res.status(200).send('OK');
});

webhookQueue.process(async (job) => {
  await processEvent(job.data);
});

4. Log Everything

Maintain detailed logs for debugging:

javascript
function handleWebhook(event) {
  console.log({
    eventId: event.id,
    type: event.type,
    receivedAt: new Date().toISOString(),
    data: event.data
  });
}

5. Monitor Health

Track webhook delivery metrics:

  • Success rate
  • Average response time
  • Error patterns
  • Retry frequency

Troubleshooting

Not Receiving Webhooks

  1. Verify endpoint URL is correct
  2. Check endpoint is publicly accessible
  3. Confirm HTTPS certificate is valid
  4. Review firewall/security rules
  5. Check webhook is enabled

Signature Verification Failing

  1. Verify using correct secret
  2. Check payload encoding (UTF-8)
  3. Ensure no middleware modifies body
  4. Verify signature header name

Timeouts

  1. Respond promptly (the delivery service enforces a request timeout)
  2. Process async after acknowledging
  3. Check endpoint performance
  4. Review server resources

Missing Events

  1. Check event types are subscribed
  2. Review webhook logs
  3. Verify endpoint returned 2xx
  4. Check for filtered events

API Reference

::: note Webhook Management Webhook management endpoints are available through the Automatum dashboard. The webhook API routes are internal and not part of the public OAuth API (/api/v1/*). To manage webhooks, use the dashboard at Settings > Webhooks. :::

Webhook Management via Dashboard

  1. Create Webhook: Navigate to Settings > Webhooks > Add Webhook
  2. List Webhooks: View all webhooks in Settings > Webhooks
  3. Update Webhook: Click on a webhook to edit its configuration
  4. Delete Webhook: Click Delete on the webhook details page
  5. Test Webhook: Click Send Test Event to verify your endpoint

Webhook Configuration

When creating or updating a webhook, you can configure:

  • Name: Human-readable identifier
  • Description: Optional description
  • URL: HTTPS endpoint URL (required)
  • Events: Array of event types to subscribe to (at least one required)
  • Secret: Optional signing secret for signature verification
  • Active Status: Enable/disable webhook delivery

Next Steps

Need Help?

Contact support@automatum.io for webhook assistance.

Automatum GTM Platform