Integration Identity, External IDs & Data Governance
A Salesforce External ID is not an enterprise identity
A matching key is not an identity strategy
An ERP sends customer 004821, an ecommerce platform sends C-4821 and a legacy CRM sends the customer’s email address. The Salesforce team creates External_ID__c, loads whichever value arrives first and calls the integration idempotent. Months later, a merger, recycled email or source-system rekey creates two Accounts for one business—or updates the wrong one. The API behaved correctly; the identity decision was never designed.
The JSBC Labs position is that a Salesforce External ID is a technical matching mechanism, not an enterprise identity. It can help an API locate a record, drive upsert and connect related records without first resolving a Salesforce ID. It does not determine whether two source records represent the same real-world entity, which system is authoritative or how identifiers survive consolidation, correction and retirement.
Name the source and namespace
Avoid a generic field called External_ID__c on a shared business object. Its meaning decays as more integrations arrive. Prefer names such as SAP_Customer_ID__c or Commerce_Profile_ID__c and document the issuer, object type, format, canonicalisation rule and environment. The string 4821 is not globally meaningful; it is meaningful only inside the namespace that issued it.
Use one field for one durable key contract. Concatenating source and identifier into a governed composite key can work when the namespace is part of the contract, but informal prefixes added by each client create inconsistent matching. If several systems each have legitimate identifiers for one record, model those identifiers explicitly rather than repeatedly overwriting a single field and erasing lineage.
External and unique are different controls
Salesforce documents External ID and Unique as separate field attributes. External ID enables API matching and indexing; Unique prevents two Salesforce records from storing the same value. An External ID field can therefore contain duplicates unless uniqueness is also enabled. That distinction matters because an upsert matching multiple records returns an error rather than selecting one arbitrarily.
For an identifier that is supposed to represent one source record, enable uniqueness unless a documented business rule requires otherwise. Salesforce also states that upsert against a non-unique External ID requires the client to have View All Data, while a unique External ID avoids that special permission. Uniqueness is therefore both a data-integrity decision and a least-privilege integration design decision.
Choose create semantics deliberately
The REST sObject Rows by External ID resource creates a record when no match exists, updates when one match exists and returns an error when multiple records match. That default is convenient for synchronisation but dangerous when the caller is only authorised to amend records that Salesforce already knows. A typo in a key can become a plausible duplicate instead of a visible rejection.
Salesforce provides the updateOnly parameter for REST requests that must not create on a miss. Define this choice per operation: onboarding may permit create-or-update, while order status or credit-limit updates should often require an existing identity. Return and monitor different outcomes for created, updated, not found, duplicate match and validation failure; treating every non-error response as “synced” hides material data-quality events.
Canonicalisation is part of the contract
Case, whitespace, leading zeros and punctuation can change the meaning of a key. Salesforce explains that case-insensitive External ID matching depends on the Unique field configuration and its case-sensitivity option. The Data Import Wizard has its own documented matching considerations. A key that appears equivalent to a person may be different—or unexpectedly identical—to the platform operation performing the match.
Canonicalise at the issuing boundary, not independently in every flow, Apex class and middleware mapping. Specify whether 004821 and 4821 are equal, whether abc and ABC are equal and which characters are valid. Reject malformed values before DML, retain the original source value when auditability requires it and test the exact API or loader used in production rather than assuming every ingestion path normalises identically.
Use foreign-key loading without hiding ownership
Salesforce supports relating a child record to an existing parent through the parent’s External ID. REST, SOAP, Apex and Data Loader patterns can therefore load an Opportunity against an Account without first querying the Account’s Salesforce ID. This reduces calls and removes brittle spreadsheet lookups, especially in ordered migrations and recurring bulk loads.
The convenience does not remove dependency management. The parent must be resolvable by the agreed key, the relationship must exist and failures need a quarantine path. Decide which system owns creation of the parent and what happens when it is missing. Do not let every child feed silently create its own interpretation of the parent, because efficient relationship loading can otherwise accelerate duplicate master data.
Design the key lifecycle
External identifiers change when systems merge, tenants move, customers consolidate or upstream records are corrected. Overwriting the old value may make future replay impossible; keeping it forever as the active match may route updates to a superseded entity. Define whether keys are immutable, replaceable or aliasable, and identify who may approve a rekey.
For material identities, retain a mapping history with source, old key, new key, effective time, reason and target Salesforce record. Pause concurrent writes during high-risk rekeys and reconcile dependent records before reopening the feed. Never reuse a retired key for another entity. A durable integration needs to explain yesterday’s messages after today’s identifier has changed.
Operate identity as a controlled service
Maintain an identity register for each integration: source system, key field, namespace, authority, uniqueness, case rule, create policy, parent dependencies, rekey process and data owner. Put field metadata and mappings under source control. Test no-match, one-match, duplicate-match, wrong case, malformed key, replay, concurrent upsert, missing parent and unauthorised update paths with production-representative permissions.
Monitor creates versus updates, duplicate external-ID failures, missing parents, null keys, rekeys and records receiving identifiers from conflicting sources. Reconcile counts and samples across system boundaries rather than trusting a green transport status. The right measure is not how many upserts succeeded; it is whether every accepted message changed the intended real-world entity exactly once and left evidence strong enough to prove it.
Official references
- Salesforce Developers — Insert or Update a Record Using an External ID
- Salesforce Developers — Upsert Records Using sObject Rows by External ID
- Salesforce Developers — SOAP API upsert()
- Salesforce Developers — Relating Records by Using an External ID
- Salesforce Help — Custom Field Attributes
- Salesforce Help — Differences Between External ID and Unique ID
- Salesforce Help — Import Related Records with an External ID in Data Loader
- Salesforce Architects — Integration Patterns