A daily batch job is usually enough for a first posted-price system. Version the response model, policy configuration and price application separately. Use an API when operators or downstream systems need a consistent recommendation contract.
{
"request_id": "price-2026-10-08-001",
"sku_id": "SKU-17",
"market_id": "STORE-3",
"decision_at": "2026-10-08T08:00:00+05:30",
"horizon_hours": 24,
"currency": "INR",
"current_price_minor": 10000,
"cost_snapshot_id": "cost-17-v4",
"inventory_snapshot_id": "stock-3-v21",
"policy_version": "pricing-v2"
}Validate currency, positive prices, horizon, timestamps and snapshot ownership. Resolve approved prices and constraints on the server, so the caller cannot relax them. Money uses integer minor units, with currency-specific rules defined in the contract.
Return decision_id, status (recommended, fallback, review_required), recommended or null
price, validity interval, supported alternatives, expected contribution, uncertainty semantics,
reason codes, model version, policy version and snapshot versions. A demand interval must state its
unit, horizon and nominal coverage. A mean-lift confidence interval must state the comparison policy
and inference method. Avoid a generic percentage called “confidence.”
Save the pre-decision feature snapshot, grid, eliminated candidates and reasons, response estimates,
selected price, assignment probability, operator override, applied price and actual exposure. Join
purchases and matured returns using decision_id plus the decision unit and time interval. Log the
action actually taken even if an operator overrides it, and keep the original experimental
assignment for the planned analysis. Make retries idempotent, and stop an expired recommendation
from overwriting a newer price.
Save a pending application record before delivery. Tie the idempotency key to the exact price, unit, interval and release, then check the current price and version atomically when applying it. Reject a changed or expired state instead of overwriting a newer decision, and reconcile an unknown delivery result before retrying. The response's alternatives are diagnostic, not permission to apply a price that failed a gate.
An operator override may have an unknown selection probability. Mark it clearly, and do not reuse the original randomisation probability as the override's propensity. These records can stay in an intention-to-treat analysis, but offline evaluation of actual actions needs a justified way to handle them.
Monitor stale inputs, cost changes, price application failures, recommendation/application gaps, abstention rate, supported-action coverage, price oscillation, margin-floor breaches and latency. Once outcomes mature, add profit, bias, demand interval coverage, returns, repeat purchase and complaints. Show outcome completeness by decision cohort, so a recent cohort does not look more profitable just because its returns have not arrived.
Set named owners and triggers for rolling back to the approved fallback, such as a sudden margin drop, broken stock logging or too many constraint violations. Retraining is a reviewed response to evidence, not the automatic answer to every drift alert.