Docs/Integrations/Webhook Reference

Integrations

Webhook Reference

All event types, headers, payload formats, and how token auth works.

Endpoint

text
POST /api/webhooks/inbound/{tenant_id}

# Example:
POST http://localhost:8000/api/webhooks/inbound/acme-retail

Required headers

HeaderValueRequired
Content-Typeapplication/jsonYes
X-Webhook-TokenYour tenant's HMAC tokenYes (in production)
X-Sourcesap | oracle | dynamics | netsuite | n8n | genericRecommended
ℹIn development (when WEBHOOK_SECRET_KEY=change-me-in-production), the token check is skipped. Set a real secret in production.

Payload format

json
{
  "event_type": "purchase_order_created",
  "source":     "sap",
  "tenant_id":  "acme-retail",
  "data": {
    "purchase_order_id": "PO-4901",
    "supplier_name":     "Supplier Alpha",
    "quantity":          500,
    "currency":          "GBP",
    "status":            "pending_approval",
    "created_date":      "2026-06-01"
  }
}

EasyFlow normalises common ERP field aliases automatically. SAP's PurchaseOrder becomes purchase_order_id. Oracle's PONumber becomes purchase_order_id. You don't need to rename fields in n8n for supported source types.

Token authentication

Each tenant's token is an HMAC-SHA256 hash of the tenant ID signed with the platform's webhook secret key. To get your token:

bash
# Get your webhook token from the API
curl http://localhost:8000/api/webhooks/token/your-tenant-id

# Response:
# {
#   "tenant_id": "your-tenant-id",
#   "token": "abc123...",
#   "endpoint": "/api/webhooks/inbound/your-tenant-id",
#   "n8n_header": "X-Webhook-Token"
# }

# Or find it in the EasyFlow Integrations page (lightning bolt in sidebar)

All event types

Event typeCategoryTypical trigger
purchase_order_createdProcurementNew PO raised in ERP
purchase_order_approvedProcurementPO approved in ERP or by manager
purchase_order_rejectedProcurementPO rejected
purchase_order_receivedProcurementGoods receipt confirmed
stock_updatedInventoryAny stock level change
stock_low_alertInventoryStock below reorder point
stock_replenishment_neededInventoryCalculated need for restock
shipment_dispatchedLogisticsShipment leaves warehouse
shipment_deliveredLogisticsDelivery confirmed
shipment_delayedLogisticsExpected delivery date missed
supplier_confirmedSuppliersSupplier accepts PO
supplier_rejectedSuppliersSupplier rejects or modifies PO
supplier_sla_breachSuppliersFill rate or lead time SLA missed
workflow_triggerGeneralCustom trigger from any system
custom_eventGeneralFallback for unknown event types

Response codes

CodeMeaning
202 AcceptedEvent received, queued for processing
400 Bad RequestInvalid JSON or missing required fields
401 UnauthorizedInvalid or missing X-Webhook-Token
404 Not FoundTenant ID not found
503 Service UnavailableEvent accepted but could not be queued (RabbitMQ down)