ml-connector
Sage 50ShipBob

Sage 50 and ShipBob integration

Sage 50 manages your accounting and GL; ShipBob manages your warehouse and fulfillment. When you store inventory at ShipBob's fulfillment centers, you need your cost of goods and inventory balances in Sage 50 to match what is actually in the warehouse. ml-connector bridges the two by reading ShipBob's shipment and receiving events and posting the corresponding inventory adjustments back into Sage 50's general ledger and inventory register. This keeps your balance sheet accurate without manual hand-offs between fulfillment and finance.

How Sage 50 works

Sage 50 is a desktop-installed accounting application available in US and UK editions. It exposes vendors, customers, purchase and sales orders, invoices, payments, receipts, GL accounts, employees, inventory items, and journal entries through a local Windows SDK: the .NET SDK for the US edition or Sage Data Objects (SDO) COM/ActiveX DLLs for the UK edition. The integration reads from the local company data files using Windows credentials and the application ID, and must run on a Windows machine with Sage 50 installed and direct LAN or local disk access to the company folder. Sage 50 offers no webhooks or remote API, so the integration polls the modified records by LastModifiedDate or enumerates the audit trail by date range. Because the integration requires exclusive access to the Sage 50 user account, no interactive user can be logged in while the SDK session is open.

How ShipBob works

ShipBob is a cloud fulfillment platform accessed via REST API at https://api.shipbob.com with a /2026-01/ version prefix. It exposes orders, shipments, products, inventory, warehouse receiving orders, returns, and billing through REST endpoints and webhooks. Authentication uses OAuth2 (with one-hour access tokens and 30-day refresh tokens) or Personal Access Tokens, with all calls requiring the Authorization Bearer header and the shipbob_channel_id header to identify the application channel. ShipBob pushes real-time events to registered webhook endpoints for order.shipped, order.shipment.tracking.updated, order.shipment.delivered, return.created, return.updated, wro.created, wro.updated, and billing charges and credits. Webhook payloads are signed with HMAC-SHA256 using v1 envelope format and the headers webhook-id, webhook-timestamp, and webhook-signature.

What moves between them

The main flow runs from ShipBob into Sage 50. As orders ship and inventory is received at ShipBob fulfillment centers, ml-connector reads the shipment and receiving events from ShipBob webhooks, maps them to the corresponding customers and inventory items in Sage 50, and posts inventory adjustments to the GL to reflect the movement out of or into the warehouse. The integration can also read historical shipment and receiving data from ShipBob REST endpoints to backfill Sage 50 and establish a baseline. Reference data such as customers, products, and locations are maintained in both systems so each fulfillment movement posts to the correct GL account and inventory line.

How ml-connector handles it

ml-connector stores the ShipBob OAuth token or Personal Access Token encrypted and uses the shipbob_channel_id header on every call to identify itself as the authorized integration channel. It registers a webhook endpoint to receive ShipBob push events for shipments, returns, and warehouse receiving orders in real time, and validates each webhook signature using HMAC-SHA256 before processing. On the Sage 50 side, ml-connector uses the local Windows SDK with the company path, application ID, and local account credentials to open a session with the company data. Because Sage 50 requires exclusive access, the integration session must not overlap with any interactive login, and it queries by LastModifiedDate or audit trail to find new transactions. When a ShipBob shipment event arrives, ml-connector maps the order to the Sage 50 customer and inventory items, computes the GL impact (cost of goods, inventory offset), and posts a journal entry into the GL dated on the shipment date. Warehouse receiving orders flow the same way, posting inventory receipts. The integration handles ShipBob token refresh automatically and retries on transient failures, carrying a full audit trail of every inventory movement and GL posting so that out-of-sync records can be identified and corrected.

A real-world example

A mid-sized e-commerce retailer stores inventory at a ShipBob fulfillment center and uses Sage 50 US edition for accounting and cost tracking. Before the integration, the fulfillment team shipped orders daily, but the inventory balances in Sage 50 were updated manually at the end of each week based on a spreadsheet export from ShipBob. This created a lag: the GL showed inventory that had already shipped, reconciliation took hours, and the finance team could not trust month-end inventory counts. With Sage 50 and ShipBob connected, each shipment triggers an automatic inventory reduction and COGS entry in the GL, posted the same day. The warehouse receiving process for new stock sends a receiving order event to Sage 50, automatically posting the cost and crediting the payable account. At month-end, inventory and cost of goods are already aligned, and reconciliation is a quick verification rather than a data-entry session.

What you can do

  • Post shipment events from ShipBob into Sage 50 as automatic inventory reductions and COGS entries in the general ledger.
  • Sync warehouse receiving orders from ShipBob into Sage 50 inventory receipts and purchase posting.
  • Map ShipBob orders and products to Sage 50 customers and inventory items so fulfillment posts to the correct GL accounts.
  • Authenticate ShipBob via OAuth2 or Personal Access Token and Sage 50 via the local Windows SDK, handling token refresh and exclusive access.
  • Receive ShipBob webhook events in real time, validate signatures, and replay failed GL postings with a full audit trail.

Questions

How does ml-connector handle Sage 50's exclusive access requirement?
Sage 50's SDK requires that no interactive user be logged into the application while the integration is reading or writing. ml-connector manages this by acquiring a session lock before opening the SDK connection, checking that no desktop session is active, and releasing the lock immediately after the transaction completes. If a user logs in interactively while a transaction is in progress, the integration pauses and retries on the next polling cycle. The integration operator must ensure that scheduled sync windows do not overlap with normal accounting work hours.
Which ShipBob events trigger Sage 50 GL postings?
order.shipped and order.shipment.delivered events trigger inventory reduction and COGS postings. warehouse receiving order (wro.created, wro.updated, wro.completed) events trigger inventory receipts and payable postings. return.created and return.updated events trigger inventory increases and adjustment GL entries. order.shipment.line_item.added and removed events trigger adjustments if the shipment is modified after the initial posting. ml-connector processes each event once and marks it as posted to avoid duplicate GL entries.
Can ml-connector sync historical shipments and receiving from ShipBob into Sage 50?
Yes. ml-connector can read historical shipment and receiving order data from ShipBob REST endpoints using pagination and date filters, then post them retroactively into Sage 50. This is useful when enabling the integration for the first time or recovering from a gap in webhook delivery. Historical postings are dated on the original transaction date in ShipBob, and ml-connector includes a reference to the ShipBob shipment or receiving order ID in the Sage 50 GL memo field to prevent duplicates if the transaction is encountered again via webhooks.

Related integrations

Connect Sage 50 and ShipBob

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started