1. Overview
  2. Observe
  3. Agent replenishment

Agent replenishment

Agent replenishment lets supply-side automation (your own worker, a partner AI agent, or an integration) POST signed updates into Eonix so stock and reorder logic can run without a staff browser session. It is the inbound mirror of outbound webhooks: outbound tells partners what happened; agent gates let partners drive forecasts, inventory adjustments, and (after staff approval) wholesaler purchase orders.

You need a commerce-enabled workspace (Web Store module) and a plan that includes Agent replenish (Trial preview and paid Micro / Scale tiers in the current catalog).


Desk map

WhatRouteWho uses it
Agent gatesObserve → Webhooks — third tab Agent gates (/dxp/observe/webhooks?tab=agent)Operators mint gates, rotate secrets, read the agent inbox
Purchase requests/dxp/observe/purchase-requestsStaff queue and approve PO intents before wholesaler delivery
Outbound to wholesalerWebhooks → Outbound tabSubscribe to agent.replenish.purchase_order and agent.replenish.stockout_predicted

Replenishment rules and forecast evaluation are available to integrators via staff-session APIs (/dxp/api/replenish/*); there is no separate rules editor in the DXP core yet. Agents can still upsert rules with inbound event agent.replenish.rule_upsert.


How the pieces fit together

Supply-side worker  --signed POST-->  POST /dxp/api/agents/replenish
                                              |
                                              v
                                    Engine inbox + worker
                                              |
                                              v
                         Platform (inventory ledger, rules, forecasts)
                                              |
Staff approve PO  -------------------->  Outbound webhook  ---->  Wholesaler URL
  1. You create an agent gate and share the signing secret with the worker (once).
  2. The worker POSTs JSON envelopes (agent.replenish.forecast, agent.replenish.adjust, …).
  3. Eonix verifies HMAC, enforces idempotency, and processes the inbox asynchronously.
  4. For wholesaler orders, staff create a purchase request in the desk and Approve; Eonix enqueues an outbound event your wholesaler endpoint receives.

Agent gates walkthrough

Goal: Register a gate and run a harmless signature test.

Step 1 — Open the desk

  1. Sign in to the desk.
  2. Open Observe → Webhooks (/dxp/observe/webhooks).
  3. Select the Agent gates tab (third tab). Wait until “Loading…” finishes.

Step 2 — Create a gate

Scroll to Add or rotate and fill:

  1. Owning Space id — the Space the gate belongs to (often pre-filled when you have an active Space; see Webhooks and events if empty).
  2. Event affinity — usually Space-local for one shop.
  3. Event types — for a first test, click the preset agent.replenish.verify (signature smoke test only).
  4. Enabled — leave ticked.
  5. Signing secret (one-time) — a long random password (for example agent-gate-test-secret-2026). Copy it somewhere safe; the desk does not show it again.

Leave External secret ref empty unless your operator uses vault-backed secrets.

Click Save gate.

Step 3 — Note the gate id and ingress

In the Gates table you should see:

  • Gate id — send this as header X-Eonix-Gate-Id on every agent POST.
  • IngressPOST /dxp/api/agents/replenish on your platform host (agents use HTTPS to the platform, not the engine port).

Use Test on the row if your build exposes it, or send a signed POST from your worker (see Integrator reference below).

Step 4 — Check the inbox

Scroll to Recent inbox on the same tab. After a successful POST you should see a row (status processed or briefly pending).

You have a working agent gate.


Event types (quick reference)

Inbound (agent POST → gate)

Event typePurpose
agent.replenish.verifySignature / connectivity test
agent.replenish.noopAcknowledge only
agent.replenish.forecastRecord days-to-stockout and daily velocity for a product at a location
agent.replenish.adjustAppend an inventory ledger row (for example restock)
agent.replenish.rule_upsertCreate or update a replenishment rule (min on hand, lead time, reorder qty)

Leave Event types blank on the gate to allow every inbound agent.replenish.* type listed above.

Outbound (Eonix → your wholesaler URL)

Configure these on Webhooks → Outbound (same Space affinity as the shop):

Event typeWhen it fires
agent.replenish.stockout_predictedEvaluation shows stock may run out before lead time (staff forecast API can emit at most once per rule per UTC day)
agent.replenish.purchase_orderStaff Approve a purchase request

Use a vault: (or operator-supported) External secret ref on the outbound subscription so signing material is not stored in plain text in the desk.


Purchase requests walkthrough

Goal: Queue a PO in the desk and approve it so outbound webhooks fire.

Prerequisites

  1. An outbound subscription with event type agent.replenish.purchase_order pointing at your wholesaler catch URL (see Outbound walkthrough — use webhook.site for a first test).
  2. A product id from Create → Products (copy the Mongo hex id from the product editor or list).

Step 1 — Open Purchase requests

  1. Observe → Purchase requests (/dxp/observe/purchase-requests), or the card on the Observe hub.
  2. Confirm Location is main (default Main shop) unless you use another shop location code.

Step 2 — Create a request

Under New request:

  1. Product id — paste the product hex id.
  2. Quantity — units to order.
  3. Supplier ref (optional) — your wholesaler SKU or reference string.
  4. Click Create.

The row appears in Queue with status pending.

Step 3 — Approve

  1. Click Approve on the row.
  2. Check Webhooks → Outbound → Recent outbox for agent.replenish.purchase_order.
  3. Confirm your wholesaler endpoint (or webhook.site) received the signed payload.

Cancel removes a pending row without sending outbound traffic.


Velocity and replenishment rules (background)

Eonix evaluates sales velocity from the inventory ledger (sale movements at the shop location). If the ledger has no sales in the window, paid commerce orders are used as a fallback.

Staff and integrators with a desk session can call:

  • GET /dxp/api/replenish/forecast?location=main — list rules with computed velocity and a needs_replenishment flag when days-to-stockout is inside lead time.
  • GET/POST/PATCH /dxp/api/replenish/rules — manage rules (product, min on hand, lead time days, reorder quantity).

With emit_alerts=1 (default), the forecast endpoint can enqueue agent.replenish.stockout_predicted outbound events (deduplicated per rule per UTC day).

Agents can push their own forecasts with agent.replenish.forecast instead of polling the staff API.


Integrator reference

Agents POST to:

POST https://<your-platform-host>/dxp/api/agents/replenish

Required headers:

HeaderMeaning
X-Eonix-Gate-IdGate id from the desk
X-Eonix-SignatureHMAC-SHA256 hex of the raw JSON body
X-Eonix-Idempotency-KeyUnique key per logical send (replay-safe)

Body shape matches other Eonix webhooks: event_id, event_type, occurred_at, core_id, origin_space_id, and a payload object. The envelope must include your workspace core_id; the platform checks that your plan includes agent replenish before forwarding to the engine.

Rate limit: 120 requests per minute per gate id. Over-limit responses are HTTP 429 with Retry-After.

Engineering detail, example worker flow, and smoke script: eonixstream/docs/dev/agent-replenish-worker.md in the platform repository.


When something goes wrong

“agent replenish is not included on your plan”

  • Upgrade the workspace tier or confirm you are not on a legacy plan without the flag. See Billing and plans.

“X-Eonix-Gate-Id required”

  • The agent must send the gate id header (or gate_id query parameter).

HTTP 429 rate limit exceeded

  • Slow the worker or batch work; limit is per gate, not per workspace.

Inbound row stays pending or shows dead

  • Engine worker may be stopped in dev (make run should include engine). Ask your operator to check engine logs and agent inbox replay tools.

Approve succeeded but wholesaler saw nothing

  • Outbound subscription must include agent.replenish.purchase_order, correct Owning Space id, and enabled delivery URL.
  • Check Recent outbox on the Outbound tab for delivery errors.

Forecast / rules APIs return 403

  • You need a signed-in staff session on /dxp/api/replenish/*; those routes are not for the public agent gate.