---
schema_version: "1"
id: 18d6f8b856448a7bc231b3af29d31517d9dbe881d4727bd9a0cd2c1023c4eae5
title: "Step 4: Bulk Insert with a Multipart Request"
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/platform/api-asynch/guides/api-bulk-v2/example/walkthrough-upload-multipart-data.md
canonical_url: https://developer.salesforce.com/docs/platform/api-asynch/guide/walkthrough-upload-multipart-data.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 753a05ad2a93dd08427b06089e4a3cc6e365dd4d7f2f1cc9e18a0216d3d02e7b
products:
  - Bulk API 2.0 and Bulk API Developer Guide
  - Platform Developer Content
---

# Step 4: Bulk Insert with a Multipart Request

This Bulk API 2.0 example guides you through creating a job, uploading data for the job, checking the status, and retrieving the results. This example uses a single, multipart request to create the job and upload the data.

In this example, `BOUNDARY` is used at the start, middle, and end of the file to mark the request body boundaries between the job’s details and its CSV data.

1.  Copy this multipart, JSON-formatted content into a file named `newmultipartjob.json`.

    **note:** Save all files in this example in your terminal’s current working directory.

    ```nolang
    --BOUNDARY
    Content-Type: application/json
    Content-Disposition: form-data; name="job"
    
    {
      "object":"Contact",
      "contentType":"CSV",
      "operation": "insert",
      "lineEnding" : "LF"
    }
    
    --BOUNDARY
    Content-Type: text/csv
    Content-Disposition: form-data; name="content"; filename="content"
    
    FirstName,LastName,MailingCity
    Astro,Nomical,San Francisco
    Hootie,McOwl,San Francisco
    Appy,Camper,San Francisco
    Earnie,Badger,San Francisco
    --BOUNDARY--
    ```

2.  Create a job.

    **URI**

    ```nolang
    /services/data/v68.0/jobs/ingest/
    ```

    **Example of creating a job**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v67.0/jobs/ingest/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: multipart/form-data; boundary=\"BOUNDARY\"" -H "Accept: application/json" -H "X-PrettyPrint:1" --data-binary @newmultipartjob.json -X POST 
    ```

    The response includes the job `id`, with a job `state` of `UploadComplete`. You use the job `id` in the next steps.

    **Example response body**

    ```nolang
    {
      "id" : "7303gEXAMPLE4X2QAN",
      "operation" : "insert",
      "object" : "Contact",
      "createdById" : "0055fEXAMPLEtG4AAM",
      "createdDate" : "2022-01-02T19:26:52.000+0000",
      "systemModstamp" : "2022-01-02T19:26:52.000+0000",
      "state" : "UploadComplete",
      "concurrencyMode" : "Parallel",
      "contentType" : "CSV",
      "apiVersion" : 68.0,
      "lineEnding" : "LF",
      "columnDelimiter" : "COMMA"
    }
    ```

    After you create a multipart job, the upload is completed for you automatically. You don’t need to manually set the job `state` to `UploadComplete` for a multipart job.

3.  Check the job status and results with this URI.

    **URI**

    ```nolang
    /services/data/v68.0/jobs/ingest/jobId/
    ```

    **Example of checking job status and results**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/7303gEXAMPLE4X2QAN/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Accept: application/json" -H "X-PrettyPrint:1" -X GET
    ```

    **Example response body**

    ```nolang
    {
      "id" : "7303gEXAMPLE4X2QAN",
      "operation" : "insert",
      "object" : "Contact",
      "createdById" : "0055fEXAMPLEtG4AAM",
      "createdDate" : "2022-01-02T19:54:04.000+0000",
      "systemModstamp" : "2022-01-02T19:54:05.000+0000",
      "state" : "JobComplete",
      "concurrencyMode" : "Parallel",
      "contentType" : "CSV",
      "apiVersion" : 67.0,
      "jobType" : "V2Ingest",
      "lineEnding" : "LF",
      "columnDelimiter" : "COMMA",
      "numberRecordsProcessed" : 4,
      "numberRecordsFailed" : 0,
      "retries" : 0,
      "totalProcessingTime" : 50,
      "apiActiveProcessingTime" : 6,
      "apexProcessingTime" : 0
    }
    ```

4.  Get successful results.

    After a job is in the `JobComplete` or `Failed` state, you can get details about which records were successfully processed.

    **URI**

    ```nolang
    /services/data/v68.0/jobs/ingest/jobId/successfulResults/
    ```

    **Example of getting successful results**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/7303gEXAMPLE4X2QAN/successfulResults/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "Accept: text/csv" -H "X-PrettyPrint:1" -X GET
    ```

    **Example response body**

    ```nolang
    "sf__Id","sf__Created",FirstName,LastName,MailingCity
    "0038c00002hMS4kAAG","true","Astro","Nomical","San Francisco"
    "0038c00002hMS4lAAG","true","Hootie","McOwl","San Francisco"
    "0038c00002hMS4mAAG","true","Appy","Camper","San Francisco"
    "0038c00002hMS4nAAG","true","Earnie","Badger","San Francisco"
    ```

    To get details about records that encountered an error during processing, use a GET request with the `failedResults` resource. To make sure that you’re looking at the complete result set, look at unprocessed records by using the `unprocessedRecords` resource. See [Get Job Unprocessed Record Results](https://developer.salesforce.com/docs/platform/api-asynch/reference/get-job-unprocessed-results.md).


