# Update or Upsert Multiple Records Using Bulk API 2.0

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

## Record Types

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

| Record Type     | API Name   |
| --------------- | ---------- |
| Contact records | `Contact`  |
| Lead records    | `Lead`     |
| Campaigns       | `Campaign` |

## Prerequisite

Before you send any requests to Bulk API 2.0, obtain a bearer token. For more information, see [Connect to REST-based APIs](/docs/marketing/marketing-cloud-growth/guide/mc-connect-apis-rest.md).

## Step 1: Prepare the CSV File

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/{apiVersion}/sobjects/OBJECT_API_NAME/describe` endpoint. Alternatively, you can view a list of fields in the Object Explorer on the Setup page of the Salesforce web app.

There are several other considerations to keep in mind when you create the CSV file. For more information, see [Prepare CSV Files](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/datafiles_prepare_csv.htm) in the *Bulk API 2.0 and Bulk API Developer Guide*.

## Step 2: Create a Bulk Update or Upsert Job

When you’re ready to bring your data into Marketing Cloud, create a bulk ingestion job. The structure of the request body varies depending on whether you want to perform an update or an upsert operation.

### Option 1: Create an Update Job

To perform an update operation, issue a POST request to the `/services/data/{apiVersion}/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](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=createBulkContactIngestionJob).

```json
POST /services/data/{apiVersion}/jobs/ingest HTTP/1.1
Host: YOUR_SUBDOMAIN.my.salesforce.com
Content-Type: application/json
Authorization: Bearer YOUR_BEARER_TOKEN

{
    "object": "contact",
    "operation": "update"
}
```

### Option 2: Create an Upsert Job

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](https://help.salesforce.com/s/articleView?id=000385174\&type=1). This example shows a basic request to create a bulk upsert job.

```json
{
  "object": "Contact",
  "operation": "upsert",
  "externalIdFieldName": "ExternalId__c"
}
```

If the request is successful, the response includes an `id` value. This value is the job ID, which you use in subsequent operations.

```json
{
  "id": "750SB000001uG6LYAU",
  "operation": "update",
  "object": "Contact",
  ...
}
```

## Step 3: Upload the Data

To upload data, send a PUT request to the `/services/data/{apiVersion}/jobs/ingest/JOB_ID/batches` endpoint, where `JOB_ID` is your job ID. Include your data in CSV format in the body of the request. For best results, limit the size of the data to 100 MB.

For more information about uploading contact data, see [uploadContactData](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=uploadContactData).

For general considerations related to uploading data using Bulk API 2.0, see [Upload Job Data](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/upload_job_data.htm) in the *Bulk API 2.0 and Bulk API Developer Guide*.

## Step 4: Change the Status of the Job

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/{apiVersion}/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](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=closeBulkContactIngestionJob).

## Step 5: Check the Status of the Job

Check the status of the bulk update job by sending a GET request to the `/services/data/{apiVersion}/jobs/ingest/JOB_ID` endpoint, where `JOB_ID` is the job ID. If the request is successful, 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](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=getBulkContactIngestionJob).

You can also retrieve lists of records that were [successfully updated](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=getSuccessfulRecords), that [failed to be updated](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=getFailedRecords), or that [haven’t been updated yet](/docs/marketing/marketing-cloud-growth/references/mc-bulk-contacts?meta=getUnprocessedRecords). 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.
