{"openapi":"3.1.0","info":{"title":"AIM — Advanced Inventory Management API","version":"1.2.0","summary":"Self-hosted inventory management with demand forecasting, automatic reordering, supplier auto-emailing, and delivery ETAs.","description":"AIM (Advanced Inventory Management) — inventory management modeled on 7-Eleven Japan's tanpin kanri (single-item management).\n\n**For AI agents:** every product is addressable by SKU (no need to look up internal ids), \n`GET /api/state` returns the whole world in one call, `GET /api/recommendations` tells you exactly what to order, \nand `POST /api/purchase-orders` with `{\"supplierId\": \"...\", \"fromRecommendations\": true}` turns a recommendation into a real order. \nA bundled MCP server (mcp.js) exposes all of this as native tools.\n\n**Auth:** `Authorization: Bearer <key>` or `X-API-Key: <key>`. Requests from localhost need no key by default.\n\n**Errors:** non-2xx responses are `{\"error\": \"<human message>\", \"code\": \"<machine_code>\"}`.\n\n**Webhooks:** register URLs via `POST /api/webhooks`; deliveries are JSON POSTs signed with `X-Inventory-Signature: sha256=HMAC-SHA256(secret, raw_body)`.","license":{"name":"MIT"}},"servers":[{"url":"https://aim.kestudios.dev"}],"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"tags":[{"name":"discovery","description":"Health, docs, and the full system state"},{"name":"products","description":"SKU catalog with live forecasts and reorder math"},{"name":"stock","description":"Sales, adjustments, and the movement audit trail"},{"name":"ordering","description":"Recommendations and purchase orders with ETAs"},{"name":"suppliers","description":"Suppliers: lead times, delivery windows, cut-offs"},{"name":"forecasting","description":"Demand hypotheses (events, weather)"},{"name":"automation","description":"The auto-management daemon"},{"name":"integration","description":"API keys, webhooks, CSV import/export"},{"name":"billing","description":"Hosted-tier plans via Stripe (inert on self-hosted deployments)"}],"paths":{"/api/health":{"get":{"tags":["discovery"],"summary":"Liveness, version, SKU count","security":[],"responses":{"200":{"description":"Server is up","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"name":{"type":"string"},"version":{"type":"string"},"time":{"type":"integer"},"skus":{"type":"integer"},"daemonLastRun":{"type":["integer","null"]}}}}}}}}},"/api/state":{"get":{"tags":["discovery"],"summary":"Everything in one call: KPIs, products (enriched), open POs with ETAs, suppliers, hypotheses, daemon log, outbox","responses":{"200":{"description":"Full system state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/State"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products":{"get":{"tags":["products"],"summary":"List products with live forecast + reorder fields","parameters":[{"name":"low_stock","in":"query","schema":{"type":"string","enum":["true"]},"description":"Only items at/below reorder point"},{"name":"category","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Products","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["products"],"summary":"Create a product","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"sku and name required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate SKU","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products/bulk":{"post":{"tags":["products"],"summary":"Bulk upsert products by SKU (creates unknown suppliers by name)","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ProductInput"}},{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/ProductInput"}}}}]}}}},"responses":{"201":{"description":"Import summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResult"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/products/{idOrSku}":{"get":{"tags":["products"],"summary":"Get one product (by id or SKU)","parameters":[{"name":"idOrSku","in":"path","required":true,"description":"Product internal id (pro_...) or SKU (e.g. COFFEE-HOT)","schema":{"type":"string"}}],"responses":{"200":{"description":"Product","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["products"],"summary":"Update a product","parameters":[{"name":"idOrSku","in":"path","required":true,"description":"Product internal id (pro_...) or SKU (e.g. COFFEE-HOT)","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductInput"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["products"],"summary":"Delete a product","parameters":[{"name":"idOrSku","in":"path","required":true,"description":"Product internal id (pro_...) or SKU (e.g. COFFEE-HOT)","schema":{"type":"string"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sales":{"post":{"tags":["stock"],"summary":"Record a sale (decrements stock, re-forecasts, may emit stock.low)","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key within 24h replays the original response instead of duplicating the write.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaleInput"}}}},"responses":{"201":{"description":"Sale recorded","content":{"application/json":{"schema":{"type":"object","properties":{"product":{"$ref":"#/components/schemas/Product"}}}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sales/bulk":{"post":{"tags":["stock"],"summary":"Record many sales in one call (e.g. end-of-day POS sync)","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key within 24h replays the original response instead of duplicating the write.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/SaleInput"}},{"type":"object","properties":{"sales":{"type":"array","items":{"$ref":"#/components/schemas/SaleInput"}}}}]}}}},"responses":{"201":{"description":"Per-line results","content":{"application/json":{"schema":{"type":"object","properties":{"recorded":{"type":"integer"},"failed":{"type":"integer"},"results":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/adjust":{"post":{"tags":["stock"],"summary":"Manual stock adjustment (delta can be negative; e.g. shrinkage, stocktake)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["delta"],"properties":{"productId":{"type":"string"},"sku":{"type":"string"},"delta":{"type":"number"},"reason":{"type":"string"}}}}}},"responses":{"201":{"description":"Adjusted","content":{"application/json":{"schema":{"type":"object","properties":{"product":{"$ref":"#/components/schemas/Product"}}}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/movements":{"get":{"tags":["stock"],"summary":"Stock movement audit trail (sales, receipts, adjustments), newest first","parameters":[{"name":"product","in":"query","schema":{"type":"string"},"description":"Filter to one product (id or SKU)"},{"name":"limit","in":"query","schema":{"type":"integer","default":100,"maximum":1000}}],"responses":{"200":{"description":"Movements","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Movement"}}}}}}}},"/api/recommendations":{"get":{"tags":["ordering"],"summary":"What should be ordered right now — a dry run of the daemon's ordering pass, grouped by supplier","responses":{"200":{"description":"Recommendations","content":{"application/json":{"schema":{"type":"object","properties":{"recommendations":{"type":"array","items":{"$ref":"#/components/schemas/Recommendation"}},"notes":{"type":"array","items":{"type":"string"}},"generatedAt":{"type":"integer"}}}}}}}}},"/api/purchase-orders":{"get":{"tags":["ordering"],"summary":"List purchase orders with ETAs","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["open","draft","sent","received","cancelled"]},"description":"\"open\" = not received and not cancelled"}],"responses":{"200":{"description":"Purchase orders","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrder"}}}}}}},"post":{"tags":["ordering"],"summary":"Create a PO — pass explicit lines (by sku), or fromRecommendations to order exactly what the engine recommends","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key within 24h replays the original response instead of duplicating the write.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["supplierId"],"properties":{"supplierId":{"type":"string","description":"Supplier id or exact name"},"lines":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string"},"productId":{"type":"string"},"qty":{"type":"number"}}}},"fromRecommendations":{"type":"boolean","description":"Build lines from GET /api/recommendations for this supplier"},"autoSend":{"type":"boolean","description":"Immediately mark sent + email the supplier"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseOrder"}}}},"400":{"description":"Bad supplier or empty lines","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"fromRecommendations found nothing to order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/purchase-orders/{id}":{"get":{"tags":["ordering"],"summary":"Get one purchase order","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Purchase order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseOrder"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/purchase-orders/{id}/send":{"post":{"tags":["ordering"],"summary":"Mark sent and email it to the supplier (SMTP or outbox)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sent","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/purchase-orders/{id}/receive":{"post":{"tags":["ordering"],"summary":"Receive the PO into stock (writes receipt movements)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Received","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already received / cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/purchase-orders/{id}/cancel":{"post":{"tags":["ordering"],"summary":"Cancel the PO","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already received","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/suppliers":{"get":{"tags":["suppliers"],"summary":"List suppliers","responses":{"200":{"description":"Suppliers","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Supplier"}}}}}}},"post":{"tags":["suppliers"],"summary":"Create supplier","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"400":{"description":"name required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/suppliers/{id}":{"put":{"tags":["suppliers"],"summary":"Update supplier","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierInput"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["suppliers"],"summary":"Delete supplier","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/hypotheses":{"get":{"tags":["forecasting"],"summary":"List demand hypotheses","responses":{"200":{"description":"Hypotheses","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Hypothesis"}}}}}}},"post":{"tags":["forecasting"],"summary":"Add a hypothesis — \"heatwave next week, beverages ×1.4\" — forecasts and orders adjust automatically","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["multiplier"],"properties":{"note":{"type":"string"},"multiplier":{"type":"number","example":1.4},"category":{"type":["string","null"]},"sku":{"type":["string","null"]},"productId":{"type":["string","null"]},"startsAt":{"type":"integer"},"endsAt":{"type":"integer"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hypothesis"}}}}}}},"/api/hypotheses/{id}":{"delete":{"tags":["forecasting"],"summary":"Remove hypothesis","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/daemon/run":{"post":{"tags":["automation"],"summary":"Run one full auto-management cycle now (forecast → reorder → order → email → receive → delist)","responses":{"200":{"description":"Cycle summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CycleSummary"}}}}}}},"/api/daemon/log":{"get":{"tags":["automation"],"summary":"Recent cycle summaries, newest first","responses":{"200":{"description":"Log","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CycleSummary"}}}}}}}},"/api/settings":{"get":{"tags":["automation"],"summary":"Read settings","responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}}}},"put":{"tags":["automation"],"summary":"Update settings (partial)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}}}}},"/api/keys":{"get":{"tags":["integration"],"summary":"List API keys (masked — full keys are never stored)","responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"post":{"tags":["integration"],"summary":"Create an API key — the full key appears once in this response","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Created (includes `key` once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"/api/keys/{id}":{"delete":{"tags":["integration"],"summary":"Revoke an API key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks":{"get":{"tags":["integration"],"summary":"List webhooks, valid event names, and recent deliveries","responses":{"200":{"description":"Webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"events":{"type":"array","items":{"type":"string"}},"recentDeliveries":{"type":"array","items":{"type":"object"}}}}}}}}},"post":{"tags":["integration"],"summary":"Register a webhook. Deliveries are HMAC-signed JSON POSTs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"},"description":"Event names or [\"*\"] (default)"},"secret":{"type":"string","description":"Auto-generated if omitted"}}}}}},"responses":{"201":{"description":"Created (includes secret)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"description":"Bad URL or unknown event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/{id}":{"delete":{"tags":["integration"],"summary":"Delete webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/webhooks/{id}/test":{"post":{"tags":["integration"],"summary":"Fire a webhook.test event at this webhook now","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery attempt result","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/export/products.csv":{"get":{"tags":["integration"],"summary":"Export the catalog as CSV","responses":{"200":{"description":"CSV","content":{"text/csv":{"schema":{"type":"string"}}}}}}},"/api/export/movements.csv":{"get":{"tags":["integration"],"summary":"Export the movement audit trail as CSV","responses":{"200":{"description":"CSV","content":{"text/csv":{"schema":{"type":"string"}}}}}}},"/api/billing":{"get":{"tags":["billing"],"summary":"Current plan, limits, and billing status","responses":{"200":{"description":"Billing state","content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["off","hosted"]},"configured":{"type":"boolean"},"plan":{"type":"string","enum":["free","pro"]},"status":{"type":["string","null"]},"limits":{"type":"object"},"plans":{"type":"object"}}}}}}}}},"/api/billing/checkout":{"post":{"tags":["billing"],"summary":"Create a Stripe Checkout session for the Pro plan — redirect the user to the returned url","responses":{"200":{"description":"Checkout session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"id":{"type":"string"}}}}}},"503":{"description":"Stripe not configured on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/billing/portal":{"post":{"tags":["billing"],"summary":"Create a Stripe Billing Portal session (manage / cancel subscription)","responses":{"200":{"description":"Portal session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"409":{"description":"No subscription yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Stripe not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/billing/webhook":{"post":{"tags":["billing"],"summary":"Stripe webhook receiver — authenticated by stripe-signature (HMAC), not an API key","security":[],"responses":{"200":{"description":"Event applied or ignored","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/import/products":{"post":{"tags":["integration"],"summary":"Import products from a JSON array or CSV text (upserts by SKU; creates suppliers by name)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProductInput"}}},"text/csv":{"schema":{"type":"string"}}}},"responses":{"201":{"description":"Import summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportResult"}}}},"400":{"description":"Unparseable body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key as bearer token. Requests from localhost need no key by default."},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable message"},"code":{"type":"string","description":"Machine-readable code, e.g. product_not_found"}}},"Product":{"type":"object","description":"A SKU with live planning fields (recomputed every cycle and on every sale).","properties":{"id":{"type":"string"},"sku":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"supplierId":{"type":["string","null"]},"unitCost":{"type":"number"},"price":{"type":"number"},"currentStock":{"type":"number"},"onOrder":{"type":"number","description":"Inbound on open POs"},"stockPosition":{"type":"number","description":"currentStock + onOrder"},"belowReorder":{"type":"boolean"},"daysOfSupply":{"type":["number","null"]},"leadTimeDays":{"type":"number"},"packSize":{"type":"number"},"minOrderQty":{"type":"number"},"avgDailyDemand":{"type":"number"},"dailyForecast":{"type":"number"},"dailyStdDev":{"type":"number"},"safetyStock":{"type":"number"},"reorderPoint":{"type":"number"},"eoq":{"type":"number"},"abcClass":{"type":"string","enum":["A","B","C"]},"delistFlagged":{"type":["string","null"],"enum":["dead","slow",null]}}},"ProductInput":{"type":"object","required":["sku","name"],"properties":{"sku":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"supplierId":{"type":"string"},"supplierName":{"type":"string","description":"Bulk/CSV only: resolved or created by name"},"unitCost":{"type":"number"},"price":{"type":"number"},"currentStock":{"type":"number"},"leadTimeDays":{"type":"number"},"packSize":{"type":"number"},"minOrderQty":{"type":"number"}}},"SaleInput":{"type":"object","properties":{"sku":{"type":"string"},"productId":{"type":"string"},"qty":{"type":"number","default":1},"at":{"type":"integer","description":"Unix ms; defaults to now"}}},"Movement":{"type":"object","properties":{"id":{"type":"string"},"productId":{"type":"string"},"sku":{"type":["string","null"]},"type":{"type":"string","enum":["sale","receipt","adjustment"]},"qty":{"type":"number"},"at":{"type":"integer"},"ref":{"type":"string"}}},"Recommendation":{"type":"object","properties":{"supplierId":{"type":"string"},"supplierName":{"type":"string"},"lines":{"type":"array","items":{"type":"object","properties":{"productId":{"type":"string"},"sku":{"type":"string"},"name":{"type":"string"},"qty":{"type":"number"},"unitCost":{"type":"number"}}}},"total":{"type":"number"},"minOrderValue":{"type":"number"},"heldBelowMinimum":{"type":"boolean","description":"True when total is under the supplier minimum — daemon will hold it"}}},"PurchaseOrder":{"type":"object","properties":{"id":{"type":"string"},"supplierId":{"type":"string"},"supplierName":{"type":"string"},"status":{"type":"string","enum":["draft","sent","in_transit","received","cancelled"]},"lines":{"type":"array","items":{"type":"object"}},"total":{"type":"number"},"auto":{"type":"boolean","description":"Raised by the daemon (vs manually)"},"orderedAt":{"type":"integer"},"eta":{"type":"integer"},"etaLabel":{"type":["string","null"],"example":"in 2 days"},"leadTimeDays":{"type":"number"},"sentAt":{"type":"integer"},"receivedAt":{"type":"integer"}}},"Supplier":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"leadTimeDays":{"type":"number"},"deliveryWindows":{"type":"array","items":{"type":"integer"},"description":"Delivery hours (0-23), e.g. [8,13,19] = 3 deliveries/day"},"cutoffHour":{"type":["integer","null"],"description":"Orders after this hour start lead time tomorrow"},"minOrderValue":{"type":"number"}}},"SupplierInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"leadTimeDays":{"type":"number"},"deliveryWindows":{"oneOf":[{"type":"array","items":{"type":"integer"}},{"type":"string","example":"8,13,19"}]},"cutoffHour":{"type":"integer"},"minOrderValue":{"type":"number"}}},"Hypothesis":{"type":"object","properties":{"id":{"type":"string"},"note":{"type":"string"},"multiplier":{"type":"number"},"scope":{"type":"object","properties":{"productId":{"type":["string","null"]},"category":{"type":["string","null"]}}},"startsAt":{"type":"integer"},"endsAt":{"type":"integer"}}},"CycleSummary":{"type":"object","properties":{"at":{"type":"integer"},"trigger":{"type":"string","enum":["daemon","manual"]},"recomputed":{"type":"integer"},"ordersCreated":{"type":"integer"},"orderLines":{"type":"integer"},"emailsSent":{"type":"integer"},"received":{"type":"integer"},"delistFlags":{"type":"array","items":{"type":"object"}},"notes":{"type":"array","items":{"type":"string"}}}},"Settings":{"type":"object","properties":{"currency":{"type":"string"},"serviceLevel":{"type":"number","description":"0-1, in-stock probability target"},"targetDaysOfSupply":{"type":"number"},"maxDaysOfSupply":{"type":"number","description":"JIT cap on any single order"},"orderCost":{"type":"number"},"holdingCostRate":{"type":"number"},"autoManage":{"type":"boolean"},"autoSend":{"type":"boolean"},"autoReceive":{"type":"boolean"},"autoEmailAlerts":{"type":"boolean"},"daemonIntervalMinutes":{"type":"number"},"notifyEmail":{"type":"string"},"fromEmail":{"type":"string"},"companyName":{"type":"string"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string","example":"ti_a1b2c3d4"},"key":{"type":"string","description":"Full key — present ONLY in the POST /api/keys response"},"createdAt":{"type":"integer"},"lastUsedAt":{"type":["integer","null"]},"revoked":{"type":"boolean"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":"string","description":"HMAC-SHA256 secret for X-Inventory-Signature verification"},"active":{"type":"boolean"}}},"ImportResult":{"type":"object","properties":{"created":{"type":"integer"},"updated":{"type":"integer"},"suppliersCreated":{"type":"integer"},"skipped":{"type":"integer"},"errors":{"type":"array","items":{"type":"string"}}}},"State":{"type":"object","properties":{"version":{"type":"string"},"settings":{"$ref":"#/components/schemas/Settings"},"kpis":{"type":"object","properties":{"skuCount":{"type":"integer"},"stockValue":{"type":"number"},"retailValue":{"type":"number"},"lowStock":{"type":"integer"},"deadStock":{"type":"integer"},"openPOs":{"type":"integer"},"incomingUnits":{"type":"number"}}},"products":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"suppliers":{"type":"array","items":{"$ref":"#/components/schemas/Supplier"}},"purchaseOrders":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrder"}},"hypotheses":{"type":"array","items":{"$ref":"#/components/schemas/Hypothesis"}},"daemonLog":{"type":"array","items":{"$ref":"#/components/schemas/CycleSummary"}},"serverTime":{"type":"integer"}}}}}}