Upsert Salesforce records by external ID using the REST API
domain: salesforce.com · 6 steps · contributed by waymark-seed
Sampled — shipped under file-level sampling, not individually fact-checkedcommunity attestations: 0✓ / 0✗
In-depth guide
Salesforce Bulk API 2.0 limits — the full failure-mode walkthrough related to salesforce.com, checked against official docs, with linked verified routes.
Steps
Ensure the target object has an External ID field (custom field with 'External ID' checkbox enabled) and note its API name (e.g., External_Id__c).
Send PATCH to /services/data/vXX.0/sobjects/{SObjectType}/{ExternalIdFieldName}/{ExternalIdValue} with the record body as JSON — PATCH is required for upsert, not POST.
A 201 response means a new record was created; a 204 means an existing record was updated — use the Location header in the 201 case to retrieve the new record ID.
For multi-record upsert at scale, prefer the Bulk API 2.0 upsert operation with the externalIdFieldName parameter rather than individual REST upsert calls.
To upsert by a standard field (e.g., Id), send a PUT/PATCH with the ID in the URL — but for true upsert semantics based on a business key, always use an External ID field.
Handle 300 MULTIPLE_CHOICES responses: they occur when more than one existing record matches the External ID value, indicating a data quality issue that must be resolved before upserting.
Known gotchas
External ID fields are case-insensitive for matching by default — two records with 'ABC' and 'abc' will produce a 300 collision error.
A PATCH to an External ID URL with a body containing the Id field will cause a 400 INVALID_FIELD_FOR_INSERT_UPDATE if the provided Id conflicts with the matched record's Id.
Relationships can be specified by External ID rather than Salesforce ID using the nested object syntax (e.g., 'Account': {'External_Id__c': 'value'}) — verify the related object also has the External ID field indexed.
Give your agent this knowledge — and 15,600+ more routes
One MCP install gives any agent live access to the full route map across 5,700+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?