ml-connector
FreshBooksFishbowl

FreshBooks and Fishbowl integration

FreshBooks runs your accounting and invoicing. Fishbowl Advanced runs your inventory, purchasing, and manufacturing orders. Connecting them keeps your bills and expenses aligned with your purchase orders and vendor data. Bills created in FreshBooks flow into Fishbowl so costs are tracked against inventory and manufacturing, and purchase orders entered in Fishbowl synchronize back to FreshBooks so your accounts payable reflects current procurement. ml-connector bridges the very different architectures of a cloud accounting system and an on-premise inventory platform.

How FreshBooks works

FreshBooks exposes invoices, bills, bill_vendors, expenses, payments, chart_of_accounts, items, and journal_entries through a REST API at https://api.freshbooks.com. Authentication uses OAuth 2.0 Authorization Code grant with user-delegated credentials and granular scopes per resource. FreshBooks pushes real-time notifications via webhooks to a customer-supplied endpoint for invoice, bill, expense, and payment events, with HMAC-SHA256 signatures. Webhook payloads are URL-encoded and include object_id, account_id, business_id, and identity_id. Note that clients and employees are accessible through the API but employees are read-only and appear only as staffid fields on expense records.

How Fishbowl works

Fishbowl Advanced exposes vendors, purchase orders, sales orders, inventory, parts, manufacturing orders, customers, and users through a REST API hosted on the customer's own on-premise server at a configurable address (typically http://server:2456/api). Authentication is session-based: POST /api/login with username, password, appName, and appId returns a token used as Authorization Bearer on all subsequent requests. Fishbowl has no outbound webhooks and offers no multi-tenant SaaS endpoint; the customer provides their server address and ml-connector polls for changes using date filters on purchase orders, inventory adjustments, and vendor updates typically on a 5-15 minute interval. GL accounts are handled by the QuickBooks or Xero integration, not exposed directly.

What moves between them

The integration runs bidirectionally with different cadences. FreshBooks bills and expenses push via webhook when created or updated; ml-connector ingests them, maps them to Fishbowl vendors and purchase orders, and records them as cost line items. Fishbowl purchase orders are polled every 5-10 minutes and mapped back to FreshBooks bills and bill_vendors so procurement changes reflect in accounts payable. Vendor master data flows both directions: new vendors in Fishbowl sync to FreshBooks bill_vendors, and new bill_vendors in FreshBooks are offered as Fishbowl vendor candidates on the next poll cycle.

How ml-connector handles it

ml-connector stores FreshBooks OAuth tokens encrypted and registers a webhook endpoint; it receives bill and expense events asynchronously and processes them into Fishbowl by first fetching the matching vendor from Fishbowl's data-query endpoint using SQL (since Fishbowl has no direct vendor-by-name lookup). For Fishbowl, ml-connector handles the on-premise server address per customer and maintains a session token, refreshing it when the API returns a 401 or the session expires. Because Fishbowl is polling-only, ml-connector tracks the high-water mark of the last sync timestamp and queries purchase orders and vendor changes incrementally to avoid re-processing. Fishbowl does not expose GL accounts, so cost allocation happens at the FreshBooks chart_of_accounts level after the sync. The signature validation on FreshBooks webhooks uses HMAC-SHA256 and rejects unsigned or tampered events. Every record carries a full audit trail linking the FreshBooks object_id to the Fishbowl purchase order or vendor; failed cost posts are queued for replay.

A real-world example

A small-to-medium wholesale distributor uses FreshBooks for invoicing, expenses, and accounts payable, and Fishbowl Advanced on-premise for purchase ordering and inventory tracking. Before the integration, the purchasing team would enter purchase orders in Fishbowl, then the accounting team would manually create bills in FreshBooks based on printed POs and vendor invoices, with no automatic link between the two. Expenses paid out of petty cash were entered in FreshBooks but had no visibility into which purchase order they belonged to. With FreshBooks and Fishbowl connected, each new FreshBooks bill for a vendor automatically syncs to Fishbowl as a cost record tied to the matching purchase order, and each new Fishbowl purchase order flows back to FreshBooks so the accounts payable team starts with a pre-populated bill. Expenses entered in FreshBooks sync to Fishbowl's cost tracking, and the inventory team can see the true landed cost of each purchase without manual reconciliation.

What you can do

  • Receive FreshBooks bill and expense webhooks and post them into Fishbowl as cost records tied to vendors and purchase orders.
  • Poll Fishbowl purchase orders and vendor data on a configurable schedule and sync them back to FreshBooks bills and bill_vendors.
  • Map FreshBooks bill items to Fishbowl parts and inventory using configurable matching rules.
  • Authenticate FreshBooks via OAuth user-delegated tokens and Fishbowl via on-premise session tokens, handling token refresh and server-address configuration.
  • Maintain a full audit trail of every bill, expense, and purchase order sync, with support for replay on failures.

Questions

Which direction does data move between FreshBooks and Fishbowl?
Data moves bidirectionally but on different cadences. FreshBooks bills and expenses are pushed via webhook and ingested into Fishbowl as cost records. Fishbowl purchase orders and vendor data are polled every 5-10 minutes and synced back to FreshBooks bills and bill_vendors. Vendor master data flows both directions so procurement stays synchronized with accounting.
How does ml-connector handle Fishbowl's on-premise architecture and lack of webhooks?
ml-connector accepts the customer's Fishbowl server URL and configurable port, maintains an authenticated session token, and polls for changes using date filters and SQL queries on a regular interval. Because there are no outbound webhooks from Fishbowl, the connector tracks the high-water mark of the last sync timestamp to detect new and updated purchase orders and vendor records without re-processing.
What happens if FreshBooks and Fishbowl disagree on a vendor or purchase order?
Every sync record in ml-connector carries the FreshBooks object_id and the Fishbowl purchase order or vendor ID, plus a full audit trail. If a sync fails, the record is queued for replay; if a record is manually edited in either system after sync, the audit log shows the change so the team can decide whether to re-sync or leave the systems as they are.

Related integrations

Connect FreshBooks and Fishbowl

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

Get started