1. Callback Events
  2. SKU Inventory Change Event

The SKU Inventory Change event is sent to your registered webhook endpoint whenever inventory levels change for any SKU. This provides real-time visibility into inventory movements across all locations and statuses.

Use the message_id field to implement idempotent processing and prevent duplicate event handling.

​
Event Payload

{
  "callback_url": "https://client.com/api/skuInventoryChange",
  "message_type": "skuInventoryChange",
  "message_id": "e58769ec-c4cf-47f9-b80a-378a9b85aeae",
  "data": [
    {
      "sku_id": "e5d00ff6-b34a-496e-9559-eb90e99463af",
      "customer_identifier": "10000",
      "total_units": 200,
      "total_available_to_sell": 100,
      "as_of": "2018-11-18T00:43:23.095637Z",
      "status_counts": [
        {
          "inventory_location_id": "bf7bb516-ce52-8950-2a8b-9008f0091d93",
          "inventory_location_address": "MasonHub - Rancho Cucamonga | 8595 Milliken Avenue, B102 Rancho Cucamonga, CA 91730",
          "inventory_status": "available",
          "quantity": 100,
          "as_of": "2018-11-18T00:43:22.664965Z"
        }
      ]
    }
  ]
}

​
Payload Fields

callback_url
string

Your registered webhook endpoint URL

message_type
string

Always skuInventoryChange for this event type

message_id
string

Unique identifier for this event. Use for idempotency checks.

data
array

Array of inventory change records. Each record contains:

​
Event Triggers

This event is triggered by various inventory operations:

​
Implementation Example

Python
@app.route('/api/skuInventoryChange', methods=['POST'])
def handle_inventory_change():
    try:
        payload = request.get_json()
        message_id = payload['message_id']

        # Check if already processed (idempotency)
        if is_message_processed(message_id):
            return 'OK', 200

        # Process each SKU update
        for item in payload['data']:
            sku_id = item['customer_identifier']
            available = item['total_available_to_sell']

            # Update your inventory system
            update_inventory(sku_id, available)

            # Update by location if needed
            for status in item['status_counts']:
                location = status['inventory_location_id']
                quantity = status['quantity']
                status_type = status['inventory_status']

                update_inventory_detail(sku_id, location, status_type, quantity)

        # Mark as processed
        mark_message_processed(message_id)

        return 'OK', 200

    except Exception as e:
        logger.error(f"Inventory webhook error: {e}")
        return 'Error', 500
JavaScript
app.post('/api/skuInventoryChange', async (req, res) => {
  try {
    const payload = req.body;
    const messageId = payload.message_id;

    // Check if already processed (idempotency)
    if (await isMessageProcessed(messageId)) {
      return res.status(200).send('OK');
    }

    // Process each SKU update
    for (const item of payload.data) {
      const skuId = item.customer_identifier;
      const available = item.total_available_to_sell;

      // Update your inventory system
      await updateInventory(skuId, available);

      // Update by location if needed
      for (const status of item.status_counts) {
        await updateInventoryDetail(
          skuId,
          status.inventory_location_id,
          status.inventory_status,
          status.quantity
        );
      }
    }

    // Mark as processed
    await markMessageProcessed(messageId);

    res.status(200).send('OK');

  } catch (error) {
    console.error('Inventory webhook error:', error);
    res.status(500).send('Error');
  }
});

​
Best Practices

High-velocity SKUs may generate frequent events. Implement efficient processing and consider batching database updates.

​
Response Requirements

Your webhook endpoint must:

  1. Respond within 30 seconds - Return HTTP 200 to acknowledge receipt
  2. Use proper status codes:
    • 200 - Event processed successfully
    • 500 - Processing error (MasonHub will retry)
  3. Handle retries - MasonHub will retry failed webhooks with exponential backoff
  4. Validate payload - Verify the payload structure before processing