ml-connector
FreshBooksLooker

FreshBooks and Looker integration

FreshBooks runs accounting and invoicing for small businesses. Looker models warehouse data and exposes it for analysis. Connecting the two lets your finance team extract FreshBooks transactions into a warehouse in near-real-time and then explore, report, and analyze the data in Looker without manual export. Invoice trends, expense categories, payment aging, and revenue breakdowns all update automatically as transactions flow through FreshBooks.

How FreshBooks works

FreshBooks exposes clients, invoices, bills, expenses, payments, journal entries, and chart of accounts through REST APIs under the /accounting and /timetracking namespaces. Authentication uses OAuth 2.0 Authorization Code grant (user-delegated, not client credentials), so each customer connects their own FreshBooks account via their user identity. FreshBooks publishes webhooks for invoice, bill, payment, and expense events as well as client and chart-of-accounts changes, delivering event notifications via POST to a registered endpoint with HMAC-SHA256 signature validation. Webhook delivery ranges from seconds to several minutes, and timeout is 10 seconds per attempt. Employees are not a standalone resource; staff details appear only via staffId on expense records. Purchase orders are not supported.

How Looker works

Looker is a Google Cloud business intelligence platform that models data warehouse schemas and exposes them through REST APIs. It authenticates via OAuth2 client credentials, trading client_id and client_secret for a bearer token (1-hour expiry, no refresh token). Data access is controlled by Looker roles and permission sets rather than OAuth scopes. Looker does not natively store ERP or accounting data; it serves as a query and modeling layer over externally supplied warehouse data. Scheduled Plans in Looker support cron-driven webhooks for outbound delivery to S3, SFTP, email, or webhook endpoints, but Looker has no inbound webhook system. Queries are limited to 5000 rows per call without streaming, and data actions (user-triggered integrations) exist but are not designed for automated system-to-system sync.

What moves between them

The main flow is FreshBooks to Looker. Invoices, bills, payments, expenses, and journal entries from FreshBooks are extracted via REST API and delivered to a data warehouse (typically Snowflake, BigQuery, or Redshift) that Looker reads and models. Chart of accounts and client records are also delivered to provide dimensional context for expense and invoice analytics. Extraction is triggered by FreshBooks webhooks for near-real-time delivery, with fallback polling to catch any missed events. GL accounts, client hierarchies, and expense categories are synced in both directions so Looker's models stay aligned with FreshBooks. The flow is read-mostly; ml-connector does not write transactions back into FreshBooks.

How ml-connector handles it

ml-connector stores the user's FreshBooks OAuth tokens encrypted and refreshes them when they expire, requesting re-authorization via the FreshBooks OAuth flow when needed. It validates incoming FreshBooks webhook signatures using the HMAC-SHA256 header and parses the event to determine which record type (invoice, payment, expense) changed. For each webhook event, ml-connector calls the FreshBooks REST API to fetch the full record details and transforms the accounting dimensions (GL accounts, cost centers, clients, expense categories) into a schema suitable for warehouse ingestion. The extracted records are then pushed to the target warehouse or delivered via Looker's Scheduled Plans. Because FreshBooks webhooks can be delayed by several minutes and timeouts can cause retries, ml-connector also polls the FreshBooks API on a schedule to catch any gaps and deduplicate records. It tracks which records have been delivered and does not re-send duplicates when both webhook and polling fetch the same transaction. All records carry an audit trail with the original FreshBooks object_id, account_id, and delivery timestamp.

A real-world example

A mid-sized consulting firm uses FreshBooks to invoice clients and track project expenses, and uses Looker to monitor revenue, profitability, and spending trends across engagements and cost centers. Before the integration, the finance team exported invoices and expense reports from FreshBooks monthly and re-entered them into a spreadsheet for analysis, then spent days reconciling discrepancies and updating Looker dashboards by hand. With FreshBooks and Looker connected, every invoice and expense posted in FreshBooks flows automatically to a warehouse where Looker models it, dashboards refresh without manual intervention, and the finance team can analyze month-to-date revenue by client, service line, and cost center in real time. The monthly export step is gone.

What you can do

  • Extract FreshBooks invoices, payments, expenses, and bills automatically into a warehouse schema that Looker can model and query.
  • Sync chart of accounts, clients, and expense categories as dimensions so Looker reports align with FreshBooks.
  • Validate FreshBooks webhook signatures (HMAC-SHA256) and handle user-delegated OAuth 2.0 authentication without client credentials.
  • Bridge delayed webhook delivery and short timeouts by combining webhook triggers with scheduled polling and deduplication.
  • Maintain an audit trail with original FreshBooks object IDs and delivery timestamps for every extracted record.

Questions

Does this integration work with FreshBooks webhook events, or does it require polling?
Both. FreshBooks webhooks trigger near-real-time extraction when transactions change, but webhooks can be delayed by several minutes and may timeout. ml-connector combines webhook triggers with scheduled polling to catch missed events and deduplicate records so every transaction reaches the warehouse exactly once.
How does ml-connector handle FreshBooks OAuth, since it does not support client credentials?
ml-connector stores the user's FreshBooks OAuth tokens encrypted and refreshes them when they expire. When tokens are no longer valid, it redirects the user to re-authorize via the FreshBooks OAuth flow so the connection stays current without manual token management.
What happens if a FreshBooks webhook signature is invalid or a record arrives out of order?
ml-connector validates each incoming webhook using the HMAC-SHA256 signature header and rejects unsigned or tampered messages with a 401 response so FreshBooks knows to retry. Out-of-order arrivals are handled by fetching the full current state from FreshBooks when a change event arrives, so the warehouse always reflects the latest truth regardless of message ordering.

Related integrations

Connect FreshBooks and Looker

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

Get started