Cin7–Shopify Replenishment Integration: Automating Purchase Order Drafts from Live Data

Cin7-Shopify Replenishment Integration

Most merchants don't realize they have a replenishment problem until it's already a stockout. By the time someone opens a spreadsheet, emails the supplier, and manually keys in quantities, the window to reorder has closed. We've seen this pattern repeatedly with mid-market brands running Shopify on the front end and Cin7 in the back: the data is all there, but the systems aren't talking. The fix isn't magic. It's a proper integration.

How Cin7 and Shopify Actually Exchange Data

Cin7 exposes a REST API with endpoints for inventory levels, purchase orders, suppliers, and products. Shopify has its own Admin API covering orders, variants, and location-level inventory. Neither system natively syncs with the other. That's the gap most teams try to paper over with manual exports or third-party middleware.

For replenishment automation, you're primarily pulling two data sets: inventory on hand from Cin7 (GET /inventory per SKU and location) and order velocity from Shopify (GET /orders filtered by created-at range and status). Together, those two feeds give you the inputs for a reorder calculation: current stock minus in-transit, divided by average daily units sold, gives you days of cover. When days of cover drops below your threshold, you have a trigger.

The integration architecture matters here. A direct API bridge that polls both systems on a schedule works, but it introduces lag. If you're running a busy Shopify store during a promotional window, a 15-minute polling cycle can mean the difference between catching a threshold breach and missing it. Event-driven is better. Shopify webhooks fire on orders/paid in near-real-time; that event can immediately recalculate days of cover and check against the Cin7 reorder point.

What Automated PO Draft Generation Looks Like in Practice

When the reorder trigger fires, the system doesn't just flag a SKU. It builds a draft purchase order using data that already lives in Cin7. Vendor details pull from the supplier record attached to that product: trading name, payment terms, currency, delivery address. SKU quantities calculate from the difference between current stock and target stock level, adjusted for any existing open POs that haven't been received yet. Target receipt dates derive from the supplier's lead time field in Cin7, offset from today.

The draft PO lands in Cin7's purchase order queue, status: draft. No manual data entry. The purchasing team opens it, reviews the quantities, adjusts if there's a reason to (a supplier is out of stock, a product is being discontinued), and approves with one click. That approval triggers Cin7 to send the PO to the supplier via email or EDI depending on how the supplier relationship is configured.

In our experience, teams that run this process see PO creation time drop from roughly 25 minutes per order to under 2 minutes. The manual work shifts from data entry to decision-making. That's the right direction.

The value isn't in removing humans from the loop. It's in making sure humans only touch the decisions that actually require judgment, not the ones that are just data transcription.

Batch vs. Event-Driven: What Breaks When You Get It Wrong

Here's the thing: batch integration sounds fine until you're in a flash sale. Batch systems run on a schedule, often nightly or every few hours. That means:

  • Inventory counts in Cin7 are stale when you check them mid-day
  • Order velocity data from Shopify lags by up to the full batch interval
  • Threshold breaches detected at midnight trigger POs that were needed at noon
  • You build in safety stock to compensate for the lag, which ties up cash

Event-driven integration eliminates most of this. When Shopify fires an orders/paid webhook, your integration layer processes it immediately, recalculates days of cover with current Cin7 inventory, and queues a PO draft if warranted. The whole loop runs in under 30 seconds. Critically, it also means you're not double-drafting: if three orders fire in quick succession, the system checks for an existing open PO for that SKU before creating a new one.

Batch still has a place. Nightly reconciliation runs to catch discrepancies, validate that all received POs updated inventory correctly, and flag anomalies. Think of batch as the audit layer, and event-driven as the operational layer. Running both is not redundant. It's thorough.

Implementation Gotchas Worth Knowing Upfront

Cin7's API rate limits are documented as 100 requests per minute per API key. That ceiling is tight if you're syncing multiple locations, running a reconciliation job, and processing webhook events simultaneously. We've found that batching inventory reads (pull all SKUs in one call using the ?includeVariants=true parameter) rather than querying per-SKU drops your request count by a factor of 10 or more on a typical catalog. This matters especially during high-traffic periods when Shopify webhooks are firing rapidly.

SKU mapping between systems is the other major pain point. Shopify variant SKUs and Cin7 product codes often diverge over time. Merchants add products through different channels, use different conventions, or have legacy data from migrations. Before you build any automation, audit your SKU overlap. In practice, a mid-market catalog of around 500 SKUs typically has 5-15% mismatches on first sync. Those mismatches need to be resolved manually or via a mapping table before automated POs can be trusted.

A few other gotchas we've run into:

  • Multi-location inventory: Cin7 tracks stock by location. If you fulfill from multiple warehouses, your reorder calculation needs to aggregate correctly or you'll trigger orders for warehouses that have plenty of stock.
  • Pending vs. paid orders: Only pull Shopify order data with financial_status=paid for velocity calculations. Pending orders skew your consumption rate and can cause premature reorder triggers.
  • Supplier minimums: Cin7 stores supplier minimum order quantities. Your PO draft logic must respect these. A system that drafts a PO for 12 units when the supplier minimum is 50 creates more work than it saves.

What a Production-Grade Implementation Covers

A minimal proof of concept connects the two APIs and triggers POs. A production-grade integration handles the messy cases:

Idempotency: if your webhook processor receives the same event twice (Shopify delivers at-least-once), it should not create duplicate POs. This requires storing event IDs and checking before processing.

Retry logic: both APIs return transient errors under load. Your integration needs exponential backoff on 429 responses from Cin7 and 503s from Shopify. Without this, you get silent failures during your busiest periods.

Alerting: when a PO draft fails to create because of missing supplier data or a SKU mismatch, someone needs to know immediately. Not the next morning. A Slack notification or email alert with the affected SKU and failure reason takes 30 minutes to set up and saves hours of hunting down missed orders.

Honestly, most teams underinvest in the error handling and pay for it later. The happy path is easy. The edge cases are where integrations earn their keep.

Takeaways

Getting Cin7 and Shopify to cooperate on replenishment is not a turnkey project, but it's also not a six-month engagement. The core mechanics are well-defined: webhook trigger, inventory calculation, PO draft construction from existing supplier records, one-click approval in Cin7. The complexity lives in the details: SKU mapping, rate limit management, idempotency, and multi-location handling.

Start with an audit of your SKU alignment between the two systems. That single step surfaces more than half the implementation risk. Then decide whether your replenishment cadence can tolerate batch latency or requires event-driven triggers. Most mid-market Shopify brands operating above 200 orders per day will want event-driven. Below that, a well-built batch job running every two hours is probably enough.

The goal is a purchasing workflow where your team reviews and approves, rather than building from scratch. That shift alone typically recovers 3 to 5 hours per week per buyer. On a team of two buyers, that's 300 to 500 hours a year redirected from data entry to supplier relationships and planning.

Worth doing. Definitely not magic. But definitely worth doing.