ml-connector
QADHubSpot

QAD and HubSpot integration

QAD runs manufacturing, procurement, and finance. HubSpot runs the CRM and commerce side of the business. Connecting the two gives sales and operations one shared view of every customer and supplier. QAD customer and supplier accounts appear in HubSpot as companies, QAD items appear as HubSpot products, and HubSpot deals that close create matching sales orders in QAD without re-keying. ml-connector handles the very different APIs on each side and moves the data on a schedule you control.

How QAD works

QAD Adaptive ERP exposes customers, suppliers, items, purchase orders, supplier invoices, GL accounts, cost centers, and goods receipts through REST business document APIs, documented in Swagger inside each customer instance. The cloud product authenticates with a JWT session or OAuth2 bearer token against a tenant-specific URL, so there is no shared hostname and no public sandbox. Older on-premise sites run QAD Enterprise Edition with the QXtend SOAP framework instead. QAD has no webhook system for cloud connectors, so its records are read by polling on a schedule.

How HubSpot works

HubSpot exposes companies, contacts, deals, products, line items, invoices, orders, and payments as REST JSON objects under https://api.hubapi.com, with both legacy /crm/v3/ paths and date-versioned /crm/objects/2026-03/ paths active. Server-to-server access uses a Private App access token passed as a Bearer header, scoped per object, plus the numeric Hub ID. Reads are cursor-paginated with after and limit, and the batch upsert endpoint provides safe re-run behavior keyed on an external ID property. Webhooks exist but require a separate Public OAuth app, so a Private App connection reads by polling.

What moves between them

The main flow runs from QAD into HubSpot. ml-connector reads QAD customers and suppliers and writes them into HubSpot as companies, with key contacts created as HubSpot contacts associated to those companies, and it maps QAD items to HubSpot products so quotes and deals reference the real catalog. In the other direction, HubSpot deals that reach a closed-won stage are read and turned into sales orders in QAD, carrying the deal amount, currency, and line items. Reference data such as account identifiers is aligned in both directions so records match on a stable external key. Polling cadence is set per object to fit how often each side changes.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the HubSpot side it sends the Private App access token as a Bearer header and reads through cursor pagination using the after token and a limit up to 200. On the QAD side it accepts the full tenant URL per customer, since QAD publishes no shared base address, and validates entity paths against that instance. Because QAD cloud is pull-only and a HubSpot Private App cannot register webhooks, both systems are polled on a schedule rather than waiting for a push. Writes into HubSpot use the batch upsert endpoint keyed on a stable external ID so a re-run updates the existing company or product instead of creating duplicates, since HubSpot has no universal idempotency key. HubSpot returns HTTP 429 with a Retry-After header when a rate tier is exceeded, so ml-connector backs off and retries. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized industrial equipment manufacturer runs QAD Adaptive ERP for production, procurement, and finance, and its sales team works deals in HubSpot. Before the integration, reps created accounts in HubSpot by hand while operations kept the same customers in QAD, so names, addresses, and product catalogs drifted apart and a closed deal had to be re-entered as a QAD sales order by an order desk. With QAD and HubSpot connected, customer and supplier accounts flow into HubSpot as companies, the QAD item list shows up as HubSpot products, and a closed-won deal becomes a QAD sales order automatically. Sales and operations work from the same accounts, and the manual order re-entry step is gone.

What you can do

  • Write QAD customers and suppliers into HubSpot as companies, with key people created as associated contacts.
  • Map QAD items to HubSpot products so deals and quotes reference the real catalog.
  • Turn closed-won HubSpot deals into QAD sales orders with amount, currency, and line items.
  • Authenticate HubSpot with a Private App Bearer token and QAD with its tenant-specific session.
  • Poll both sides on a per-object schedule, with upsert dedup, retries, and a full audit trail.

Questions

Which direction does data move between QAD and HubSpot?
The main flow is QAD into HubSpot. Customers, suppliers, and items move from QAD into HubSpot as companies, contacts, and products. In the other direction, HubSpot deals that reach closed-won are read and written into QAD as sales orders, so each system holds the records it owns.
Does the integration use HubSpot webhooks?
No. HubSpot webhooks can only be configured on a Public OAuth app, not the Private App used for server-to-server token access. ml-connector reads HubSpot by polling on a schedule using cursor pagination, which also matches QAD cloud, since QAD has no push notifications for connectors.
How does ml-connector avoid creating duplicate records in HubSpot?
HubSpot has no universal idempotency key for standard writes, so ml-connector uses the batch upsert endpoint keyed on a stable external ID property carried from QAD. On a re-run the matching company or product is updated rather than duplicated. Rate limit responses return HTTP 429 with a Retry-After header, which ml-connector honors before retrying.

Related integrations

Connect QAD and HubSpot

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

Get started