Your Salesforce Integrations Are Broken. Here is Exactly Why and How to Fix Them

Your Salesforce Integrations Are Broken. Here is Why. | Enterprise Architecture
Enterprise Architecture · Integration · Events

Your Salesforce Integrations Are Broken.
Here is Exactly Why and How to Fix Them

After 15 years building enterprise integrations, I still see architects and developers default to REST APIs for everything. Here is why that is costing you scalability, reliability, and money. And exactly when to use each pattern.

Reading time: ~18 minutes | Published: March 2026 | Published By: Sandip Patel, Salesforce Architect
3 Integration Patterns
1:1 vs Broadcast
6 Real-World Use Cases
15yr Field Experience
Quick Insights

APIs, Platform Events, and Webhooks are three fundamentally different integration patterns, not interchangeable terms. APIs are synchronous one-to-one conversations. Platform Events are asynchronous one-to-many broadcasts inside Salesforce. Webhooks are outbound push notifications to external systems. Choosing the wrong pattern is the #1 cause of brittle, unscalable Salesforce integrations. This guide explains all three with real-world analogies, architecture diagrams, and a decision framework you can use today.

1
The Problem With “Just Use an API”
Why pattern selection is the most consequential integration decision you make
“Every integration failure I have investigated in 15 years had the same root cause: someone used the right technology for the wrong pattern.”

Here is a scenario I encounter on almost every enterprise Salesforce engagement. A new opportunity is closed-won in Salesforce. The ERP needs to be notified to kick off fulfilment. The architect says: “We’ll call the ERP API when the record is saved.” Simple. Done. Except three months later, the ERP team is drowning in duplicate orders during peak load, the Salesforce org has an 8-second save time for Opportunity records, and no one can explain why 3% of orders silently failed.

The technology was correct. The pattern was wrong.

Over 60% of Salesforce integration issues (performance degradation, data loss, duplicate processing, governor limit breaches) trace back to a single root cause: using a synchronous API call where an asynchronous event-driven pattern was needed, or vice versa. The fix is almost never rewriting code. It is changing the architectural pattern.

The three patterns we cover in this article (Salesforce APIs, Platform Events, and Webhooks) are not just different technologies. They represent fundamentally different philosophies about how systems communicate, who is responsible for delivery, and what happens when something goes wrong. Getting this choice right at design time prevents an entire class of production incidents.

~60% of Salesforce integration issues caused by wrong pattern selection
5s+ average record save latency when synchronous API calls block the UI
72hr Platform Event replay window for guaranteed message delivery
2
The Phone Call vs. Radio Broadcast Analogy
The simplest explanation you will ever read. The one you will use to explain this to your CTO.

Before we go deep on architecture, let me give you the mental model I use when explaining this to everyone from junior developers to C-suite executives. It works every time.

📞
Salesforce API
The Phone Call

You dial one specific person. You wait on hold until they pick up. You ask your question. They answer. You hang up. You know immediately if they answered or not. If the line is busy, you get an error. It is synchronous, direct, one-to-one, and blocking.

📻
Platform Events
The Radio Broadcast

You broadcast on a frequency. Anyone tuned in to that station hears it, one listener or one hundred, you broadcast once. You do not wait for anyone to respond. You do not know or care who is listening. It is asynchronous, one-to-many, and non-blocking.

🔔
Webhook
The Doorbell

You register your address with a delivery company: “When you have something for me, ring my doorbell.” The company pushes to you when something happens. You never need to keep calling them to ask. It is push-based, event-triggered, and crosses system boundaries.

Why This Analogy Matters

Nobody calls 1,000 people individually to tell them a radio show is starting. Nobody broadcasts on a radio station when they need a specific answer from one person. Nobody polls a delivery company every 5 minutes asking “do you have a parcel for me?” Each pattern exists because the others would be absurd in that context. The same logic applies to your architecture.

Diagram 01 · Communication Pattern Comparison
API: PHONE CALL (Synchronous) Salesforce Request → ERP/System ← Response (blocks until done) PLATFORM EVENTS: RADIO BROADCAST (Asynchronous) Publisher Event Bus /MyEvent__e Apex Trigger Flow MuleSoft Publisher returns immediately. No waiting. WEBHOOK: DOORBELL (Push / Event-Triggered) External System HTTP POST → Salesforce / Your Endpoint External fires when event occurs. No polling needed.
3
Salesforce APIs: The Phone Call
When synchronous, direct communication is exactly the right choice

Salesforce exposes several API flavours including REST, SOAP, Bulk, Streaming, Composite, and more. They all share one fundamental characteristic: they are request-response patterns. The calling system asks a question and waits for an answer before proceeding. This blocking behaviour is both their strength and their limitation.

When the API Is the Right Tool

Use a Salesforce API when you need an immediate, confirmed answer. Retrieving a specific Account record to display in a third-party portal. Creating an Order in Salesforce when a customer checks out on your e-commerce platform and you need the Salesforce record ID back immediately to display a confirmation. Checking whether a Lead already exists before creating a new one. These are all phone-call scenarios where you need the other party to pick up and respond before you can move on.

The Governor Limit Reality

Every synchronous API call from within Salesforce Apex (callouts in triggers, flows, or processes) counts against your synchronous callout limits: 100 callouts per transaction, 10 seconds per callout timeout, 120 seconds total. Call an ERP API synchronously on every Opportunity save and you will hit these walls under load. The fix is not increasing limits. The fix is switching to Platform Events.

API Types at a Glance

API TypeBest ForPatternWatch Out For
REST API CRUD on records, external app integration, mobile HTTP GET/POST/PATCH/DELETE API version management, error handling
SOAP API Enterprise legacy system integration, complex data types XML over HTTP Verbose payloads, strict schema contracts
Bulk API 2.0 Large data loads, millions of records Async batched jobs Not for real-time. Designed for batch.
Composite API Multiple record operations in one call Batched REST request All-or-nothing transaction risk
Connect API Chatter, Communities, Experience Cloud REST Separate limits from core REST API

Sample: REST API Call from External System into Salesforce

// External system creates a Lead in Salesforce via REST API
// POST /services/data/v59.0/sobjects/Lead/

const response = await fetch(`${instanceUrl}/services/data/v59.0/sobjects/Lead/`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    FirstName: 'Jane',
    LastName:  'Doe',
    Company:   'Acme Corp',
    Email:     '[email protected]',
    LeadSource: 'Web'
  })
});

// Caller WAITS here. Execution is blocked until Salesforce responds.
const result = await response.json();
console.log(`Lead created with ID: ${result.id}`); // ← need this ID immediately
JavaScript · REST API
Architect’s Rule of Thumb

If the calling system needs a record ID, a status confirmation, or a data value back before it can proceed, use the API. If the calling system only needs to notify that something happened, and does not need a synchronous response, consider Platform Events or a Webhook instead.

4
Platform Events: The Radio Broadcast
Salesforce’s native event-driven architecture and why it changes everything about how you design integrations

Platform Events are Salesforce’s implementation of the publish-subscribe (pub-sub) pattern. A publisher fires an event onto the Salesforce Event Bus and immediately returns. It does not wait. It does not check if anyone is listening. It broadcasts the signal and moves on. Subscribers (Apex triggers, Flows, MuleSoft, external systems via CometD) independently consume those events at their own pace.

This architectural pattern eliminates the most common causes of Salesforce integration failure: synchronous coupling, governor limit breaches on triggers, and cascade failures when a downstream system is unavailable.

“Platform Events do not just change how you integrate. They change how you think about what Salesforce is. From a data store you push and pull from, to an event source you subscribe to.”

How Platform Events Work: Architecture View

Diagram 02 · Platform Event Architecture: Publish / Subscribe Flow
PUBLISHERS Apex Code Flow / Process Builder External System (API) MuleSoft Salesforce Event Bus Order_Placed__e 72hr replay window At-least-once delivery publish → SUBSCRIBERS (independent, async) subscribe → Apex Trigger Flow (Autolaunched) MuleSoft (CometD) External App (CometD) Agentforce / Einstein KEY CHARACTERISTICS ✓ Publisher decoupled from subscribers, never waits ✓ One event can trigger N independent subscribers ✓ 72-hour replay window, no event lost if subscriber is down ✓ Apex governor limits do NOT apply to the publisher

Defining and Publishing a Platform Event

// Step 1: Define your Platform Event in Setup (or via Metadata API)
// Object: Order_Placed__e
// Fields: OrderId__c (Text), CustomerId__c (Text), Amount__c (Number), Status__c (Text)

// Step 2: Publish from Apex (e.g. when Opportunity is Closed Won)
trigger OpportunityTrigger on Opportunity (after update) {
    List<Order_Placed__e> events = new List<Order_Placed__e>();
    
    for (Opportunity opp : Trigger.new) {
        if (opp.StageName == 'Closed Won' && 
            Trigger.oldMap.get(opp.Id).StageName != 'Closed Won') {
            
            events.add(new Order_Placed__e(
                OrderId__c    = opp.Id,
                CustomerId__c = opp.AccountId,
                Amount__c     = opp.Amount,
                Status__c     = 'New'
            ));
        }
    }
    
    // Publish: returns IMMEDIATELY. Trigger does not wait for subscribers.
    EventBus.publish(events);
}
Apex · Platform Event Publisher
// Step 3: Subscribe via Apex Trigger on the Platform Event
trigger OrderPlacedSubscriber on Order_Placed__e (after insert) {
    for (Order_Placed__e event : Trigger.new) {
        // This runs asynchronously, fully decoupled from the publisher
        OrderService.createFulfilmentRecord(
            event.OrderId__c,
            event.CustomerId__c,
            event.Amount__c
        );
    }
}
Apex · Platform Event Subscriber
The 72-Hour Replay Window: Your Safety Net

Every Platform Event is stored on the Event Bus for 72 hours with a monotonically increasing ReplayId. If a subscriber goes down for 4 hours during a maintenance window, it can resume from the last processed ReplayId when it comes back up. No events are lost. No re-processing logic required. This is the feature that makes Platform Events safe for critical business processes. A direct API call can never guarantee this.

Platform Events vs. Change Data Capture (CDC)

A common point of confusion: Salesforce also offers Change Data Capture (CDC). These are automatic events fired whenever a standard or custom object record changes. The difference is intent. Platform Events are business events you deliberately define and publish: “An order was placed.” CDC events are data-layer change signals: “The Account record with ID 001XYZ was updated, here are the changed fields.” Use Platform Events for business process events. Use CDC when an external system needs to sync Salesforce data changes in near-real-time without polling the API.

5
Webhooks: The Doorbell
How external systems push events into Salesforce and how this pattern works across the modern SaaS landscape

Webhooks are not a Salesforce-native concept. They are an industry-standard pattern used by virtually every modern SaaS platform: Stripe, Shopify, GitHub, Twilio, Slack, HubSpot, and hundreds more. Understanding webhooks is essential for any Salesforce architect because Salesforce is almost never an island. It lives inside an ecosystem of external platforms that need to push data into it when things happen.

The webhook pattern is simple: an external system registers a URL with you: “when event X happens, POST the details to this URL.” When the event fires, the external system sends an HTTP POST to your endpoint. You process it. Done. No polling. No cron jobs. No “check every 5 minutes if anything changed.”

Real-World Webhook Scenarios Every Salesforce Team Deals With

Diagram 03 · Webhook Flow: Stripe Payment → Salesforce
Customer pays online checkout Stripe payment.succeeded event fires HTTP POST → JSON payload MuleSoft / Your Webhook Endpoint validates + transforms Salesforce API or Platform Event Salesforce Opportunity: stage = Closed Won ← HTTP 200 OK (immediately) confirms receipt to Stripe ① Customer pays ② Stripe fires event ③ Endpoint receives + validates ④ Salesforce updated
Critical Implementation Rule

Always return HTTP 200 immediately when you receive a webhook, before doing any processing. Webhook senders like Stripe expect a response within 5–30 seconds. If you try to synchronously process the payload and update Salesforce before responding, your endpoint will time out under load and the sender will retry, causing duplicate processing. Return 200 first, then hand off to an async queue or Platform Event for processing.

Webhook Security: Never Trust, Always Verify

// Webhook endpoint (Node.js / MuleSoft receives Stripe event)
// STEP 1: Verify the signature BEFORE processing anything

app.post('/webhook/stripe', express.raw({type: 'application/json'}), (req, res) => {
  
  const sig    = req.headers['stripe-signature'];
  const secret = process.env.STRIPE_WEBHOOK_SECRET;
  
  let event;
  try {
    // Stripe signs every payload. Verify it came from Stripe, not an attacker.
    event = stripe.webhooks.constructEvent(req.body, sig, secret);
  } catch (err) {
    return res.status(400).send(`Webhook signature verification failed`);
  }

  // STEP 2: Return 200 IMMEDIATELY, before any processing
  res.status(200).json({ received: true });

  // STEP 3: Async processing. Publish to queue or Platform Event.
  if (event.type === 'payment_intent.succeeded') {
    processPaymentAsync(event.data.object); // non-blocking
  }
});
Node.js · Webhook Receiver
What Salesforce Outbound Messages Are

Salesforce’s own Outbound Messages (part of Workflow Rules) are effectively Salesforce acting as a webhook sender, firing a SOAP-based HTTP POST to an external endpoint when a record condition is met. They are the legacy version of the pattern. For new implementations, use Platform Events to trigger a MuleSoft or middleware flow that POSTs to the external system, this gives you far more control, retry logic, and observability.

6
Architecture Decision Framework
How to choose the right pattern, every time

Here is the decision framework I walk every architect through when we are designing a new integration. Answer these questions in order:

Integration Pattern Decision Checklist

1
Does the caller need an immediate response with data (a record ID, a status, a value) before it can proceed? → If yes, use a Salesforce API. This is your synchronous phone-call scenario.
2
Is the trigger happening inside Salesforce, and does it need to notify multiple downstream systems or processes? → If yes, use Platform Events. Publish once, let N subscribers react independently and asynchronously.
3
Is an external SaaS platform (Stripe, Shopify, GitHub, Twilio) trying to push events into Salesforce when something happens on their side? → Webhooks from the external system, received by MuleSoft or a middleware endpoint, then forwarded into Salesforce via API or Platform Event.
4
Is Salesforce trying to push notifications out to an external system when a record changes? → Change Data Capture (CDC) subscribed by MuleSoft, or Platform Event + MuleSoft outbound call. Avoid Outbound Messages for new builds.
5
Are you moving large volumes of data (100K+ records) in bulk? → Bulk API 2.0. Not a Platform Event. Not a REST API loop.
ScenarioAPIPlatform EventWebhook
External app creates a Lead and needs the new record ID back ✓ Best choice ✗ No response ✗ Wrong direction
Opportunity Closed Won triggers ERP + billing + fulfilment + notifications ⚠ Risky: blocking, N calls ✓ Best choice ✗ Wrong pattern
Stripe payment success → update Salesforce Opportunity stage ✓ Works (via middleware) ✓ After receiving ✓ Stripe sends webhook
Salesforce Account update → sync to external data warehouse ⚠ Polling required ✓ CDC + subscriber ✗ Salesforce is sender here
Load 500,000 records from data migration into Salesforce ✓ Bulk API 2.0 ✗ Not for bulk ✗ Not appropriate
Real-time order status update displayed in Experience Cloud portal ✓ REST API poll ✓ Platform Event + LWC ✓ If external pushes
Diagram 04 · Integration Pattern Selection Flowchart
Integration Needed Need immediate response with data? YES REST / SOAP API NO External system pushing event in? YES Webhook → API NO Multiple systems need to react? YES Platform Event (Pub/Sub) NO Moving 100K+ records in bulk? YES Bulk API 2.0 NO → Platform Event (async single subscriber)
7
Real-World Use Cases by Industry
Six scenarios I have seen deployed in production and the pattern that solved each one
Financial Services
Loan Approval Triggers Multi-System Cascade

A mortgage lender approves a loan in Salesforce Financial Services Cloud. The approval needs to trigger: document generation, legal system notification, branch notification, customer SMS, and CRM update across 5 different systems.

✓ Platform Event published on approval. Each of the 5 systems subscribes independently. No single failure blocks the others. Full audit trail via ReplayId.
E-Commerce / Retail
Shopify Order → Salesforce → ERP

Customer places an order on Shopify. Salesforce needs to create an Order record and the ERP needs to process fulfilment. Previously: polling Shopify API every 5 minutes. Missed orders during peak. Race conditions on duplicate processing.

✓ Shopify webhook fires on order.created → MuleSoft endpoint → Platform Event into Salesforce → ERP subscriber. Real-time, no polling, no duplicates.
Healthcare
Real-Time Patient Discharge Notification

Hospital EHR system discharges a patient. Salesforce Health Cloud needs to update case status, trigger a follow-up care flow, and notify the care coordinator. The EHR fires a webhook. Previous approach used a nightly batch file causing a 12-hour lag on critical care actions.

✓ EHR webhook → MuleSoft transforms HL7 payload → Salesforce REST API creates Case + publishes Platform Event → Flow triggers care coordinator notification within 60 seconds.
Manufacturing / B2B
IoT Sensor Alert → Field Service Dispatch

Industrial equipment sends telemetry to an IoT platform (AWS IoT). When a sensor threshold is breached, a field service work order needs to be created in Salesforce Field Service and the nearest technician dispatched automatically.

✓ AWS IoT rule fires webhook to MuleSoft → Platform Event published in Salesforce → Apex subscriber creates Work Order + triggers Einstein AI dispatch recommendation.
SaaS / Technology
Stripe Invoice Paid → Revenue Recognition

A SaaS company bills customers through Stripe. When payment is received, the Salesforce Opportunity must close, the contract activated, and a revenue recognition entry created, all in under 30 seconds for real-time dashboard accuracy.

✓ Stripe webhook (invoice.paid) → MuleSoft validates signature → Salesforce Composite API updates Opp + Contract atomically → Platform Event triggers revenue recognition job.
Insurance
Claims Processing Event-Driven Pipeline

An insurer receives a FNOL (First Notice of Loss) through a digital portal. It needs to create a claim record, check fraud scoring API, assign an adjuster, send customer confirmation, and update the policy system, previously a synchronous API chain that caused 12-second user wait times.

✓ Platform Event published on FNOL receipt. Fraud check, assignment, and confirmation run in parallel as independent subscribers. User confirmation displayed in under 2 seconds. Full traceability maintained.
8
Your Action Plan
What to do this week, whether you are an architect, developer, or business leader

For Salesforce Architects and Developers

Run an integration audit. Pull up your current Salesforce org’s outbound API callouts and check your Apex classes and triggers for any synchronous HTTP callouts made from record-save contexts. Each one is a potential performance bomb and a future production incident waiting to happen. For every callout you find, ask: does the caller actually need the response synchronously? If not, that is a Platform Event candidate.

Second action: look at your external system integrations, especially your SaaS platforms like Stripe, Shopify, GitHub, or any payments/logistics provider. If any of them are being polled via scheduled jobs, check if they offer webhooks. They almost certainly do. Replace the polling job with a webhook receiver and eliminate an entire class of latency and missed-event issues.

Quick Win for This Week

Create your first Platform Event definition in a sandbox today. It takes 10 minutes. Define Order_Notification__e with three text fields. Write a 5-line Apex publisher. Write a trigger subscriber that logs to debug. Deploy and test it. Once you feel that decoupled, asynchronous publish-subscribe pattern working in practice, you will never want to use a synchronous API callout in a trigger again.

For Business and Technology Leaders

Ask your architecture team one question: “In our Salesforce integrations, are we using synchronous API calls in places where an asynchronous event-driven pattern would be more resilient and scalable?” If they cannot answer that clearly, schedule an integration architecture review. The pattern choices made at design time are invisible until they cause an incident, and then they become the most expensive decisions in the project.

TimeframeArchitects / DevelopersBusiness Leaders
This Week Audit synchronous callouts in triggers. Identify Platform Event candidates. Build first Platform Event in sandbox. Ask your team: where are we polling instead of subscribing? What integration failures occurred in the last 6 months?
30 Days Create internal decision framework for API vs. Platform Events vs. Webhooks. Document it for your team. Request an integration architecture review as part of your next technology roadmap session.
60 Days Replace top 3 highest-risk synchronous callouts with Platform Events. Add replay monitoring. Baseline your integration reliability metrics. Track failed callout rates before and after pattern changes.
9
Frequently Asked Questions
Can I use Platform Events to integrate Salesforce with an external system directly?
Yes, external systems can subscribe to Platform Events using the CometD protocol over the Streaming API. They can also publish Platform Events by calling the Salesforce REST API to create Platform Event records. MuleSoft is the most common middleware layer for this, but any system that supports CometD or can make a REST call can participate in the Platform Event ecosystem.
What is the difference between Platform Events and Change Data Capture?
Platform Events are business-intent events you deliberately define and publish: “An order was placed,” “A fraud alert was triggered.” You control the schema, the timing, and the payload. Change Data Capture (CDC) automatically fires low-level data change events whenever a Salesforce record is created, updated, or deleted, including a diff of exactly what changed. Use Platform Events for business process events. Use CDC when an external system needs to stay in sync with Salesforce data changes without polling the API.
How do I handle webhook deduplication if a sender delivers the same event twice?
All major webhook senders (Stripe, Shopify, GitHub) provide an idempotency key or event ID with every payload. Store the event ID when you first process it, either in a custom Salesforce object or an external cache. On each incoming webhook, check if you have seen that ID before. If yes, return HTTP 200 and skip processing. This is essential for production reliability because webhook senders routinely retry on network timeouts and your endpoint must handle duplicates gracefully.
Are there governor limits on Platform Events?
Yes, but they are much more generous than synchronous API limits. Salesforce allows up to 250,000 Platform Event publishes per 24 hours on Enterprise Edition (higher on Unlimited). The key limit to watch is the subscriber side. Apex triggers on Platform Events share the same Apex CPU and SOQL limits as regular triggers. For very high-volume event processing, consider using Flow subscribers for simple logic and keeping Apex subscribers lean, or routing high-volume events through MuleSoft for processing outside Salesforce.
When should I use MuleSoft vs. calling Salesforce directly from an external system’s webhook?
Use MuleSoft (or equivalent middleware) when you need transformation, the incoming payload format does not match Salesforce’s expected format. Use it when you need fan-out, where one webhook triggers actions in multiple systems. Use it when you need resilience. MuleSoft can queue and retry failed Salesforce calls. If the payload is already clean and you only need to create one Salesforce record with no transformation, a direct webhook-to-Salesforce-API call can work, but it is fragile. Middleware pays for itself within six months on any non-trivial integration.
“The difference between a brittle integration and a resilient one is rarely the code. It is the pattern. Choose the pattern first and the code follows naturally.”

I have debugged integrations at 2am that were failing because a well-intentioned developer made an API call from a trigger that ran 200 times per second during a batch import. I have seen Platform Events replay 40,000 messages after a 3-hour subscriber outage, perfectly, with zero data loss. I have watched webhook implementations silently lose 3% of Stripe payments because someone forgot to return HTTP 200 before processing. These are not edge cases. They are patterns.

The mental models in this article (phone call, radio broadcast, doorbell) are the ones I use in every architecture review. They are simple enough for a business leader to understand and precise enough to drive the right technical decision. Use them.

Are you currently dealing with performance issues or data consistency problems in a Salesforce integration? Drop your scenario in the comments. I would genuinely like to help diagnose which pattern might be causing the issue.

Leave a reply

Your email address will not be published. Required fields are marked *