This file is the front end. Your backend owns the receipts — it just needs to return orders in this shape, and everything on screen derives from it. Consumption state lives separately, so re-syncing orders never wipes what you've marked as eaten.
{
"order_id": "publix-2026-07-21",
"retailer": "Publix",
"placed": "2026-07-21",
"delivered": "2026-07-21T20:10:00-04:00",
"shopper": "Pedro",
"totals": { "subtotal": 208.54, "total": 247.35, "saved": 156.34 },
"items": [{
"name": "Monster Energy Drink (4 x 12 fl oz)",
"category": "Beverages",
"qty": 3, // packages bought"units_per_pack": 4, // consumable units inside"unit_label": "can",
"unit_price": 9.97,
"final_price": 19.94,
"deal": "Buy 2 get 1",
"perishable": false,
"shelf_days": null
}]
}Also scriptable: window.Pantry.ingest(ordersArray) merges new receipts by order_id, and window.Pantry.export() returns everything as JSON — wire either straight to a fetch() against your API. Manual pack, per-pack, and price adjustments are stored as overrides on top of order data — never inside it — so a receipt re-sync keeps your corrections, and they ride along in the export.