ml-connector
Exact OnlineBILL

Exact Online and BILL integration

Exact Online runs your general ledger and purchase orders. BILL manages your accounts payable and vendor payments. Connecting the two ensures your GL accounts and cost centers in Exact Online align with BILL's chart of accounts, and bills created in BILL post into Exact Online's journal without manual re-entry. ml-connector bridges the different authentication models and keeps both systems synchronized on a schedule you control.

How Exact Online works

Exact Online exposes GL accounts, cost centers, cost units, journal entries, transaction lines, accounts (vendors and customers), purchase orders, purchase invoices, items, and contacts through a region-specific REST API with OData v3 query syntax (filter, select, orderby, top, skip). Authentication uses OAuth 2.0 Authorization Code Grant with access tokens that expire after 10 minutes and refresh tokens that rotate every 30 days. Exact Online also supports webhooks for create, update, and delete events on GL accounts, transaction lines, purchase orders, purchase invoices, and other resources, with HMAC-SHA256 signature verification. Division ID must be fetched from /api/v1/current/Me on first call and is required for all subsequent API calls. Related entities cannot be expanded ($expand not supported) and must be fetched in separate requests.

How BILL works

BILL exposes vendors, bills, payments, recurring bills, vendor credits, chart of accounts, and funding accounts through a REST API authenticated with a custom session token obtained by calling POST /v3/login with username, password, organizationId, and devKey. Sessions expire after 35 minutes of inactivity or 48 hours for AP sync token logins. BILL supports webhooks for vendor.created, vendor.updated, bill.created, bill.updated, payment.updated, and other events, with HMAC-SHA256 signature verification via the x-bill-sha-signature header using minified JSON. BILL has a maximum of 10 webhook subscriptions per organization. Purchase orders are not supported in BILL (BILL is AP and AR focused, not procurement). The webhook securityKey is returned once during subscription creation and must be stored immediately. Some sensitive operations require MFA with pre-approved trusted sessions, although financial data syncs typically do not require MFA.

What moves between them

The main flow is bidirectional. Cost centers and GL accounts from Exact Online are read and mapped to BILL's chart of accounts so bills created in BILL land on correct accounting dimensions. Bills, vendors, and payments flow from BILL into Exact Online's journal as transaction lines and GL entries on a schedule tied to your accounts payable cycle. Purchase orders and purchase invoices remain in Exact Online and are not replicated to BILL. Reference data alignment happens first so every bill that posts to Exact Online maps to a valid GL account and cost center that already exists.

How ml-connector handles it

ml-connector stores the OAuth 2.0 credentials for Exact Online and the session credentials for BILL encrypted in the database. On the Exact Online side, it fetches the division ID from /api/v1/current/Me on first call and refreshes the access token every 9 minutes before it expires. On the BILL side, it calls POST /v3/login to obtain a sessionId and refreshes it before the 35-minute inactivity timeout. Both systems' webhooks are registered to notify ml-connector of changes, and ml-connector validates incoming webhook payloads using HMAC-SHA256 (Exact Online with webhook secret, BILL with the securityKey returned at subscription creation). When webhooks are unavailable, ml-connector polls both systems on a schedule. Cost centers and GL accounts from Exact Online are fetched first via /api/v1/{division}/crm/CostCenters and /api/v1/{division}/financial/GLAccounts, deduplicated, and held in a mapping table. Bills and payments from BILL are then read and matched to the mapped GL accounts before posting to Exact Online's journal. Because Exact Online requires separate API calls for related data (no $expand), ml-connector fetches GL accounts first, then transaction lines, then journal entries in sequence. BILL does not support purchase orders, so purchase order details from Exact Online are logged but not written to BILL. If a bill in BILL cannot be matched to a valid GL account in Exact Online, it is held in a failure queue with a full audit trail and can be replayed once the missing GL account is added. Both systems return rate-limit headers, and ml-connector backs off with exponential jitter before retrying.

A real-world example

A mid-sized services firm runs Exact Online for general ledger and project accounting across five business units, and uses BILL for accounts payable and vendor payments. Before the integration, the accounts payable team entered bills from BILL into Exact Online twice weekly, matching vendor names and amounts by hand and guessing which cost center applied based on the bill description. With Exact Online and BILL connected, bills created in BILL automatically post to Exact Online's journal on the cost center that matches the project or business unit, and GL account mismatches are flagged for manual review before posting. The manual re-entry step is eliminated, and month-end close now starts with bills already reconciled.

What you can do

  • Read GL accounts and cost centers from Exact Online and map them to BILL's chart of accounts so bills post to the correct accounting dimensions.
  • Sync bills, payments, and vendor records from BILL into Exact Online's journal as transaction lines on a schedule you control.
  • Authenticate Exact Online with OAuth 2.0 and BILL with session token credentials, both encrypted and auto-refreshed before expiry.
  • Receive webhooks from both systems for real-time change notifications, with HMAC-SHA256 signature verification and exponential backoff retries.
  • Hold bills that do not match a GL account in a failure queue with full audit trails and replay them once the missing GL account is added.

Questions

Which direction does data move between Exact Online and BILL?
Data flows bidirectionally. GL accounts and cost centers are read from Exact Online and mapped to BILL's chart of accounts so new bills post to the correct dimensions. Bills, payments, and vendor records flow from BILL into Exact Online's general ledger as transaction lines and journal entries on a schedule tied to your AP cycle. Purchase orders remain in Exact Online and are not replicated to BILL since BILL does not support purchase order data.
How does ml-connector handle Exact Online's requirement that related data must be fetched in separate API calls?
Exact Online does not support the $expand parameter, so related entities like GL accounts, cost centers, and transaction lines must be fetched individually. ml-connector fetches GL accounts and cost centers first, builds a mapping table, then queries transaction lines and journal entries in sequence. This is more expensive than a single call but ensures data integrity and avoids N+1 queries by caching the mappings.
What happens if a bill from BILL does not match any GL account in Exact Online?
If a bill cannot be matched to a valid GL account, ml-connector holds it in a failure queue with a full audit trail showing the bill, the attempted GL account name, and why the match failed. Once the missing GL account is added to Exact Online, you can replay the bill through the queue to post it into the journal automatically.

Related integrations

Connect Exact Online and BILL

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

Get started