Next Restaurant 6.1.0: move your data in, run payroll, and connect other systems Next Inventory 6.2.0: a REST API and webhooks for your other systems Next DB 6.1: Auto-Updating Tables, Printing, Phone Layout and SEO Next Task 6.0.0: a task manager for Joomla Next Inventory 6.1.1: smoother Check Out, no more list limits, and much faster PHP2Shell: Is Your Joomla Site Safe? What to Do Today Introducing Next Boards: Kanban project and task boards for Joomla Building the Future of Joomla Extensions
NextSoftware

Webhook events

Outbound events. When stock or a record changes, Next Inventory sends an HTTP POST to each webhook subscribed to that event, so another system can react without polling.

A webhook says something happened; the REST API reads the full record. To keep another system's stock in step, subscribe to stock.changed: it covers every way stock can change.

Configured in Configuration → Webhooks.

Delivered as POST with Content-Type: application/json.

Envelope

{
    "event": "stock.changed",
    "timestamp": "2026-11-11T09:30:00Z",
    "site": "https://your-site.example",
    "data": []
}
Field Type Meaning
event string The event name. The same as the X-NextInventory-Event header.
timestamp string ISO 8601, when the event happened. Unchanged on a retry.
site string The sending site's root address, so one receiver can serve several sites.
data object The event's own fields.

Signing

Each delivery carries webhook-signature in the form v1,<base64>, computed with HMAC-SHA256.

The signature covers the {webhook-id}.{webhook-timestamp}.{raw body}.

  • Two schemes are sent on every delivery; verify either one: the Standard Webhooks webhook-signature (base64, signs id, timestamp and body) or X-NextInventory-Signature (sha256= + hex HMAC of the raw body only).
  • Each webhook has its own secret. A generated secret starts with whsec_ and is base64: the HMAC key is the decoded bytes after the prefix. A secret you typed yourself is used as-is.
  • Compute the HMAC over the bytes as received; re-encoding the parsed JSON changes them and the check fails. Compare with a constant-time function.
  • Reject a webhook-timestamp more than about 300 seconds old to refuse replayed messages. X-NextInventory-Signature has no timestamp, so it cannot tell a replay from a fresh delivery.
  • Making a new secret takes effect on the next delivery, so update the receiver first.
  • webhook-id (msg_<delivery id>) and X-NextInventory-Delivery are the same on every retry of one delivery: dedupe on them.

Verify a Standard Webhooks signature in PHP

$body = file_get_contents('php://input');
$id   = $_SERVER['HTTP_WEBHOOK_ID'] ?? '';
$ts   = $_SERVER['HTTP_WEBHOOK_TIMESTAMP'] ?? '';
$sigs = $_SERVER['HTTP_WEBHOOK_SIGNATURE'] ?? '';

if (abs(time() - (int) $ts) > 300) {
    http_response_code(401);
    exit;
}

$key      = str_starts_with($secret, 'whsec_') ? base64_decode(substr($secret, 6)) : $secret;
$expected = 'v1,' . base64_encode(hash_hmac('sha256', "$id.$ts.$body", $key, true));
$valid    = false;

foreach (explode(' ', $sigs) as $sig) {
    $valid = $valid || hash_equals($expected, $sig);
}

if (!$valid) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);

Delivery

Retries: 7.

The Deliveries tab of the Webhooks screen lists every delivery with its event, status (pending, sent, failed), attempts, HTTP code and last error, with a status filter and Resend.

  • Answer 2xx within 8 seconds. Anything else is retried after 1m, 5m, 30m, 2h, 6h, 12h and 24h; after the 8th failed attempt the delivery is marked failed. Answer 410 Gone to stop at once.
  • Be idempotent. Dedupe on webhook-id: a retry or a Resend carries the same id.
  • Expect any order. A retry can arrive after a later event about the same item.
  • Retries need the scheduled task "Next Inventory: Retry webhook deliveries", created when the first webhook is saved. The Health tab warns when deliveries are overdue.
  • The endpoint must be reachable from your server. Private and local addresses are refused unless a Super User allows them.
  • Ignore fields you do not recognise. New fields may be added over time.

Tick the events each webhook should receive. A webhook only receives the events it subscribes to; Send a test ping sends ping to it whatever it subscribes to.

Events

Event When
stock.changed An item's stock quantity changed, in any way
stock.low An item fell to its low-stock threshold
stock_movement.finalized A check in, check out, add or remove batch was finalized
transfer.finalized A warehouse transfer was finalized
adjustment.finalized A stock adjustment was finalized
item.created An item was created
item.updated An item was edited
item.deleted An item was deleted
warehouse.created A warehouse was created
warehouse.updated A warehouse was edited
warehouse.deleted A warehouse was deleted
recipient.created A recipient was created
recipient.updated A recipient was edited
recipient.deleted A recipient was deleted
ping A test message

All Extensions