← All articles
Salesforce · MuleSoft · Quick Reads

Salesforce Upsert with External IDs from MuleSoft

When an external system sends customer, account, order, or product data to Salesforce, it often does not know the Salesforce record ID.

That does not mean the integration should first search Salesforce and then decide whether to create or update a record.

A cleaner pattern is to give Salesforce a stable business identifier from the source system and use it as an External ID for upsert behavior.

The Problem with Create-or-Update Logic

Imagine an ERP sends this customer:

{
  "customerNumber": "ERP-10482",
  "name": "Acme Manufacturing",
  "country": "US"
}

The ERP knows ERP-10482. It does not know Salesforce's Account Id.

A naive integration can become:

1. Query Salesforce for customerNumber
2. If found → update
3. If not found → create

That works, but it adds another API operation and creates a race between the lookup and the write.

Instead, configure a Salesforce field such as:

ERP_Customer_Number__c

as an External ID and use that field as the identity supplied by the source system.

Think in Terms of Source Identity

The important design question is:

What identifier does the system of record guarantee will remain stable for this business entity?

Good candidates might include:

  • customer number;
  • employee number;
  • product SKU when it is truly stable and unique;
  • source-system order ID;
  • a generated immutable integration identifier.

A display name is usually a poor external key because names can change and may not be unique.

MuleSoft Transformation

Suppose Mule receives:

{
  "customerNumber": "ERP-10482",
  "name": "Acme Manufacturing",
  "website": "https://example.com",
  "country": "US"
}

The DataWeave mapping can keep source identity explicit:

%dw 2.0
output application/java
---
{
    ERP_Customer_Number__c: payload.customerNumber,
    Name: payload.name,
    Website: payload.website,
    BillingCountry: payload.country
}

The Salesforce operation then performs the upsert using ERP_Customer_Number__c as the external ID field.

Conceptually:

ERP-10482 exists in Salesforce?
    yes → update that record
    no  → create a record associated with ERP-10482

This keeps the integration centered on a stable cross-system identifier instead of Salesforce's internal ID.

Why This Helps with Retries

External-ID upsert is particularly valuable when delivery can be retried.

Suppose Mule sends a customer record successfully, but a timeout prevents the caller from receiving the response. The caller retries the same message.

If the integration blindly performs another create, duplicate Salesforce records can result.

With a stable external ID, retrying the same logical record targets the same Salesforce identity.

That makes the write naturally more idempotent.

It does not make the entire integration automatically idempotent—child records, side effects, events, and downstream calls may still require their own controls—but it removes a common source of duplicate parent records.

External ID Is a Contract

Treat the external identifier as part of the integration contract, not merely a Salesforce configuration detail.

Document:

Source system: ERP
Entity: Customer
Source identifier: customerNumber
Salesforce object: Account
Salesforce external ID: ERP_Customer_Number__c

This becomes especially important when several source systems integrate with the same Salesforce object.

For example, do not casually place unrelated CRM, ERP, and billing identifiers into one external-ID field just because they all look like strings.

Validate the Identifier Before Upsert

A missing external ID is not something to silently default.

Avoid patterns such as:

ERP_Customer_Number__c: payload.customerNumber default "UNKNOWN"

If multiple records receive UNKNOWN, identity semantics are destroyed.

Instead, validate required identifiers before attempting the write and route invalid records through the integration's error-handling strategy.

What If the External Identifier Changes?

This should be decided before implementation.

If a source-system key can legitimately change, ask whether it is really an identity key or simply a mutable business attribute.

An ideal integration identifier is:

stable + unique + owned by an authoritative system

If the business identifier is mutable, consider a separate immutable source ID for integration identity.

Multiple Records in a Batch

For batch-style synchronization, the same principle applies to every record:

[
  { "customerNumber": "ERP-1001", "name": "Acme" },
  { "customerNumber": "ERP-1002", "name": "Global Media" },
  { "customerNumber": "ERP-1003", "name": "Northern Trail" }
]

Transform the collection while preserving the external ID on every item:

payload map (customer) -> {
    ERP_Customer_Number__c: customer.customerNumber,
    Name: customer.name
}

Then use the connector/API operation appropriate to the required volume and Salesforce limits.

The external-ID pattern determines identity. It does not by itself determine whether you should use individual operations, collections, Bulk API, or another ingestion approach.

Avoid Query-Then-Write When Upsert Fits

There are valid reasons to query before writing—for example, when the decision depends on existing Salesforce state.

But do not query simply because the integration does not know the Salesforce Id.

If the requirement is just:

create if this source record is new
update if this source record already exists

an External ID plus upsert is usually the more direct model.

Quick Design Checklist

Before implementing an External-ID upsert, confirm:

  • the source identifier is stable;
  • it is unique at the intended business scope;
  • missing identifiers are treated as errors rather than invented defaults;
  • the Salesforce field is configured for the intended external identity behavior;
  • retries use the same source identifier;
  • child records and other side effects have their own idempotency strategy where needed.

Practical Rule

When integrating an authoritative source with Salesforce, preserve the source system's stable identity all the way into Salesforce.

Use Salesforce record IDs when Salesforce owns the identity. Use a well-designed External ID when another system does.

CONTINUE READING

Explore closely related architecture, integration and implementation topics.