ml-connector
Exact OnlineGoogle BigQuery

Exact Online and Google BigQuery integration

Exact Online runs accounting, sales, and purchasing across your European operations. Google BigQuery is your cloud data warehouse. Connecting the two lets you load transactional data from Exact Online into BigQuery on a schedule, so your analytics and reporting always reflect the latest invoices, orders, and general ledger postings without manual export or spreadsheet re-entry. Data flows from Exact Online into BigQuery, where your BI tools and analytics engines can query it.

How Exact Online works

Exact Online exposes accounts, sales invoices and lines, purchase invoices and lines, purchase orders, GL accounts, cost centers, journal entries, transaction lines, items, contacts, employees, payments, receipts, and bank entries through a REST API with OData v3 query syntax, accessible at region-specific base URLs (/api/v1/{division}/). Authentication requires OAuth 2.0 Authorization Code Grant with an access token lifetime of 10 minutes and a refresh token lifetime of 30 days. Exact Online supports webhooks (push model) for a broad set of resources including accounts, invoices, orders, GL entries, and bank entries, with HMAC-SHA256 signature validation. Webhook payloads contain only the entity key and action (create/update/delete), so full entity data must be fetched separately via the REST API.

How Google BigQuery works

Google BigQuery is a fully-managed, serverless data warehouse that accepts structured records via a REST API at https://bigquery.googleapis.com/bigquery/v2. Authentication uses OAuth 2.0 Service Account (JWT Bearer flow), with access tokens valid for 3600 seconds. BigQuery has no native webhooks or event subscriptions; it is pull-only. Data is inserted via tabledata.insertAll with best-effort deduplication using insertId. BigQuery requires that the service account possess bigquery.dataEditor and bigquery.jobUser roles for read-write access. Storage Read API is preferred for large-volume reads.

What moves between them

Invoices, purchase orders, GL entries, and transaction lines flow from Exact Online into Google BigQuery. Exact Online webhooks notify ml-connector of changes (create, update, delete); ml-connector fetches the full entity data from Exact Online's REST API, transforms it to match your BigQuery table schema, and writes it into BigQuery on a schedule tied to your batch window or in real-time via webhook delivery. Cost centers and GL accounts are synced bidirectionally so that line items always reference valid dimensions in BigQuery. Change detection uses Exact Online's webhook topics and BigQuery's timestamp columns for tracking.

How ml-connector handles it

ml-connector stores your Exact Online OAuth credentials (client ID and secret) encrypted and refreshes the access token every 10 minutes before it expires, so calls never fail mid-flow due to token age. It subscribes to Exact Online's webhook topics per division (SalesInvoices, PurchaseOrders, TransactionLines, GLAccounts, etc.) and receives notifications via HTTP POST with HMAC-SHA256 validation to confirm authenticity. When a webhook arrives, ml-connector fetches the full entity from Exact Online's REST API using the OData query syntax, maps the data to your BigQuery table schema, and writes rows via tabledata.insertAll with a unique insertId for deduplication. For fields that require expansion (such as GL account or cost center details), ml-connector makes separate REST calls since Exact Online does not support the $expand parameter. Your BigQuery service account credentials are stored encrypted, and the JWT is signed fresh on each API call. The integration respects BigQuery's 1-hour access token lifetime and refreshes tokens as needed. Every record carries a full audit trail including the webhook event timestamp, the data fetched from Exact Online, the transformation applied, and the write outcome into BigQuery.

A real-world example

A mid-market professional services firm operates across the UK and Germany using Exact Online for invoicing, purchase orders, and GL accounting in each region. Finance uses Google BigQuery to aggregate data from multiple Exact Online divisions for consolidated reporting and analysis. Before the integration, the finance team manually exported invoices and GL entries from each Exact Online division every morning and loaded them into BigQuery via scripts, a process prone to delays and gaps if Exact Online was unavailable. With Exact Online and BigQuery connected, webhooks notify ml-connector of new invoices and GL postings as they occur, and they appear in BigQuery within minutes. Month-end reconciliation now starts with a complete and current picture, and the export-load cycle is gone.

What you can do

  • Sync sales and purchase invoices from Exact Online into BigQuery tables with full line-item detail and timestamp tracking.
  • Load GL account records and transaction lines into BigQuery so cost center and account dimension queries always reflect the current Exact Online chart of accounts.
  • Refresh Exact Online OAuth tokens automatically every 10 minutes before expiry so webhook subscriptions never stale.
  • Authenticate to Google BigQuery via service account JWT and insert records with deduplication via insertId to prevent duplicates on retry.
  • Subscribe to Exact Online webhook topics per division and fetch full entity data via OData REST API on each notification, transforming to match your BigQuery schema.

Questions

Does ml-connector handle Exact Online's per-division setup?
Yes. Exact Online requires a division ID for all API calls. ml-connector accepts the division ID per customer, subscribes to webhook topics for that division, and qualifies all REST API calls with the correct division. If you operate multiple Exact Online divisions, you can connect each one separately as a distinct flow.
How does ml-connector handle Exact Online's short 10-minute access token lifetime?
ml-connector caches the access token and refresh token encrypted, and it refreshes the access token every 10 minutes before expiry. This ensures webhook subscriptions stay active and API calls never fail due to a stale token. The refresh token itself lasts 30 days, and the user must re-authorize if it expires.
What happens if BigQuery's insertId deduplication fails?
BigQuery's tabledata.insertAll provides best-effort deduplication based on insertId within a 1-hour window. ml-connector generates a unique insertId for each record (typically derived from the Exact Online entity key and event timestamp). If a duplicate arrives outside the 1-hour window, it may be inserted twice; ml-connector tracks this in the audit log so you can identify and clean up duplicates in BigQuery if needed.

Related integrations

Connect Exact Online and Google BigQuery

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

Get started