Get Started with Aeion SCM
Set up your AI-powered supply chain in 5 steps. Weighted moving average forecasting, wave picking with route optimization, voice-directed picking, safety stock, and vendor scoring—all in under 30 minutes.
Configure Warehouse & Bins
Go to SCM → Settings → Warehouses.
Create Warehouse:
bash
POST /api/v1/scm/warehouses
{
"name": "East Coast DC",
"code": "ECDC",
"address": {
"street": "123 Logistics Way",
"city": "Newark",
"state": "NJ",
"postalCode": "07102",
"country": "US"
},
"status": "active",
"totalCapacity": 50000
}
Configure Bin Locations:
bash
POST /api/v1/scm/warehouses/{warehouseId}/bins
{
"code": "A-03-2",
"zoneId": "fast-pick",
"type": "pick",
"aisle": "A",
"rack": "03",
"level": "2",
"maxWeight": 500
}
Bin Code Format: A-03-2 → aisle-rack-level
- Aisle: Letter (A-Z) — warehouse zone
- Rack: Rack position within aisle
- Level: Vertical position
Bin Types: pick, reserve, overflow, quarantine, staging
Set Up Products & Inventory
Go to SCM → Products → Add Product.
Create Product:
bash
POST /api/v1/scm/products
{
"sku": "WDG-1234-BLK",
"name": "Widget Pro - Black",
"type": "finished_good",
"description": "Premium widget with advanced features",
"cost": 8.00,
"price": 24.99,
"weight": 0.5,
"barcode": "012345678901",
"reorderPoint": 25,
"reorderQty": 100,
"leadTimeDays": 7
}
Set Initial Stock:
Stock levels are adjusted to an absolute quantity, not created directly — this keeps every change auditable against a reason.
bash
POST /api/v1/scm/stock-levels/adjust
{
"productId": "product-xxx",
"warehouseId": "warehouse-ecdc",
"newQty": 500,
"reason": "Initial stock load"
}
Reorder Parameters (set on the product):
```typescript { "reorderPoint": 25, // When stock drops below, suggest reorder "reorderQty": 100, // Default order quantity "leadTimeDays": 7 // Days from order to receipt }
// Safety stock = avgDailyDemand × defaultSafetyStockDays (scm_settings, default: 14) // When to reorder = reorderPoint + safetyStock ```
Configure AI Demand Forecasting
Go to SCM → Settings → Demand Forecasting.
Forecasting Settings (`scm_settings`, singleton — `PATCH /api/v1/scm/settings`):
typescript
{
"aiReorderEnabled": true,
"defaultReorderMethod": "ai", // manual | fixed_qty | min_max | ai
"defaultSafetyStockDays": 14, // Safety stock = avgDailyDemand × this
"forecastHorizonWeeks": "8", // 4 | 8 | 12 | 26
"forecastConfidenceThreshold": 75 // Min confidence % to include in suggestions
}
List Current Reorder Suggestions (API):
bash
GET /api/v1/scm/demand/suggestions?warehouse=warehouse-ecdc&urgency=high
Generate Fresh Suggestions (API):
bash
POST /api/v1/scm/demand/suggestions/generate
Response:
typescript
{
"suggestions": [
{
"productId": "product-xxx",
"productName": "Widget Pro - Black",
"sku": "WDG-1234-BLK",
"currentStock": 18,
"reorderPoint": 25,
"avgDailyDemand": 2.5,
"daysUntilStockout": 7,
"suggestedQty": 142,
"urgency": "high"
}
],
"count": 1
}
Create PO from Suggestion (API):
bash
POST /api/v1/scm/purchase-orders
{
"vendorId": "vendor-acme",
"warehouseId": "warehouse-ecdc",
"lineItems": [
{
"productId": "product-xxx",
"qtyOrdered": 142,
"unitCost": 12.50
}
],
"paymentTerms": "net30",
"expectedDelivery": "2026-05-18"
}
Response:
typescript
{
"doc": {
"id": "po-xxx",
"poNumber": "PO-1001",
"status": "draft",
"vendor": "vendor-acme",
"warehouse": "warehouse-ecdc",
"lineItems": [
{
"product": "product-xxx",
"qtyOrdered": 142,
"qtyReceived": 0,
"unitCost": 12.50,
"lineTotal": 1775.00
}
],
"subtotal": 1775.00,
"total": 1775.00,
"paymentTerms": "net30",
"expectedDelivery": "2026-05-18"
}
}
Set Up Wave Picking
Go to SCM → WMS → Wave Picking.
Wave and voice-picking behavior (route optimization by aisle/rack/level,
4-character confirmation codes excluding lookalike characters) is built in and
not currently configurable via scm_settings — there's no wave.*/voice.*
settings section to set up before using it.
Create Pick Wave (API):
bash
POST /api/v1/scm/pick-waves
{
"warehouseId": "warehouse-ecdc",
"orderIds": ["order-123", "order-456", "order-789"],
"orderType": "commerce",
"waveType": "outbound",
"assignedTo": ["worker-1", "worker-2"]
}
Response:
typescript
{
"doc": {
"id": "wave-xxx",
"waveNumber": "WAVE-2026-00001",
"status": "planned",
"waveType": "outbound",
"totalLines": 15,
"pickedLines": 0,
"lineItems": [
{
"productId": "product-xxx",
"binCode": "A-03-2",
"qty": 5,
"pickedQty": 0,
"confirmCode": "X7K2",
"orderId": "order-123"
}
],
"optimizedRoute": false,
"assignedTo": ["worker-1", "worker-2"]
}
}
Optimize Pick Route (API):
bash
POST /api/v1/scm/pick-waves/{waveId}/optimize
Voice Picking Workflow:
```bash # Get the next pick instruction for a worker: GET /api/v1/scm/pick-waves/{waveId}/next-pick?pickerId=worker-1
# Worker device shows: # "Go to Aisle A, Rack 3, Level 2" # "Pick 5 units" # "Say confirm code X7K2"
# Worker confirms pick (lineIndex identifies the line within the wave, not a # separate lineItemId in the URL): POST /api/v1/scm/pick-waves/{waveId}/confirm-pick { "lineIndex": 0, "pickedQty": 5, "confirmCode": "X7K2", "pickedBy": "worker-1" }
# If wrong code: the response reports the mismatch — the wave line is not # marked picked, so the picker can retry. ```
Complete Wave (API):
bash
PATCH /api/v1/scm/pick-waves/{waveId}/complete
A wave can't be completed while any lines have unpicked quantity.
Configure Vendors & Procurement
Go to SCM → Vendors → Add Vendor.
Create Vendor:
bash
POST /api/v1/scm/vendors
{
"name": "ACME Supplies Co.",
"code": "ACME",
"contactName": "John Smith",
"contactEmail": "john@acme.com",
"contactPhone": "555-0100",
"address": {
"street": "456 Industrial Blvd",
"city": "Chicago",
"state": "IL",
"postalCode": "60601",
"country": "US"
},
"paymentTerms": "net30",
"leadTimeDays": 7,
"minOrderQty": 1,
"taxId": "12-3456789"
}
Vendor Scorecard (API):
bash
GET /api/v1/scm/vendors/{vendorId}/scorecard
typescript
{
"vendorId": "vendor-acme",
"metrics": {
"onTimeDelivery": 92, // % on-time
"qualityScore": 98, // % accepted (2% rejected)
"avgLeadTime": 6.5, // Days
"leadTimeVariance": 1.2 // Standard deviation
},
"overallScore": 95,
"tier": "preferred"
}
Receive PO (API):
Receiving is its own resource (receiving-receipts), not a sub-route of the
PO itself — the PO id goes in the request body.
bash
POST /api/v1/scm/receiving-receipts
{
"poId": "po-xxx",
"lines": [
{
"productId": "product-xxx",
"qtyExpected": 142,
"qtyReceived": 140,
"qtyRejected": 2,
"lotNumber": "LOT-ACME-2026-05",
"binLocation": "RCV-01",
"reason": "2 units damaged in transit"
}
],
"receivedBy": "worker-1"
}
Receiving a PO automatically creates an inventory movement and updates stock levels — no separate manual step.
Quick Reference
Warehouse API:
```bash # Create warehouse POST /api/v1/scm/warehouses
# Get warehouses GET /api/v1/scm/warehouses
# Create bin location POST /api/v1/scm/warehouses/{warehouseId}/bins ```
Product API:
```bash # Create product POST /api/v1/scm/products
# Get product GET /api/v1/scm/products/{productId}
# List products GET /api/v1/scm/products ```
Inventory API:
```bash # Adjust stock to an absolute quantity POST /api/v1/scm/stock-levels/adjust
# Transfer stock between warehouses POST /api/v1/scm/stock-levels/transfer
# Get stock GET /api/v1/scm/stock-levels?productId=xxx&warehouseId=xxx
# Create a raw inventory movement POST /api/v1/scm/inventory-movements ```
PO API:
```bash # Create PO POST /api/v1/scm/purchase-orders
# Get PO GET /api/v1/scm/purchase-orders/{poId}
# Send PO POST /api/v1/scm/purchase-orders/{poId}/send
# Receive against a PO POST /api/v1/scm/receiving-receipts ```
Wave API:
```bash # Create wave POST /api/v1/scm/pick-waves
# Optimize route POST /api/v1/scm/pick-waves/{waveId}/optimize
# Get next pick instruction GET /api/v1/scm/pick-waves/{waveId}/next-pick
# Confirm a pick POST /api/v1/scm/pick-waves/{waveId}/confirm-pick
# Complete wave PATCH /api/v1/scm/pick-waves/{waveId}/complete ```
Demand API:
```bash # List current suggestions GET /api/v1/scm/demand/suggestions
# Generate fresh suggestions POST /api/v1/scm/demand/suggestions/generate
# Get forecast GET /api/v1/scm/demand/forecast/{productId}
# SKU performance (includes ABC classification) GET /api/v1/scm/analytics/sku-performance ```
FAQ
Recent periods are weighted higher than older ones — the 6 most recent periods carry about 78% of the total weight. Captures trends better than a simple moving average, without manual parameter tuning.
Route optimization sorts pick lines by aisle → rack → level, eliminating backtracking, so pickers cover less ground per wave.
The character set excludes lookalike/soundalike characters (I/O/0/1), giving over 1 million possible codes while avoiding voice recognition confusion. Worker says "X7K2" instead of entering a number.
Safety stock is based on average daily demand and your configured safety-stock days (`scm_settings.defaultSafetyStockDays`, default: 14).
On-time delivery %, quality (rejection rate), and lead time consistency roll up into an overall weighted score, recalculated automatically on every PO receipt.
Bin assignments are suggested based on ABC classification. A-items (the top 80% of cumulative annual value) are placed closest to the dock. C-items are placed farthest. See `GET /api/v1/scm/warehouses/{id}/slotting-analysis`.
draft → sent → partial → received (partial/received depend on how much of the order has arrived). Can also be cancelled from any state before received, or marked overdue if expected delivery passes unreceived.
Receiving a PO (`POST /api/v1/scm/receiving-receipts`) automatically creates an inventory movement, updates stock levels, and handles partial receipts and rejections — no separate manual steps.
Classify inventory by cumulative annual value. A: items making up the top 80% of total value. B: the next slice, up to 95% cumulative. C: the remainder, 95-100% cumulative. Used for slotting and cycle counting priorities — see `GET /api/v1/scm/analytics/sku-performance`.
Available stock is compared against average daily demand, then sorted by urgency (lowest days first).
Yes, via `POST /api/v1/scm/stock-levels/transfer` — it creates linked outbound/inbound inventory movements at the source and destination warehouses.
Forecasted demand is compared against actual shipments using Mean Absolute Percentage Error (MAPE). Under 10% is good, under 20% is acceptable.
planned → active/in_progress → completed (or cancelled at any point before completion). A wave can't be completed while any lines have unpicked quantity, and completion triggers an event your integrations can subscribe to.