Update or Upsert Multiple Records Using Bulk API 2.0

With Bulk API 2.0, you can update thousands of existing records asynchronously. Alternatively, you can perform upsert operations on records. An upsert operation updates existing records and creates records when matching records aren’t found.

You can use Bulk API 2.0 to update the record types shown in this table.

Record TypeAPI Name
Contact recordsContact
Lead recordsLead
CampaignsCampaign

Before you send any requests to Bulk API 2.0, obtain a bearer token. For more information, see Connect to REST-based APIs.

Create a CSV file that contains the information that you want to update or upsert. The CSV file must include an Id column that contains the ID for each contact that you want to update. If you’re performing an upsert operation, you must also include a column that contains a unique external ID.

The additional columns for each record contain the values that you want to update or upsert. The column names in your CSV file must match the field names in the target object exactly. You can retrieve a list of field names by issuing a GET call to the /services/data/v60.0/sobjects/OBJECT_API_NAME/describe endpoint. Alternatively, you can view a list of fields in the Object Explorer in Salesforce Setup.

There are several other considerations to keep in mind when you create the CSV file. For more information, see Prepare CSV Files in the Bulk API 2.0 and Bulk API Developer Guide.

To begin the process of updating records in bulk, create a bulk ingestion job. Issue a POST request to the /services/data/v60.0/jobs/ingest endpoint. The body of the request must contain at least two properties: object and operation. The value of the object property must match the API name of the record type that you want to update. The value of the operation property must be update or upsert.

This example shows a minimal request to create a job that updates contacts in bulk. For additional information and code examples, see createBulkContactIngestionJob.

To perform an upsert operation, the body of the request must also include the externalIdFieldName property. The value of this property must equal the field name of an external ID on the target object. To learn more about external IDs, see Differences between the 'External ID' field and the 'Unique ID' field setting. This example shows a basic request to create a bulk upsert job.

The response includes an id value. This value is the job ID, which you use in subsequent operations.

To upload data, send a PUT request to the /services/data/v60.0/jobs/ingest/JOB_ID/batches endpoint, where JOB_ID is your job ID. The body of the request contains your data in CSV format. For best results, limit the size of the data to 100 MB.

For more information about uploading contact data, see uploadContactData.

For general considerations related to uploading data using Bulk API 2.0, see Upload Job Data in the Bulk API 2.0 and Bulk API Developer Guide.

When you finish uploading your data, change the status of the job to "UploadComplete". This step tells Salesforce to begin processing the data. You can change the status by sending a PATCH request to the /services/data/v60.0/jobs/ingest/{jobId} endpoint. The body of the request must be a JSON object with a single property named state with a value of uploadComplete.

To end a bulk update job without processing any records, change the value of state to aborted.

For more information and code examples, see closeBulkContactIngestionJob.

Check the status of the bulk update job by sending a GET request to the /services/data/v60.0/jobs/ingest/JOB_ID endpoint, where JOB_ID is the job ID. The response includes a status property, which describes the current state of the job. For more information about retrieving the status of a job, see getBulkIngestionJob.

You can also retrieve lists of records that were successfully updated, that failed to be updated, or that haven’t been updated yet. These examples show you how to retrieve this information for contacts. For other object types, replace “contact” in the URL endpoints with the API name of the object type that you want to retrieve results for.