If you’ve ever tried to keep two business systems in sync, you know the pain. Data lives in one place, gets updated in another, and before you know it, your sales team is looking at different numbers than your warehouse crew. We recently tackled this exact problem for a client who was migrating from Salesforce to HubSpot while keeping Fishbowl as their inventory and order management system.

The catch? They had an existing Salesforce-to-Fishbowl integration that worked, and they couldn’t afford any downtime during the switch. Here’s how we built something better than what they had before.

 

The Starting Point: Salesforce and a 15-Minute Sync

The client had been running Salesforce for years with a scheduled integration that synced closed deals to Fishbowl. It ran every 15 minutes, polling Salesforce for new opportunities and pushing them to Fishbowl as sales orders.It worked. Mostly. But Salesforce had become overkill for their needs, the licensing costs kept climbing, and their team found HubSpot’s interface more intuitive. They made the call to migrate.Our job was to rebuild the Fishbowl integration for HubSpot—and make it better while we were at it. The 15-minute delay was a constant source of frustration. The warehouse team would get a call about an order that wasn’t in Fishbowl yet. “Just wait a few minutes” isn’t a great answer when you’re trying to run a tight operation. We decided to go real-time from the start.

The Solution: Webhooks HubSpot supports webhooks through their Private Apps feature. Instead of constantly asking “did anything change?“, HubSpot tells us the moment something happens. A deal closes? We know instantly. A scheduled date changes? Immediate notification.

We built three webhook handlers:

1. Ticket Created → Sync Deal to Fishbowl: The client uses HubSpot workflows to create a ticket when a deal is marked closed-won. The ticket contains the job number and scheduled installation date. When that ticket is created, our webhook fires, grabs the associated deal and line items, and creates the sales order in Fishbowl.

2. Ticket Date Changed → Update Fishbowl: Installation dates change all the time. Customer reschedules, weather delays, whatever. When someone updates the scheduled date on the HubSpot ticket, we push that change directly to Fishbowl via a SQL update. No need to reimport the entire order.

3. Payment Created → Record in Fishbowl: HubSpot’s commerce tools track payments. When a payment comes in, we automatically record it against the corresponding sales order in Fishbowl. The accounting team no longer has to manually reconcile payments between systems.

The Technical Bits

For the infrastructure nerds out there, here’s what’s under the hood:

We’re running on Cloudflare Workers, which gives us serverless execution at the edge with essentially zero cold start time. Webhooks need to respond fast, and Workers deliver. Signature validation was critical—HubSpot signs every webhook request with HMAC-SHA256, and we verify that signature before processing anything. No valid signature, no processing. This prevents anyone from spoofing webhook calls to mess with our data.

We kept a daily sync as a safety net. It runs once at 6 AM, catches anything that might have slipped through (network blip, webhook failure, etc.), and handles edge cases. Belt and suspenders. State management lives in Cloudflare KV. Every synced deal gets a record with its Fishbowl order ID, the scheduled date at time of sync, and a timestamp. This lets us detect duplicates and track what’s changed.

 

Error Handling That Actually Helps

Silent failures are the worst kind of failures. When something goes wrong at 2 AM, you need to know about it before your client calls you the next morning wondering why orders didn’t sync. We built an error tracking system that:

- Categorizes errors by type (missing contact, missing ticket, product not found, etc.)- Deduplicates repeated errors so your inbox doesn’t explode- Sends email notifications for new issues- Provides a web dashboard where ops can see what’s broken and mark issues resolvedWhen a deal can’t sync because it’s missing a required field, the system logs it, emails the team, and moves on. No crashed jobs, no blocked queues. Fix the data in HubSpot, and the next sync picks it up automatically.ResultsAfter deploying the webhook-based system:- Sync time went from 15 minutes to instant. Orders appear in Fishbowl within seconds of closing in HubSpot.- API usage dropped dramatically. We’re no longer polling HubSpot’s search endpoint every 15 minutes.- The ops team got their time back. No more manual data entry, no more reconciliation spreadsheets.- Errors became visible and actionable. When something breaks, people know about it and can fix it.

 

In ConclusionMigrating from Salesforce to HubSpot doesn’t have to mean rebuilding everything from scratch, but it’s also an opportunity to do things better. The old polling-based Fishbowl integration worked fine for years, but the webhook-based system we built for HubSpot is faster, more reliable, and scales without breaking a sweat.If you’re planning a similar migration—or just struggling to keep your CRM and inventory systems in sync—feel free to reach out.Looking for help migrating from Salesforce to HubSpot? Need a custom integration between your CRM, ERP, or inventory management system? We build solutions that keep your business systems talking to each other. Contact us to discuss your project.