ml-connector
AcumaticaShipBob

Acumatica and ShipBob integration

Acumatica Cloud ERP runs orders, inventory, and finance. ShipBob runs e-commerce pick, pack, and ship across distributed fulfillment centers. Connecting the two sends released Acumatica sales orders to ShipBob for fulfillment and brings the shipping result back into the ERP. Stock items sync to the ShipBob catalog by SKU, ShipBob shipment tracking and on-hand inventory post into Acumatica, and fulfillment charges are recorded against the right accounts. ml-connector handles the very different APIs on each side and moves the data on a schedule you control plus the ShipBob webhooks you enable.

How Acumatica works

Acumatica Cloud ERP exposes sales orders, stock and non-stock items, inventory, customers, vendors, and bills through its contract-based REST API, a JSON-over-HTTPS interface served from a tenant-specific URL where the endpoint version in the path must match the running ERP release exactly. All field values are wrapped in value objects, and entity names are case sensitive. It authenticates with OAuth 2.0 through the built-in OpenID Connect server or with a legacy session cookie. Acumatica can push outbound events from its Push Notifications screen, but those use a shared-secret header rather than a signed payload, so most connectors read changes by polling on the LastModifiedDateTime filter.

How ShipBob works

ShipBob exposes orders, products, inventory levels, shipments, warehouse receiving orders, returns, and billing through the ShipBob Developer API, a REST interface over JSON. It authenticates with OAuth 2.0 authorization code or a personal access token, and every write call must carry the shipbob_channel_id header that identifies the acting application channel. Listing endpoints page with a next-page response header rather than a body cursor, weights are in ounces and dimensions in inches, and shipping cost sits at invoice_amount inside the shipment object rather than at the top level of the order. ShipBob pushes events such as order.shipped and order.shipment.delivered by webhook, signed with HMAC-SHA256.

What moves between them

The primary flow runs from Acumatica into ShipBob. When a sales order is released in Acumatica, ml-connector creates the matching ShipBob fulfillment order with the recipient address and line items keyed by SKU, and it syncs Acumatica stock items into the ShipBob product catalog so those SKUs resolve. The return flow runs from ShipBob into Acumatica: shipment tracking numbers and carrier status post back onto the originating order, on-hand inventory counts per fulfillment center update Acumatica stock levels, and ShipBob fulfillment charges are written as Acumatica bills. Shipment and delivery events arrive by ShipBob webhook so tracking updates near real time, while inventory and billing sync on a schedule you set.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Acumatica side it runs OAuth 2.0 against the customer instance URL and pins the endpoint version, since a version mismatch returns HTTP 404, and it wraps every field value in the required value object. On the ShipBob side it holds the OAuth token, refreshes it on the one-hour expiry, and attaches the shipbob_channel_id header to every call so writes are accepted. Products are mapped first by SKU so each Acumatica order line resolves to a ShipBob product before the order is created, and addresses and units are converted, with weights sent in ounces and dimensions in inches. ShipBob shipped and delivered webhooks are verified by recomputing the HMAC-SHA256 over the webhook id, timestamp, and raw body before processing. Because Acumatica push notifications are not guaranteed and ShipBob exposes no idempotency key, ml-connector checks the ShipBob reference_id before creating an order to avoid duplicates and polls on LastModifiedDateTime as a catch-up. Acumatica throttles at HTTP 429 by license tier and ShipBob signals headroom through X-RateLimit-Remaining, so ml-connector backs off, retries, and keeps a full audit trail with error replay on every record.

A real-world example

A direct-to-consumer brand doing a few thousand orders a month runs Acumatica Cloud ERP for inventory, finance, and order management, and outsources warehousing to ShipBob across two fulfillment centers. Before the integration, staff exported released orders from Acumatica into a spreadsheet and re-keyed them into ShipBob each morning, then pasted tracking numbers back by hand and reconciled the ShipBob invoice against Acumatica at month-end. With Acumatica and ShipBob connected, each released order flows to ShipBob automatically, tracking and delivery status post back to the ERP as shipments leave, inventory stays aligned across both fulfillment centers, and the fulfillment charges arrive as bills. The morning re-keying and the manual tracking paste are gone, and close starts from reconciled fulfillment costs.

What you can do

  • Create ShipBob fulfillment orders from released Acumatica sales orders, with recipient address and SKU-keyed line items.
  • Sync Acumatica stock items into the ShipBob product catalog by SKU so order lines resolve to a fulfillment product.
  • Post ShipBob shipment tracking and carrier status back onto the originating Acumatica order as each shipment leaves.
  • Update Acumatica inventory from ShipBob on-hand levels per fulfillment center and record ShipBob fulfillment charges as bills.
  • Authenticate Acumatica with version-pinned OAuth 2.0 and ShipBob with OAuth plus the required shipbob_channel_id header.

Questions

Which direction does data move between Acumatica and ShipBob?
Orders and products move from Acumatica into ShipBob: released sales orders become ShipBob fulfillment orders, and stock items sync to the ShipBob catalog by SKU. Shipment tracking, on-hand inventory per fulfillment center, and fulfillment charges move from ShipBob back into Acumatica. Acumatica stays the system of record for the order and the financials while ShipBob owns the physical fulfillment.
How does the integration keep Acumatica and ShipBob in sync without missing events?
ShipBob pushes shipped and delivered events by webhook, signed with HMAC-SHA256, which ml-connector verifies before posting tracking back to Acumatica. Acumatica push notifications are not guaranteed and use a shared-secret header rather than a signed payload, so ml-connector also polls on the LastModifiedDateTime filter to catch released orders. Every record carries a full audit trail and can be replayed if a downstream call fails.
How are duplicate ShipBob orders avoided when an Acumatica order syncs more than once?
Neither API offers an idempotency key, so ml-connector uses the merchant-controlled reference_id on ShipBob orders as an external key. It checks for an existing order by reference_id before creating a new one, which prevents a re-run or a retried request from submitting the same Acumatica order to ShipBob twice. The shipbob_channel_id header is attached to every write so those creates are accepted.

Related integrations

Connect Acumatica and ShipBob

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

Get started