Authentication
Vendor API keys with scoped access and one-time secret display.
Webhook Events
Outbound webhook payload format for operational alerting.
Webhook Reference
Integration contract for outbound operational events from RED: The Order Engine.
Quick Start (60 seconds)
- Expose an HTTPS endpoint that accepts
POST application/json. - Optionally configure a shared bearer token and validate
Authorization: Bearer <token>. - Return
2xximmediately after basic validation. - Queue downstream processing asynchronously.
- These webhooks are asynchronous notifier outputs, not guaranteed immediate transactional callbacks.
- Implement idempotency and dedupe by
event+timestamp+ stable item key where applicable.
Delivery
- Method:
POST - Content-Type:
application/json - Delivery mode: best-effort from scheduled notifier runs.
- No strict ordering guarantee across event types, vendors, or runs.
- Ordering within a single notifier run is also not guaranteed and must not be relied on.
- Duplicate delivery can occur across reruns and threshold/state transitions; receivers must be idempotent.
- Non-
2xxresponses are treated as failures for the run; automatic transport retries are not performed in-process. - Failed deliveries are not retried immediately. A future scheduler/notifier run may emit the same event again if its source condition still qualifies or state dedupe permits re-emission.
- Timeouts and endpoint errors fail the current run; redelivery depends on scheduler rerun cadence.
- Payload batching: one POST per event payload. Inventory notifier emits one payload per non-empty event type.
- Catalog availability notifier emits one payload per vendor when one or more availability rows changed.
- Purchase order status change event emits when external order-response/fulfillment transitions change top-level status.
- Payload size is variable; proactive inventory events are capped to
maxItemsPerEvent(hard max 500 items/event). - Typical payloads are far smaller; with default limits they are usually under ~100KB, but consumers should enforce their own request-size limits.
- Event latency is scheduler-bound and not real-time; expect delay relative to run cadence.
Security
- HTTP is supported for local/test environments only. Use HTTPS in production.
- Optional shared bearer token authentication is supported via
Authorization: Bearer <token>. - Bearer token is configured on the sender side (global alert webhook env vars or per-vendor proactive config).
- Token rotation is supported by updating webhook configuration and redeploying/reloading scheduler inputs.
- Requests are not currently signed with HMAC.
- Because payloads are not signed, bearer-token validation and HTTPS are the primary trust controls for v1.
- Validate token before trusting payload contents.
Common Event Envelope
All webhook payloads include a common envelope. timestamp is event generation time (ISO-8601 UTC), not delivery time.
- Whenever a payload includes both
countanditems,countequalsitems.length. - v1 does not include a top-level event identifier field. Use
event+timestamp+ stable business keys for dedupe/correlation.
{
"source": "string",
"event": "string",
"timestamp": "ISO-8601 UTC"
}Event Catalog
vendor_api_threshold_breach
Triggered when vendor API observability thresholds are breached in the configured window.
- Fires once per alert-check run when at least one breach exists.
- No cross-run dedupe; repeated breaches can emit repeatedly.
- Single event payload per run.
{
"source": "orderengine.vendor-api",
"event": "vendor_api_threshold_breach",
"timestamp": "2026-03-12T03:05:28.827Z",
"windowMinutes": 15,
"thresholds": {
"minRequests": 20,
"maxServerErrorRate": 0.01,
"maxRateLimitedRate": 0.1,
"maxAuthFailureRate": 0.2,
"maxLatencyMs": 10000
},
"totals": {
"requests": 120,
"authFailures": 40,
"rateLimited": 0,
"serverErrors": 5
},
"latency": { "avgMs": 320, "maxMs": 12340 },
"topPaths": [{ "path": "/api/external/v1/purchase-orders", "requests": 70 }],
"topVendors": [{ "vendorId": "vendor_123", "requests": 82 }],
"breaches": [
{
"metric": "auth_failure_rate",
"observed": 0.3333,
"threshold": 0.2,
"message": "Auth failure rate 33.33% exceeds 20.00%"
}
]
}purchase_order_status_changed
Triggered when purchase order status changes due to external vendor response or fulfillment updates.
- Emitted immediately after successful external API mutations that transition top-level order status.
- Uses the same per-vendor webhook destination config as proactive and catalog events.
- No cross-request dedupe; each distinct status transition emits once.
previousStatusandnewStatususe purchase order lifecycle values such assubmitted,acknowledged,scheduled,out_for_delivery,delivered,partially_received,received, andcancelled.reasonis currently one ofvendor_response,fulfillment_update,mark_delivered, ormark_received. Consumers must gracefully handle unknown future values.
{
"source": "orderengine.purchase-orders",
"event": "purchase_order_status_changed",
"timestamp": "2026-03-12T03:05:28.827Z",
"vendorId": "vendor_123",
"vendorName": "Vendor Name",
"orderId": "po_123",
"orderNumber": "PO-00123",
"previousStatus": "submitted",
"newStatus": "acknowledged",
"reason": "vendor_response",
"notes": "Can fulfill on next route day",
"context": {
"receiverName": null,
"receivedAt": null,
"discrepancySummary": null
},
"requestId": "req_123",
"triggeredBy": "vendor-api-key:key_123"
}catalog_availability_changed
Triggered when vendor catalog availability state changes for one or more products.
- Emitted by the catalog availability notifier with per-vendor state-change dedupe.
- One payload is sent per vendor when at least one item fingerprint changes.
- Stable dedupe key per item:
alertKey(vendor product id).
{
"source": "orderengine.vendor-catalog",
"event": "catalog_availability_changed",
"timestamp": "2026-03-12T03:05:28.827Z",
"vendorId": "vendor_123",
"vendorName": "Vendor Name",
"count": 1,
"items": [
{
"alertKey": "vp_123",
"vendorId": "vendor_123",
"vendorName": "Vendor Name",
"vendorProductId": "vp_123",
"productId": "prod_55",
"vendorSku": "VEN-123",
"productSku": "SKU-55",
"productName": "Blue Gummies 10pk",
"isActive": true,
"isAvailableForOrder": true,
"availableUnits": 240,
"availableCases": 24,
"minOrderCaseQty": 1,
"orderMultiple": 1,
"availabilityReason": null
}
]
}Inventory Alert Events
Event names: restock_threshold_reached / out_of_stock_warning / over_stock_warning
- Emitted by the proactive inventory notifier from velocity-derived inventory signals.
- One payload is sent per non-empty event type per vendor per run.
- State-change dedupe is enforced per vendor + event + alertKey + alert fingerprint.
- Event names are stable API contracts and will not change within the v1 webhook contract; keep exact spelling, including
over_stock_warning.
{
"source": "orderengine.vendor-velocity",
"event": "restock_threshold_reached",
"timestamp": "2026-03-12T03:05:28.827Z",
"dateRange": "30d",
"thresholds": {
"restockDaysOfSupply": 6,
"outOfStockUnits": 0,
"overstockDaysOfSupply": 45
},
"count": 2,
"items": [
{
"alertKey": "vendor_123:store_001:prod_55",
"vendorId": "vendor_123",
"vendorName": "Vendor Name",
"storeId": "store_001",
"storeName": "Main Street",
"productId": "prod_55",
"productName": "Blue Gummies 10pk",
"sku": "BG-10",
"status": "Low stock",
"onHand": 8,
"dailyVelocity": 2.4,
"daysOfSupply": 3.3,
"restockSuggestion": 26,
"trendDirection": "down",
"trendPercent": -14.2
}
]
}Payload Schemas
Threshold Breach Event Schema
source: fixed stringorderengine.vendor-apievent: fixed stringvendor_api_threshold_breachtimestamp: ISO-8601 UTC generation time (not delivery time)windowMinutes: integer alert evaluation window sizethresholds: configured threshold object used for evaluationtotals: request/status aggregate totals for the windowlatency: aggregate latency metrics for the windowtopPaths: hottest paths for the window (may be empty)topVendors: top vendor request counts (may be empty)breaches: one or more breach descriptors
Purchase Order Status Change Event Schema
source: fixed stringorderengine.purchase-ordersevent: fixed stringpurchase_order_status_changedtimestamp: ISO-8601 UTC generation time (not delivery time)vendorId/vendorName: vendor context for this payloadorderId/orderNumber: purchase order identifierspreviousStatus/newStatus: lifecycle transition pairreason: transition trigger enum for v1:vendor_response|fulfillment_update|mark_delivered|mark_received. Unknown future values must be handled safely.context: optional trigger-specific details (delivery/receipt evidence)notes,requestId,triggeredBy: optional correlation fields
Catalog Availability Event Schema
source: fixed stringorderengine.vendor-catalogevent: fixed stringcatalog_availability_changedtimestamp: ISO-8601 UTC generation time (not delivery time)vendorId/vendorName: vendor context for this payloadcount: number of changed rows in this payload; equalsitems.lengthitems: changed catalog availability rows
Inventory Alert Event Schema
source: fixed stringorderengine.vendor-velocityevent: one ofrestock_threshold_reached,out_of_stock_warning,over_stock_warningtimestamp: ISO-8601 UTC generation time (not delivery time)dateRange: one of7d | 14d | 30d | 90dthresholds: thresholds applied when deriving alert itemscount: number of items in this payload; expected to equalitems.lengthitems: alert item array; may be empty before notifier filtering, non-empty in sent payloads
Catalog Availability Item Meanings
alertKey: stable dedupe/correlation key (vendor product id)isAvailableForOrder: computed availability gate for orderingavailableUnits/availableCases: current stock signalminOrderCaseQty/orderMultiple: ordering constraintsavailabilityReason:inactive | out_of_stock | null
Inventory Alert Item Meanings
alertKey: stable per vendor/store/product identifier for dedupe correlationstatus: velocity status label from reporting output (human-readable, not versioned enum)onHand: units currently in stockdailyVelocity: projected daily units solddaysOfSupply: projected days until depletion at current velocityrestockSuggestion: suggested units to reorder (units, not cases)trendDirection: one ofup | down | flattrendPercent: trend percentage from reporting output for the selected date range
Receiver Best Practices
- Respond with
2xxquickly after authentication and basic shape checks. - Do not perform heavy processing inline; enqueue and process asynchronously.
- Validate bearer token (if configured) before trusting payload data.
- Design handlers to be idempotent and tolerant of duplicate or delayed events.
- Log payload metadata (
event,timestamp, stable keys) for support correlation. - Handle unknown future fields gracefully to stay forward-compatible.
Minimal Handler Example
POST /webhooks/orderengine 1) Validate HTTPS + bearer token 2) Parse JSON and verify required envelope fields (source, event, timestamp) 3) Return 204 immediately 4) Enqueue payload for async processing 5) Dedupe using event + timestamp + stable key(s)
Debugging and Incident Correlation
- Webhook requests currently do not include an
x-request-idheader. - Use
event+timestamp+ stable keys (for example,alertKey) for correlation. - Record HTTP status and response body on your receiver side for failed deliveries.
- If a delivery fails, the next scheduler execution is the next redelivery opportunity.