- Callback Events
- Inbound Shipment Events
Callback Events
Inbound Shipment Events
Webhook event sent when inbound shipment status changes during the receiving process
Inbound Shipment Events provide real-time updates as your inventory shipments arrive and are received at MasonHub distribution centers. Track the receiving process from dock arrival through final inventory putaway.
Inventory becomes available for sale only after receiving is complete and items are processed through quality control.
​Event Payload
{
"callback_url": "https://client.com/api/inboundShipmentEvent",
"message_type": "inboundShipmentEvent",
"message_id": "0896116f-e54b-4756-9d3e-1b0c4a25d821",
"data": [
{
"id": "33455ccc-40f5-431b-81a1-44098f8a92bd",
"customer_identifier": "shipment32432",
"status": "receivingComplete",
"as_of": "2018-12-11T15:53:23Z",
"details": {
"inventory_location_address": "MasonHub Rancho | 1 Mason Way Rancho Cucomunga, CA 97130",
"arrived_at": "2018-12-11T09:15:00Z",
"started_receiving_at": "2018-12-11T11:01:24Z",
"finished_receiving_at": "2018-12-11T15:53:23Z",
"line_items": [
{
"customer_sku_id": "shirt-534212",
"quantity": 100,
"total_quantity_received": 90,
"not_on_original_shipment": false
}
]
}
}
]
}
​Payload Fields
Your registered webhook endpoint URL
Always inboundShipmentEvent for this event type
Unique identifier for this event. Use for idempotency checks.
Array of shipment status updates. Each record contains:
​Shipment Status Values
onDock
Shipment arrived at facility dock - awaiting processing
receivingStarted
Receiving process has begun - items being counted and inspected
receivingComplete
All items processed and added to inventory
​Receiving Discrepancies
The total_quantity_received may differ from the expected quantity due to:
Shortages
Fewer items received than expected - investigate with carrier
Overages
More items received than expected - verify with supplier
Damages
Items damaged in transit - may be rejected or marked damaged
Unexpected Items
Items not on ASN (not_on_original_shipment: true)
​Example Scenarios
​Complete Receipt - All Items Received
{
"status": "receivingComplete",
"details": {
"line_items": [
{
"customer_sku_id": "shirt-534212",
"quantity": 100,
"total_quantity_received": 100,
"not_on_original_shipment": false
}
]
}
}
​Partial Receipt - Shortage
{
"status": "receivingComplete",
"details": {
"line_items": [
{
"customer_sku_id": "shirt-534212",
"quantity": 100,
"total_quantity_received": 90,
"not_on_original_shipment": false
}
]
}
}
​Unexpected Item Received
{
"status": "receivingComplete",
"details": {
"line_items": [
{
"customer_sku_id": "shirt-534212",
"quantity": 100,
"total_quantity_received": 100,
"not_on_original_shipment": false
},
{
"customer_sku_id": "pants-9876",
"quantity": 0,
"total_quantity_received": 25,
"not_on_original_shipment": true
}
]
}
}
​Implementation Example
@app.route('/api/inboundShipmentEvent', methods=['POST'])
def handle_inbound_shipment_event():
try:
payload = request.get_json()
message_id = payload['message_id']
# Check if already processed
if is_message_processed(message_id):
return 'OK', 200
# Process each shipment update
for shipment in payload['data']:
shipment_id = shipment['customer_identifier']
status = shipment['status']
details = shipment.get('details', {})
# Update shipment status
update_shipment_status(shipment_id, status)
if status == 'onDock':
logger.info(f"Shipment {shipment_id} arrived at dock")
notify_ops_team_shipment_arrived(shipment_id)
elif status == 'receivingStarted':
started_at = details.get('started_receiving_at')
logger.info(f"Receiving started for {shipment_id}")
elif status == 'receivingComplete':
# Process line items
line_items = details.get('line_items', [])
for item in line_items:
sku = item['customer_sku_id']
expected = item['quantity']
received = item['total_quantity_received']
unexpected = item['not_on_original_shipment']
# Update inventory records
update_inventory_received(sku, received)
# Check for discrepancies
if received < expected:
shortage = expected - received
log_shortage(shipment_id, sku, shortage)
alert_ops_team_shortage(shipment_id, sku, shortage)
elif received > expected:
overage = received - expected
log_overage(shipment_id, sku, overage)
if unexpected:
log_unexpected_item(shipment_id, sku, received)
notify_supplier_unexpected_item(shipment_id, sku)
logger.info(f"Receiving complete for {shipment_id}")
mark_message_processed(message_id)
return 'OK', 200
except Exception as e:
logger.error(f"Inbound shipment webhook error: {e}")
return 'Error', 500
app.post('/api/inboundShipmentEvent', async (req, res) => {
try {
const payload = req.body;
const messageId = payload.message_id;
// Check if already processed
if (await isMessageProcessed(messageId)) {
return res.status(200).send('OK');
}
// Process each shipment update
for (const shipment of payload.data) {
const shipmentId = shipment.customer_identifier;
const status = shipment.status;
const details = shipment.details || {};
// Update shipment status
await updateShipmentStatus(shipmentId, status);
if (status === 'onDock') {
console.log(`Shipment ${shipmentId} arrived at dock`);
await notifyOpsTeamShipmentArrived(shipmentId);
} else if (status === 'receivingStarted') {
console.log(`Receiving started for ${shipmentId}`);
} else if (status === 'receivingComplete') {
// Process line items
const lineItems = details.line_items || [];
for (const item of lineItems) {
const sku = item.customer_sku_id;
const expected = item.quantity;
const received = item.total_quantity_received;
// Update inventory
await updateInventoryReceived(sku, received);
// Check for discrepancies
if (received < expected) {
const shortage = expected - received;
await logShortage(shipmentId, sku, shortage);
await alertOpsTeamShortage(shipmentId, sku, shortage);
} else if (received > expected) {
const overage = received - expected;
await logOverage(shipmentId, sku, overage);
}
if (item.not_on_original_shipment) {
await logUnexpectedItem(shipmentId, sku, received);
await notifySupplierUnexpectedItem(shipmentId, sku);
}
}
console.log(`Receiving complete for ${shipmentId}`);
}
}
await markMessageProcessed(messageId);
res.status(200).send('OK');
} catch (error) {
console.error('Inbound shipment webhook error:', error);
res.status(500).send('Error');
}
});
​Use Cases
Inventory Tracking
Monitor receiving progress and update inventory forecasts
Discrepancy Management
Identify and resolve shortages, overages, and damages
Supply Chain Visibility
Track shipment timelines from arrival to inventory availability
Supplier Performance
Monitor supplier accuracy and shipment quality
​Best Practices
Monitor Discrepancies
Track shortages and overages to identify patterns
Alert Operations
Notify teams immediately when issues are detected
Update Forecasts
Adjust inventory availability based on actual receipts
Document Issues
Log all discrepancies for carrier claims and supplier resolution
​Response Requirements
Your webhook endpoint must:
- Respond within 30 seconds - Return HTTP 200 to acknowledge receipt
- Handle all statuses - Support onDock, receivingStarted, receivingComplete
- Process discrepancies - Compare expected vs received quantities
- Update inventory - Reflect actual received quantities in your system
​Related Events
- SKU Inventory Change Event - Triggered when received inventory is added to available stock
- Snapshot Ready - Full inventory reconciliation after receiving