QAD and Snowflake integration
QAD runs manufacturing and finance. Snowflake stores and queries data at scale but is not an ERP, so it holds no native invoices, suppliers, or GL accounts of its own. Connecting the two lands QAD's operational and financial records in Snowflake tables where reporting and analytics tools can reach them, and reconciled results can be read back out. ml-connector moves the data through Snowflake's SQL API using idempotent upserts, on a schedule you control. The very different APIs on each side, and the fact that neither pushes events, are handled for you.
What moves between them
The main flow runs from QAD into Snowflake. ml-connector reads QAD suppliers, purchase orders, supplier invoices, GL accounts, cost centers, items, goods receipts, AP payments, and customers, then writes each into its matching Snowflake table with a MERGE keyed on the QAD record ID. Line-item detail lands in VARIANT columns as JSON. The reverse direction is read-only against Snowflake: reconciled or analytics-prepared rows can be selected back out for downstream use, but ml-connector does not treat Snowflake as a finance source of record. Cadence is set per flow on a polling schedule, since neither QAD cloud nor Snowflake pushes change events.
How ml-connector handles it
ml-connector stores both credential sets encrypted. For Snowflake it signs a key-pair JWT on each request, valid for at most one hour, and presents it with the KEYPAIR_JWT token-type header; for QAD 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 Snowflake never pushes to connectors, both sides are polled on the schedule you set, and changed rows in Snowflake are detected with a Stream or an updated_at watermark. Writes use MERGE INTO keyed on the QAD ID so a replay never creates duplicate rows, and each POST carries a requestId UUID so Snowflake deduplicates a retried statement. QAD's three-way match is respected by syncing goods receipts before supplier invoices. The connector backs off with jitter on Snowflake HTTP 429 and 5xx responses, confirms the target warehouse has auto-resume on so queries do not fail while it is suspended, and tracks JWT and key rotation so credential expiry does not become an outage. Every record carries a full audit trail and can be replayed if a downstream call fails.
A real-world example
A mid-sized contract manufacturer runs QAD Adaptive ERP for procurement, production, and finance, and the analytics team wants spend and AP data in Snowflake alongside data from other systems. Before the integration, an analyst pulled QAD reports by hand and loaded CSV extracts into the warehouse on an irregular basis, so dashboards were always a few days stale and supplier spend never tied back cleanly to the ledger. With QAD and Snowflake connected, suppliers, purchase orders, supplier invoices, and GL data land in warehouse tables on a set schedule through idempotent upserts. The analytics team builds on current data, and the manual export and load step is gone.
What you can do
- Land QAD suppliers, purchase orders, supplier invoices, GL accounts, and cost centers in Snowflake tables on a schedule.
- Write with idempotent MERGE upserts keyed on the QAD record ID so replays never create duplicate rows.
- Read reconciled or analytics-prepared rows back out of Snowflake without treating it as a finance source of record.
- Authenticate Snowflake with key-pair JWT and QAD with its tenant-specific token, both stored encrypted.
- Poll both systems because neither pushes events, with backoff on 429, a requestId per call, and a full audit trail.
Questions
- Which direction does data move between QAD and Snowflake?
- The main flow is QAD into Snowflake. Suppliers, purchase orders, supplier invoices, GL accounts, cost centers, and related records are read from QAD and written into Snowflake tables. The reverse direction is read-only: ml-connector can select reconciled rows back out of Snowflake, but it does not write financial records into QAD from the warehouse.
- How does ml-connector avoid duplicate rows when it retries a write?
- Writes use Snowflake MERGE INTO statements keyed on the QAD record ID, so a record that already exists is updated rather than inserted again. Each POST to the SQL API also carries a requestId UUID, which Snowflake uses to deduplicate a retried statement. Together these make a replay after a network failure safe.
- Does Snowflake push changes to ml-connector, or does it poll?
- Snowflake does not push events to external connectors; its outbound notifications only reach Slack, Teams, and PagerDuty. So ml-connector polls Snowflake on the schedule you set. To pick up only changed rows it uses a Snowflake Stream for change data capture or an updated_at watermark on the target tables.
Related integrations
More QAD integrations
Other systems that connect to Snowflake
Connect QAD and Snowflake
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started