API Integration · Logistics

Crest
Supply Co.

An outdoor gear brand switched to Saddle Creek Logistics for better warehouse capacity. Problem: Saddle Creek has no Shopify app. Orders were being manually exported as CSVs four times a day. We replaced it with a live webhook connector and cut fulfillment lag from 6 hours to 4 minutes.

Client
Crest Supply Co.
Year
2025
Type
API Integration
Stack
Node.js · Shopify Webhooks · Saddle Creek API · Inngest · PostgreSQL
Timeline
5 weeks
01 — The Problem

No App. No Integration.
Just Spreadsheets.

Crest Supply Co. sells outdoor and climbing gear through Shopify. After outgrowing their previous 3PL, they moved to Saddle Creek Logistics — a Tennessee-based fulfillment partner with 30+ warehouse facilities and the capacity to handle their growth. What Saddle Creek doesn't have is a Shopify app.

Their operations manager was manually exporting orders from Shopify as CSV files and uploading them to Saddle Creek's supplier portal four times a day — at 8am, 12pm, 4pm, and 8pm. Orders placed between uploads sat unfulfilled. Inventory levels were updated nightly at best. Returns were tracked in a separate spreadsheet that no one fully trusted.

Up to 6-hour fulfillment lag

Orders placed at 12:01pm didn't reach the warehouse until the 4pm upload — two hours before the daily cut-off.

4× daily manual exports

The ops manager's entire morning was structured around being available for the 8am and 12pm CSV uploads.

Stale inventory on Shopify

Stock levels updated once per night. Products oversold regularly — especially during promotions when Saddle Creek processed returns faster than the nightly sync.

Returns in a spreadsheet

Returns data lived in a separate sheet no one maintained consistently. Refunds were processed days late.

Core insight

Saddle Creek has a fully capable REST API. The missing piece wasn't technical capability — it was the connector between Shopify's event stream and Saddle Creek's API surface. Build that connector with proper queuing and error handling, and the CSV process disappears entirely.

02 — The Approach

Four Principles
That Shaped the Build.

01

Write first, process second

Every webhook payload is persisted to PostgreSQL before any transformation or dispatch happens. If the downstream processing fails, the raw event is never lost — it can always be replayed from the events table.

→ This pattern was the deciding factor when an Inngest outage occurred three weeks post-launch. Every order during the outage was replayed cleanly from the events table with zero data loss.
02

Idempotency by design

Shopify can fire the same webhook multiple times. Saddle Creek's API will create a duplicate order if it receives the same payload twice. Every dispatch uses an idempotency key derived from the Shopify order ID and event type — duplicate payloads are no-ops.

→ Shopify fired duplicate order/create webhooks on 12 orders in the first month. All 12 were silently de-duplicated with no double-fulfillment.
03

Alert on real failures, not on noise

Transient API errors (rate limits, timeouts) are retried automatically by Inngest. Only orders that exhaust all retries reach the Slack alert channel. The ops team gets paged on real problems — not on every 429 that resolves itself.

→ In six months post-launch, the alert channel has fired 4 times — all genuine Saddle Creek API outages, all resolved within 30 minutes.
04

SKU mapping as a first-class concern

Shopify variant IDs and Saddle Creek SKUs are completely different namespaces. The mapping table is managed by the ops team in Retool — no developer involvement to add new products or update SKU codes after a rebranding.

→ When Crest relaunched their rope line with new SKUs three months after go-live, the ops manager updated the mapping table in Retool in ten minutes without touching any code.
03 — How It Works

Inside the
Connector.

01

Order webhook

Shopify fires a signed HMAC webhook on orders/create, orders/updated, and orders/cancelled. The handler verifies the signature on receipt — replayed or tampered requests are rejected immediately. The raw payload is written to a PostgreSQL events table before any processing begins, creating an immutable record of every order event.

Shopify WebhooksHMAC verificationPostgreSQL
02

Schema translation

Shopify's order schema and Saddle Creek's API format have almost nothing in common — different address field names, different carrier codes, different SKU identifiers. A transformation layer maps every field, normalises UK/US address formats, translates Shopify shipping method names to Saddle Creek carrier preferences, and converts Shopify variant IDs to Crest's 3PL SKUs using a maintained mapping table.

Node.jsSKU mapping tableAddress normalisation
03

Queue and dispatch

Transformed orders are enqueued via Inngest before dispatch to Saddle Creek's API. Inngest provides automatic retry with exponential backoff, dead-letter handling for permanently failed orders, and a full execution timeline per order. Failed orders surface in a Slack alert with the error and the original Shopify order ID — no silent failures.

InngestSaddle Creek APISlack alerts
04

Inventory sync

A scheduled job runs every 15 minutes, pulling current stock levels from Saddle Creek's inventory endpoint and writing them back to Shopify via the Inventory API. This replaces the previous nightly spreadsheet export — inventory on the Shopify storefront is now within 15 minutes of the warehouse's actual count.

Saddle Creek Inventory APIShopify Inventory APIVercel Cron
05

Returns flow

When Saddle Creek processes a return, a webhook fires to the same handler. The return event is matched to the original Shopify order, the refund is initiated via Shopify's Refund API, and the inventory adjustment is applied. Returns that can't be matched automatically are flagged for manual review in a Retool dashboard used by the ops team.

Saddle Creek Returns APIShopify Refund APIRetool
06

Audit and observability

Every order event, API call, retry, and status change is logged to PostgreSQL with timestamps. The ops team has a Retool dashboard showing real-time order pipeline status, any stuck orders, and a 30-day error rate trend. The accounting team gets a weekly export of the full event log — required for seven-year financial record retention.

PostgreSQLRetoolVercel
04 — Results

Numbers Worth
Shipping For.

<4min
Fulfillment lag (was up to 6 hours)
99.8%
Inventory accuracy (was 94%)
0
CSV uploads since launch
0
Lost orders in 6 months
05 — Key Decisions

Calls Worth
Explaining.

Inngest
over Bull / Redis queue
benefitInngest is Vercel-native and requires no Redis infrastructure. It provides built-in replay, a visual execution timeline per job, and dead-letter handling out of the box. Debugging a failed order means clicking into the Inngest dashboard — not tailing logs.
tradeoffVendor dependency. If Inngest has an outage, the queue pauses. The write-first PostgreSQL pattern mitigates this — events can always be replayed — but it adds operational surface area.
PostgreSQL audit log
over application logging only
benefitCrest's accountants require seven years of order event history for financial reporting. Application logs rotate. PostgreSQL rows don't unless you explicitly delete them. The audit table is the authoritative record for both engineering and finance.
tradeoffTable grows indefinitely. At current order volume, it adds roughly 2GB/year. A partitioning strategy will be needed at scale — deferred for now but documented in the runbook.
15-minute inventory sync
over real-time push
benefitSaddle Creek's inventory API doesn't support webhooks — only polling. 15 minutes was the shortest interval that stayed within their API rate limits across all of Crest's SKUs without risking throttling during peak periods.
tradeoff15-minute staleness window. During a flash sale, this is long enough to oversell a low-stock item. A safety buffer is applied to inventory counts for products below 10 units to compensate.