+ Start a Discussion
Admin SVD Admin SVDAdmin SVD Admin SVD 

Multiple Upsert using external id in a sObject Collection API REST?

Hello,

I am trying to upsert multiple objects using API REST call /services/data/v44.0/composite/sobjects (sObject Collection) refercing the objects to External Ids, but so far, I haven't had any luck.

I am doing something like:

{
    "allOrNone": false,
    "records": [
        {
            "attributes": {
                "type": "Account"
            },
            "MyExternalID__c": "27",
            "LastName": "test-test :( test-tes",
            "PersonEmail": "email@email.com"
        }
    ]
}
 

But I get al the time this error message:

[
    {
        "success": false,
        "errors": [
            {
                "statusCode": "MISSING_ARGUMENT",
                "message": "Id not specified in an update call",
                "fields": []
            }
        ]
    }
]

Any clue?

Thanks in advance!

Syed Insha Jawaid 2Syed Insha Jawaid 2
Hi Admin

In order to update a single record you need to change the endpoint to :
(PATCH) /services/data/41.0/sobjects/Contact/CustomField__c/ExtIdValue

As you are trying to update multiple records the endpoint changes with body as well.
For instance to update contact records : 

(POST) /services/data/41.0/composite
{
"compositeRequest" : [{
  "method" : "PATCH",
  "url" : "/services/data/v41.0/sobjects/Contact/CustomField__c/ExtIdValue",
  "body" : { "LastName" : "Jack", ... }
  }, ...]
}

This is a "composite" request which allows updation of 25 records.If you wish to update more records then try Bulk,SOAP API's,SObject Tree API(t allows up to 200 records per request).

For reference of composite API : https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_composite.htm
For refernce of sObject API : https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobject_tree.htm

Cheers!!
Raj VakatiRaj Vakati
As per docs, Each object must contain an id field with a valid ID value.

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobjects_collections_update.htm
 
{
    "allOrNone": false,
    "records": [
        {
            "attributes": {
                "type": "Contact"
            },
            "MyExt__c": "27",
"Id":"0034600001PC1UL",
            "LastName": "test-test :( test-tes",
            "email": "email@email.com"
        }
    ]
}

User-added image
Raj VakatiRaj Vakati


https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_upsert.htm

This example uses the PATCH method to insert a new record. It assumes that an external ID field, “customExtIdField__c,” has been added to Account. It also assumes that an Account record with a customExtIdField value of 11999 does not already exist.
Example for upserting a record that does not yet exis
 
curl https://yourInstance.salesforce.com/services/data/v20.0/sobjects/Account/customExtIdField__c/11999 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d @newrecord.json -X PATCH

 
Admin SVD Admin SVDAdmin SVD Admin SVD

Thank you Raj,

So, from your answers there is no way to reference an External ID in a SObject Collection upsert operation, right?

Thanks for all the alternatives, I was already aware of them :) But the beauty of SObject Collection is that you can do up to 200 operations in the same API call, and also you can update any type of object in the same call.

But as a downside.... it seems that you cannot reference externals IDs in this kind of calls :(

Syed Insha Jawaid 2Syed Insha Jawaid 2
Hi Admin SVD

You can try the composite API for upserting at most 25 records.
For reference check the answer mentioned above.

Cheers!!!
 
Adam Cadman 4Adam Cadman 4
@Admin SVD,
I aso wanted to do this and was dissapointed when that the external Id was not returned with the results.
However, the documentation says the records are always returned in the same order as they are sent
So, as long as you don't have another field called 'id', 'success' or 'errors' you can merge the list of objects you sent with the list of objects you got back.
In Python, I did it like this:
for i in range(len(entries)):
        entries[i].update(sf_entries[i])

Here, 'entries' is the list of dictionaries (array of objects in JSON) I sent (before I added the 'records' list and the 'allOrNone' property) and 'sf_entries' is the list of dictionaries I got back.
The .update method adds all the key:value pairs in the sf_entries[i] dictionary to the entries[i] dictionary

How much work this is depends on what language you are using - I doubt it gets much easier than this though!