Wave Accounting and Fishbowl integration
Wave Accounting tracks your invoicing and revenue. Fishbowl Advanced manages your inventory and orders. Connecting the two keeps your sales orders and customer records in sync without re-entry. When you create a customer or invoice in Wave, Fishbowl reflects that immediately so you can pick and ship against the right accounts. ml-connector bridges Wave's cloud GraphQL API and Fishbowl's on-premise REST API, handling the very different authentication models and the fact that Fishbowl runs in your own data center.
What moves between them
The main flow moves from Wave into Fishbowl. Invoices and customer records created or updated in Wave are read via GraphQL, mapped to Fishbowl customers and sales orders, and written into Fishbowl via REST. Products are synchronized in both directions so invoice line items reference inventory that already exists in Fishbowl. Because Fishbowl is pull-only and has no webhook support, ml-connector polls Wave's GraphQL endpoints on a schedule you define (typically daily or per-invoice-event). Wave webhooks are also accepted where enabled to accelerate the sync.
How ml-connector handles it
ml-connector stores Wave OAuth credentials encrypted and refreshes the access token automatically when it expires (every 2 hours). On the Fishbowl side, it accepts the customer-supplied server URL and port, authenticates once per session, and maintains a persistent Bearer token across calls. Wave webhook payloads are validated by computing the HMAC-SHA256 signature of the request body against the stored secret and checking the x-wave-signature header; a mismatch returns 401. When writing to Fishbowl, ml-connector maps Wave customers and products to matching Fishbowl entities by name or SKU; if a customer does not exist in Fishbowl, it creates one. Invoice-to-sales-order mapping is defined per customer so the same Wave invoice can route to different Fishbowl workflows depending on the account. Because Fishbowl is on-premise, ml-connector never assumes a shared base URL and always uses the customer-supplied endpoint. Retries respect Fishbowl's polling window (recommended 5 to 15 minute intervals) and track the most recent sync timestamp so no record is processed twice.
A real-world example
A small manufacturing business uses Wave Accounting to invoice customers and track revenue. Their sales fulfillment happens in Fishbowl Advanced running on a local server. Before the integration, when an order came in, the sales team created it in Wave, then logged into Fishbowl separately to create a matching sales order so warehouse could pick and ship. Invoices and customer records often went out of sync, and the team manually reconciled the mismatch during month-end close. With Wave and Fishbowl connected, each customer and invoice created in Wave automatically populates in Fishbowl at the next sync pulse (triggered by a webhook or a scheduled poll), so the warehouse always sees current customer details and current orders. The team no longer re-enters orders, and month-end reconciliation is simpler because both systems start from the same source.
What you can do
- Sync Wave invoices into Fishbowl as sales orders, mapped to the correct customer.
- Keep Fishbowl customers in sync with Wave customer records, including name, email, and billing address.
- Map Wave products to Fishbowl parts so invoice line items reference inventory that exists in Fishbowl.
- Handle Wave's OAuth 2.0 refresh cycle and Fishbowl's on-premise session authentication transparently.
- Accept Wave webhooks to accelerate the sync, and poll on a schedule you define if webhooks are unavailable.
Questions
- How does the integration handle Wave and Fishbowl's different data models?
- Wave tracks invoices and customers; Fishbowl tracks sales orders and inventory. ml-connector maps Wave invoices to Fishbowl sales orders and Wave customers to Fishbowl customers. Products are matched by name or SKU so invoice line items reference inventory that already exists in Fishbowl. If a customer or product does not exist in Fishbowl, ml-connector creates it.
- What happens when Wave webhooks are not enabled or fail?
- ml-connector polls Wave's GraphQL API on a schedule you define, typically once per day or more frequently if you choose. The polling interval is independent of Fishbowl's recommended 5 to 15 minute fetch window; ml-connector tracks the most recent sync timestamp to avoid duplicate processing.
- Why does Fishbowl require a customer-supplied server URL instead of a fixed endpoint?
- Fishbowl Advanced is an on-premise system, not a SaaS platform. Each customer runs their own Fishbowl instance on their own server at a URL and port they control. ml-connector stores the customer-supplied server URL and uses it for all REST calls, so there is no shared base address like there is with Wave's hosted GraphQL endpoint.
Related integrations
More Wave Accounting integrations
Other systems that connect to Fishbowl
Connect Wave Accounting and Fishbowl
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started