ml-connector
FreshBooksSnowflake

FreshBooks and Snowflake integration

FreshBooks runs your accounting and invoicing. Snowflake runs your data warehouse and analytics. Connecting the two keeps your financial records in Snowflake aligned with FreshBooks, so you have a single source of truth for reporting, reconciliation, and audit. New invoices, payments, and expenses flow into Snowflake tables automatically, and your finance team can query the full history without re-exporting or re-keying data.

How FreshBooks works

FreshBooks exposes invoices, payments, expenses, bills, bill vendors, clients, chart of accounts, items, and journal entries through REST APIs authenticated with OAuth 2.0 Authorization Code grant (user-delegated, not Client Credentials). The platform pushes events via webhooks to a customer-supplied endpoint for invoices, payments, bills, expenses, and other accounting records, signed with HMAC-SHA256. Webhook payloads include the object ID, account ID, business ID, and event type. FreshBooks webhook delivery is not real-time and can range from seconds to several minutes, with a 10-second timeout per attempt. Status fields on invoices and payments are read-only and computed by the system.

How Snowflake works

Snowflake is a cloud data warehouse that stores data in user-defined tables and serves as a query engine for financial records. It authenticates via Key Pair Authentication (RSA private key and JWT) or Programmatic Access Token (PAT), recommended for server-to-server connections. Snowflake provides REST APIs for SQL statement execution and data operations, with asynchronous query support returning HTTP 202 and a statement handle for polling. The SQL API uses partition-based pagination with gzip-compressed responses. Snowflake has no built-in finance objects, so all entities are user-defined tables that you control. There is no native push webhook system, and queries are pull-only.

What moves between them

The main flow is FreshBooks into Snowflake. When FreshBooks webhooks fire on invoice.create, invoice.update, payment.create, payment.update, expense.create, expense.update, bill.create, and bill.update, ml-connector receives the event, validates the HMAC-SHA256 signature, and loads the record into the corresponding Snowflake table. Records are keyed on FreshBooks object ID to allow updates. Because Snowflake is pull-only, ml-connector also supports polling FreshBooks at a cadence you define, so if webhooks are delayed or disabled you can still sync on a schedule. No data flows back to FreshBooks; Snowflake is read-only for downstream reporting and reconciliation.

How ml-connector handles it

ml-connector stores your FreshBooks OAuth credential and Snowflake Key Pair Authentication details encrypted at rest. On webhook arrival, it validates the HMAC-SHA256 signature using the webhook signing key, extracts the object ID and event type, queries FreshBooks REST API to fetch the full record, maps FreshBooks fields to your Snowflake table schema, and executes an INSERT or UPSERT statement via Snowflake's SQL API using Key Pair JWT authentication. Because FreshBooks webhooks may be delayed or disabled, ml-connector can also poll FreshBooks on a schedule tied to your accounting cycle. Snowflake's async query pattern means ml-connector submits SQL statements and polls the statement handle until complete, handling retries and timeouts. If a record fails to load, the full webhook payload and error are logged to an audit table so the record can be replayed after you fix the schema or credential issue. FreshBooks webhook timeout is 10 seconds per attempt, so ml-connector acks the webhook before querying FreshBooks, ensuring FreshBooks does not disable the callback on slow Snowflake queries.

A real-world example

A mid-sized professional services firm uses FreshBooks for invoicing and accounting, and Snowflake for their data warehouse and business intelligence. Before the integration, the finance team exported invoices and payments from FreshBooks each week and manually loaded them into Snowflake staging tables via SQL, then reconciled against the BI dashboards. With FreshBooks and Snowflake connected, every invoice, payment, and expense flows into Snowflake automatically via webhook, so the BI dashboards are always current. Month-end reconciliation now runs in minutes instead of hours, since the data is already there and no manual export-load cycle is needed.

What you can do

  • Load FreshBooks invoices, payments, expenses, and bills into Snowflake tables automatically via webhook when events occur.
  • Poll FreshBooks on a schedule you define if webhooks are delayed or disabled, so you never miss financial records.
  • Validate FreshBooks webhook signatures (HMAC-SHA256) and handle retries if Snowflake queries are slow.
  • Store audit logs of every record load attempt, with the full payload and error, so you can replay failed records after fixes.
  • Map FreshBooks fields to your Snowflake table schema and upsert by FreshBooks object ID so updates overwrite old data.

Questions

Which direction does data move between FreshBooks and Snowflake?
The flow is FreshBooks into Snowflake only. Invoices, payments, expenses, and bills are loaded into Snowflake tables when events occur or on a polling schedule you define. Snowflake is the target data warehouse and serves as the system of record for reporting and reconciliation. No data is written back to FreshBooks.
Why does ml-connector poll FreshBooks if webhooks are available?
FreshBooks webhooks are not real-time and can be delayed by several minutes. Additionally, webhooks can be disabled or miss events if a customer accidentally deletes the webhook registration. ml-connector supports optional polling on your accounting cycle so you never miss a record, and the audit log tracks whether each record came from webhook or poll so you can reconcile overlaps.
How does ml-connector handle FreshBooks webhook timeouts?
FreshBooks webhooks have a 10-second timeout per attempt, and slow Snowflake queries can exceed that limit. ml-connector acks the webhook immediately before querying FreshBooks and loading into Snowflake, so FreshBooks does not think the webhook failed and disable the callback. If the load fails, the full payload and error are logged to the audit table and can be replayed.

Related integrations

Connect FreshBooks and Snowflake

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

Get started