Developer Handover Pack
Everything needed to build the automation from scratch: current state, full agent specs, data flow, and the build stack.
Developer Handover Pack
Multichannel Inventory Sync
[YourCompany.com] · Fulfilment Department · Prepared by FullSpec · [Today's Date]
This document is the primary technical reference for the FullSpec build team working on the Multichannel Inventory Sync automation. It covers the current manual process in detail, the specification for each automation agent, the end-to-end data flow across all connected systems, and the recommended build stack. The FullSpec team owns the build, testing, and deployment from start to finish. The process owner's team is responsible for supplying API credentials, confirming reorder threshold data, and reviewing flagged anomalies once the system is live.
01Process snapshot
02Agent specifications
Watches all connected sales channels and the warehouse system for any stock-changing event, including new orders on Shopify and Amazon Seller Central, confirmed returns processed through Linnworks, and purchase order receipts marked as received. On each event, the agent queries Linnworks for the current on-hand quantity of every affected SKU, applies the order delta, return credit, or inbound receipt, and produces a validated new quantity per SKU. If any calculated quantity falls below zero, the agent halts the update for that SKU and raises an anomaly flag for human review instead. Valid quantities are pushed simultaneously to the Shopify Inventory API and the Amazon Listings API. A timestamped audit row is then appended to the master Google Sheet covering SKU, event type, previous quantity, and new quantity. This agent replaces all eight manual steps that previously consumed up to 160 minutes per cycle and was the primary source of stock drift, oversells, and delayed returns restocking. Estimated build time: 28 hours. Complexity: Complex.
// Input
event_type: 'order' | 'return' | 'po_receipt'
source_channel: 'shopify' | 'amazon' | 'linnworks'
sku_id: string
quantity_delta: integer // negative for orders, positive for returns and receipts
order_id: string // reference for audit log
linnworks_stock_on_hand: integer // pulled from Linnworks API after trigger
// Calculation
new_quantity = linnworks_stock_on_hand + quantity_delta
if new_quantity < 0: raise anomaly_flag, halt channel updates for this SKU
// Output (valid quantity only)
shopify_inventory_update: { inventory_item_id, location_id, available: new_quantity }
amazon_listings_update: { seller_sku, quantity: new_quantity, fulfillment_latency: 1 }
google_sheets_row: { timestamp, sku_id, event_type, source_channel, prev_quantity, new_quantity, order_id }
// On anomaly
anomaly_record: { sku_id, calculated_quantity: new_quantity, trigger_event: event_type, flagged_at: timestamp }
human_review_required: true- Linnworks must be configured as the single source of truth before the agent goes live. If Shopify or Amazon is also writing stock levels independently via another integration, a tiebreaker rule must be documented and agreed before build begins. Failing to resolve this will cause conflicting updates.
- Shopify plan must include API access to the Inventory API (available on Basic and above). Confirm the plan tier and that inventory tracking is enabled per SKU before build.
- Amazon Listings API rate limits apply: submit-feeds endpoint allows 1 request per 2 seconds. The agent must implement a queue with exponential back-off for batches exceeding a single SKU. Amazon-side listing visibility may lag 2 to 5 minutes behind the submitted update; this is expected behaviour and must be communicated to the process owner.
- Linnworks API authentication uses OAuth 2.0 with a server-side token exchange. Confirm the Linnworks subscription tier supports API access (requires 'Open Platform' or above on the Linnworks plan). Store the refresh token in the shared credential store, not in the workflow configuration.
- Google Sheets audit log: confirm the target Sheet ID and tab name before build. The agent appends rows and never overwrites; the sheet must have edit access granted to the automation service account.
- Deduplicate on order_id: if the same order webhook fires more than once (Shopify and Amazon both retry on non-200 responses), the agent must check the audit log for an existing order_id before applying the delta a second time.
- Anomaly flag behaviour must be confirmed with the process owner: the default is to halt the channel update and log the record without sending a channel push. A secondary Slack alert to the fulfilment coordinator should fire for each anomaly. Confirm the target Slack channel before build.
Triggers immediately after the Stock Level Sync Agent completes a quantity update for one or more SKUs. The agent reads the new quantity for each updated SKU from the Google Sheets audit log and compares it against the reorder threshold defined for that SKU in a reference tab of the same sheet. If the new quantity is at or below the threshold, it composes a structured Slack alert and posts it to the buying team channel, including SKU name, current quantity, and reorder point. Regardless of whether a threshold is breached, the agent posts a stock movement journal entry to Xero for every qualifying stock-change event, keeping the finance record current without end-of-week manual reconciliation. This agent replaces steps 9, 10, and 11, eliminating 55 minutes of manual work per cycle and the finance reconciliation delay. Estimated build time: 18 hours. Complexity: Moderate.
// Input (from Sync Agent completion or Google Sheets read)
sku_id: string
new_quantity: integer
event_type: 'order' | 'return' | 'po_receipt'
quantity_delta: integer
timestamp: ISO8601 string
reorder_threshold: integer // read from Sheets reference tab by sku_id lookup
unit_cost: number // read from Sheets reference tab for Xero journal value
// Decision
if new_quantity <= reorder_threshold: fire Slack alert
// Output: Slack alert (conditional)
slack_message: {
channel: '#buying-team',
text: 'Low stock alert: [SKU name] is at [new_quantity] units (reorder point: [reorder_threshold]). Please raise a PO.'
}
// Output: Xero journal entry (always)
xero_manual_journal: {
narration: 'Inventory movement: [sku_id] | [event_type] | [timestamp]',
journal_lines: [
{ account_code: '630', description: 'Inventory asset adjustment', line_amount: quantity_delta * unit_cost },
{ account_code: '310', description: 'COGS offset', line_amount: -(quantity_delta * unit_cost) }
]
}- Reorder thresholds must be populated per SKU in the Google Sheets reference tab before this agent can produce correct alerts. An initial data-entry session to populate those values is a prerequisite for go-live. SKUs with no threshold set should be logged and skipped, not errored.
- Xero API uses OAuth 2.0 with a 30-minute access token and a 60-day refresh token. The orchestration layer must handle token refresh automatically. Confirm the Xero organisation ID and the target account codes (inventory asset and COGS) with the finance manager before build.
- Slack integration requires a Slack App with the chat:write OAuth scope installed to the workspace. Confirm the buying team channel name or channel ID before build. Do not hard-code a channel name; store it as a configurable environment variable.
- Unit cost per SKU is required to calculate the Xero journal line amount. Confirm where this value is stored: the recommended approach is a column in the Google Sheets reference tab alongside the reorder threshold. If unit costs are held in Linnworks or Xero itself, an additional API read must be scoped into the build.
- Xero manual journal posts are permanent and cannot be deleted via the API. Ensure the quantity delta and unit cost values are validated before the journal write step. Implement a dry-run logging mode during testing so journal entries are logged but not posted until QA sign-off.
- The Slack alert must include a direct link or reference to the Google Sheets audit row so the buying team can review the triggering event without contacting fulfilment. Confirm the Sheet URL structure and whether the team has read access to the sheet.
03End-to-end data flow
// ─── TRIGGER ───────────────────────────────────────────────────────────────
// Source: Shopify order webhook, Amazon SP-API order feed, or Linnworks event
//
incoming_event {
event_type: 'order' | 'return' | 'po_receipt'
source_channel: 'shopify' | 'amazon' | 'linnworks'
sku_id: string // e.g. 'SKU-00142'
quantity_delta: integer // e.g. -2 for a 2-unit order, +1 for a return
order_id: string // Shopify order ID, Amazon order ID, or LW PO ref
event_timestamp: ISO8601 string
}
// ─── STOCK LEVEL SYNC AGENT: Step 1 — Pull current stock from Linnworks ──
// GET /api/v1/stock/items?sku={sku_id}
linnworks_response {
sku_id: string
stock_item_id: string // Linnworks internal GUID
stock_on_hand: integer // e.g. 47
location_id: string // warehouse location GUID
bin_rack: string
}
// ─── STOCK LEVEL SYNC AGENT: Step 2 — Calculate new quantity ────────────
new_quantity = linnworks_response.stock_on_hand + incoming_event.quantity_delta
// e.g. 47 + (-2) = 45
// ─── DECISION: Quantity valid? ───────────────────────────────────────────
if new_quantity < 0:
anomaly_record {
sku_id: incoming_event.sku_id
calculated_quantity: new_quantity
trigger_event: incoming_event.event_type
source_channel: incoming_event.source_channel
order_id: incoming_event.order_id
flagged_at: ISO8601 timestamp
}
// Post anomaly alert to Slack #fulfilment-alerts
// Halt all channel updates for this SKU — do NOT continue
STOP
// ─── STOCK LEVEL SYNC AGENT: Step 3 — Update Shopify ───────────────────
// POST /admin/api/2024-01/inventory_levels/set.json
shopify_request {
inventory_item_id: string // from Shopify product variant lookup by sku_id
location_id: string // Shopify fulfilment location ID
available: new_quantity
}
shopify_response {
inventory_level.available: integer // confirmed new quantity
updated_at: ISO8601 string
}
// ─── STOCK LEVEL SYNC AGENT: Step 4 — Update Amazon Seller Central ──────
// PUT /listings/2021-08-01/items/{sellerId}/{sku_id}
amazon_request {
seller_sku: incoming_event.sku_id
quantity: new_quantity
fulfillment_latency: 1 // days
}
amazon_response {
status: 'ACCEPTED' | 'INVALID'
submission_id: string
}
// Note: Amazon listing visibility lags 2-5 min after ACCEPTED status
// ─── STOCK LEVEL SYNC AGENT: Step 5 — Write audit row to Google Sheets ──
// POST spreadsheets/{sheet_id}/values/{range}:append
sheets_row {
timestamp: ISO8601 string
sku_id: string
event_type: incoming_event.event_type
source_channel: incoming_event.source_channel
prev_quantity: linnworks_response.stock_on_hand
new_quantity: new_quantity
order_id: incoming_event.order_id
shopify_status: 'updated' | 'skipped'
amazon_status: amazon_response.status
}
// ─── AGENT HANDOFF: Stock Level Sync Agent -> Reorder Alert and Finance Sync Agent
// Handoff payload is the completed sheets_row plus reorder_threshold lookup
// ─── REORDER ALERT AND FINANCE SYNC AGENT: Step 6 — Read threshold ──────
// GET spreadsheets/{sheet_id}/values/thresholds!A:D
threshold_lookup {
sku_id: string
reorder_threshold: integer // e.g. 10
unit_cost: number // e.g. 8.50
sku_name: string // human-readable label for Slack message
}
// ─── REORDER ALERT AND FINANCE SYNC AGENT: Step 7 — Conditional Slack alert
if new_quantity <= threshold_lookup.reorder_threshold:
// POST https://slack.com/api/chat.postMessage
slack_payload {
channel: env.BUYING_TEAM_CHANNEL_ID
text: 'Low stock: {sku_name} | Current: {new_quantity} units | Reorder point: {reorder_threshold} | Ref: {order_id}'
blocks: [ rich_text_block with SKU detail and Sheet deep-link ]
}
// ─── REORDER ALERT AND FINANCE SYNC AGENT: Step 8 — Post to Xero ────────
// POST https://api.xero.com/api.xro/2.0/ManualJournals
xero_payload {
narration: 'Inventory movement: {sku_id} | {event_type} | {ISO8601 timestamp}'
journal_lines: [
{
account_code: '630', // Inventory Asset
description: 'Stock adjustment: {sku_id}',
line_amount: quantity_delta * threshold_lookup.unit_cost
},
{
account_code: '310', // COGS
description: 'COGS offset: {sku_id}',
line_amount: -(quantity_delta * threshold_lookup.unit_cost)
}
]
}
xero_response {
manual_journal_id: UUID
status: 'DRAFT' | 'POSTED'
}
// ─── END OF FLOW ─────────────────────────────────────────────────────────
// All updates complete. Audit row in Google Sheets serves as the single
// reconciliation record linking event_type, channel, quantity, and Xero ref.04Recommended build stack
More documents for this process
Every document generated for Multichannel Inventory Sync.