Step 5: Bulk Upsert
-
Confirm that your object is using an external ID field.
Upserting records requires an external ID field on the object involved in the job. Bulk API 2.0 uses the external ID field to determine whether a record is used to update an existing record or create a record.
This example assumes that the external ID field customExtIdField__c has been added to the Account object.To add this custom field in your org with Object Manager, use these properties.For more information, see Custom Fields in Salesforce Help.- Data Type—text
- Field Label—customExtIdField
- Select External ID
-
Create a CSV file containing the records that you want to upsert.
The first row of the CSV file lists the field names for the object that you’re working with. Each subsequent row corresponds to a record that you want to insert.
One column in the CSV file must correspond to the external ID field customExtIdField__c.
For information on preparing CSV files, such as delimiter options and valid date and time formats, see Bulk API 2.0 Ingest.
For this example, copy this information into a file named accountupsert.csv.
1customExtIdField__c,name,NumberOfEmployees 2123,GenePoint,800 3234,"United Oil & Gas, UK",1467 4345,"United Oil & Gas, Singapore",348 5456,Edge Communications,10045 6567,Burlington Textiles Corp of America,5876 7678,Dickenson plc,67 8789,Grand Hotels & Resorts Ltd,409 9890,Express Logistics and Transport,243 10901,University of Arizona,9506 111350,United Oil & Gas Corp.,5467 121579,sForce,40000 132690,University of The Terrific,1257 -
Create a job that includes the external ID field.
Copy this information into a file named newupsertjob.json.
1{ 2 "object" : "Account", 3 "externalIdFieldName" : "customExtIdField__c", 4 "contentType" : "CSV", 5 "operation" : "upsert", 6 "lineEnding" : "LF" 7}URI
1/services/data/v66.0/jobs/ingest/Example for creating a bulk upsert job
1curl https://MyDomainName.my.salesforce.com/services/data/v66.0/jobs/ingest/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "X-PrettyPrint:1" -d @newupsertjob.json -X POSTExample response body
The response includes the job ID, with a job state of Open. Use the job ID and the URL in the contentUrl field in the next step when you upload your data.
1{ 2 "id" : "7476gEXAMPLE4X2ZWO", 3 "operation" : "upsert", 4 "object" : "Account", 5 "createdById" : "0055fEXAMPLEtG4AAM", 6 "createdDate" : "2022-01-02T21:57:03.000+0000", 7 "systemModstamp" : "2022-01-02T21:57:03.000+0000", 8 "state" : "Open", 9 "externalIdFieldName" : "customExtIdField__c", 10 "concurrencyMode" : "Parallel", 11 "contentType" : "CSV", 12 "apiVersion" : 66.0, 13 "contentUrl" : "services/data/66.0/jobs/ingest/7476gEXAMPLE4X2ZWO/batches", 14 "lineEnding" : "LF", 15 "columnDelimiter" : "COMMA" 16} -
Upload the CSV data file that you created.
URI
For convenience, use the URI in the contentUrl field of the response from step 1. The URI is similar to:
1/services/data/v66.0/jobs/ingest/jobId/batches/Example for uploading data
1curl https://MyDomainName.my.salesforce.com/services/data/v66.0/jobs/ingest/7476gEXAMPLE4X2ZWO/batches/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: text/csv" --data-binary @accountupsert.csv -X PUTExample response body
No response body is returned.
-
Set state to UploadComplete.
After you’re done submitting data, notify Salesforce servers that the upload of job data is complete and is ready for processing.
Create a JSON file named upload_complete.json with the contents:
1{"state":"UploadComplete"}URI
/services/data/v66.0/jobs/ingest/jobId/
Example of setting state to UploadComplete
1curl https://MyDomainName.my.salesforce.com/services/data/v66.0/jobs/ingest/7476gEXAMPLE4X2ZWO/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "X-PrettyPrint:1" -d @upload_complete.json -X PATCHExample response body
1{ 2 "id" : "7476gEXAMPLE4X2ZWO", 3 "operation" : "upsert", 4 "object" : "Account", 5 "createdById" : "0055fEXAMPLEtG4AAM", 6 "createdDate" : "2022-01-02T21:28:22.000+0000", 7 "systemModstamp" : "2022-01-02T21:28:22.000+0000", 8 "state" : "UploadComplete", 9 "externalIdFieldName" : "customExtIdField__c", 10 "concurrencyMode" : "Parallel", 11 "contentType" : "CSV", 12 "apiVersion" : 66.0 13} -
Get successful results.
After a job is in the JobComplete or Failed state, you can get details about which job data records were successfully processed.
URI
1/services/data/v66.0/jobs/ingest/jobId/successfulResults/Example of getting successful results
1curl https://MyDomainName.my.salesforce.com/services/data/v66.0/jobs/ingest/7476gEXAMPLE4X2ZWO/successfulResults/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "Accept: text/csv" -H "X-PrettyPrint:1" -X GETThe response contains CSV formatted data, with each row containing a record ID of successfully processed records.
Example response body
1"sf__Id","sf__Created",customExtIdField__c,name,NumberOfEmployees 2"0018c00002DJIpJAAX","true","123","GenePoint","800" 3"0018c00002DJIpKAAX","true","234","United Oil & Gas, UK","1467" 4"0018c00002DJIpLAAX","true","345","United Oil & Gas, Singapore","348" 5"0018c00002DJIpMAAX","true","456","Edge Communications","10045" 6"0018c00002DJIpNAAX","true","567","Burlington Textiles Corp of America","5876" 7"0018c00002DJIpOAAX","true","678","Dickenson plc","67" 8"0018c00002DJIpPAAX","true","789","Grand Hotels & Resorts Ltd","409" 9"0018c00002DJIpQAAX","true","890","Express Logistics and Transport","243" 10"0018c00002DJIpRAAX","true","901","University of Arizona","9506" 11"0018c00002DJIpSAAX","true","1350","United Oil & Gas Corp.","5467" 12"0018c00002DJIpTAAX","true","1579","sForce","40000" 13"0018c00002DJIpUAAX","true","2690","University of The Terrific","1257"To get details about records that encountered an error, use the failedResults resource. To make sure that you’re looking at the complete result set, use the unprocessedRecords resource. See Get Job Unprocessed Record Results.