---
schema_version: "1"
id: 50e5305f0e50c1af2e2454c198ae99d5e38aa050482d61571a20a707e3038ddb
title: "Step 3: Bulk Insert"
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-data.md
canonical_url: https://developer.salesforce.com/docs/platform/api-asynch/guide/walkthrough-upload-data.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 206554324f676864c536d1628b2a29b0441e916c87427faf043250a3f47b29b5
products:
  - Bulk API 2.0 and Bulk API Developer Guide
  - Platform Developer Content
---

# Step 3: Bulk Insert

This Bulk API 2.0 example guides you through creating a job, uploading data for the job, notifying Salesforce servers that your upload(s) are complete, checking the status of the processing job, and retrieving the results.

To do any Bulk API 2.0 task, such as inserting or updating records, you first create a Bulk API 2.0 job. The job specifies the type of object that you’re loading, such as Account, and the operation that you’re performing, such as insert or delete. After you create the job, you use the resulting job ID in subsequent requests to upload job data or abort (cancel) the job.

1.  Copy this CSV formatted list of accounts into a file named bulkinsert.csv. You use this file to upload data after creating the job.

    **note:** Save all files in this example in your terminal’s current working directory.

    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.

    ```nolang
    Name,ShippingCity,NumberOfEmployees,AnnualRevenue,Website,Description
    Lorem Ipsum,Milano,2676,912260031,https://ft.com/lacus/at.jsp,"Lorem ipsum dolor sit amet"
    Posuere Inc,Bodø,141603,896852810,http://webs.com/in/faucibus/orci/luctus/et/ultrices/posuere.json,"consectetur adipiscing elit"
    Angeles Urban,Aykol,197724,257060529,http://odnoklassniki.ru/sapien.aspx,"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
    Madaline Neubert Shoes,Xukou,190305,71664061,https://blogs.com/faucibus/orci/luctus/et/ultrices/posuere/cubilia.json,"Ut enim ad minim veniam"
    Times Online UK,Varadero,121802,58284123,http://timesonline.co.uk/eu/magna.html,"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
    The Washington Post,Hengdaohezi,190944,164329406,http://washingtonpost.com/vestibulum/proin/eu/mi/nulla/ac/enim.png,"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur"
    Amazon,Quintães,80285,684173825,http://amazon.co.uk/potenti/cras/in/purus/eu.png,"Excepteur sint occaecat cupidatat non proident"
    ```

2.  Create a job.


    1.  Create a file named `newinsertjob.json`.

    2.  Copy this content into the file.

        ```nolang
        {
            "object" : "Account",
            "contentType" : "CSV",
            "operation" : "insert",
            "lineEnding" : "LF"
        }
        ```

        When you create a Bulk API 2.0 job, specify a line ending that matches the line ending used to create the CSV file using the `lineEnding` request field. Bulk API 2.0 supports two line-ending formats: linefeed (`LF`), and carriage-return plus linefeed (`CRLF`). The default line ending, if not specified, is `LF`. Different operating systems use different characters to mark the end of a line.

        Unix / Linux / OS X uses `LF` (line feed, '`\n`', `0x0A`).

        Windows / DOS uses `CRLF` (carriage return followed by line feed, '`\r\n`', `0x0D0A`).

        It’s also possible that the text editor used to create the CSV file is configured for a specific line-ending format that supersedes the default operating system format.

        **URI**

        ```nolang
        /services/data/v68.0/jobs/ingest/
        ```

        **Example for creating a bulk insert job**

        ```nolang
        curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "Accept: application/json" -H "X-PrettyPrint:1" -d @newinsertjob.json -X POST
        ```

        **Example response body**

        The response includes the job `id`, with a job `state` of `Open`.

        ```nolang
        { "id" : "7505fEXAMPLE4C2AAM",​
        "operation" : "insert",​
        "object" : "Account",​
        "createdById" : "0055fEXAMPLEtG4AAM",​
        "createdDate" : "2022-01-02T21:33:43.000+0000",​
        "systemModstamp" : "2022-01-02T21:33:43.000+0000",​
        "state" : "Open",​
        "concurrencyMode" : "Parallel",​
        "contentType" : "CSV",​
        "apiVersion" : 68.0,​
        "contentUrl" : "services/data/68.0/jobs/ingest/7505fEXAMPLE4C2AAM/batches",​
        "lineEnding" : "LF",​ "columnDelimiter" : "COMMA" }
        ```

        You use the job `id` from this response in the next steps. You can also use the URI in the `contentUrl` field in the next step when you upload your data.

3.  Upload your CSV data using the URI in the `contentUrl` field of the response.

    You can upload up to 150 MB per job (after base64 encoding).

    The URI is similar to

    ```nolang
    /services/data/v68.0/jobs/ingest/jobId/batches/
    ```

    **Example for uploading data**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/7505fEXAMPLE4C2AAM/batches/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: text/csv" -H "Accept: application/json" -H "X-PrettyPrint:1" --data-binary @bulkinsert.csv -X PUT
    ```

    **Example response body**

    No response body.

4.  Set job `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.

    **URI**

    ```nolang
    /services/data/v68.0/jobs/ingest/jobId/
    ```

    **Example of setting `state` to `UploadComplete`**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/7505fEXAMPLE4C2AAM/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json; charset=UTF-8" -H "Accept: application/json" -H "X-PrettyPrint:1" --data-raw '{ "state" : "UploadComplete" }' -X PATCH
    ```

    **Example response body**

    ```nolang
    { "id" : "7505fEXAMPLE4C2AAM",​
    "operation" : "insert",​
    "object" : "Account",​
    "createdById" : "0055fEXAMPLEtG4AAM",​
    "createdDate" : "2022-01-02T21:33:43.000+0000",​
    "systemModstamp" : "2022-01-02T21:33:43.000+0000",​
    "state" : "UploadComplete",​
    "concurrencyMode" : "Parallel",​
    "contentType" : "CSV",​
    "apiVersion" : 68.0 }
    ```

5.  Check the job status and results.

    **URI**

    ```nolang
    /services/data/v68.0/jobs/ingest/jobId/
    ```

    **Example of checking job status**

    ```nolang
    curl https://MyDomainName.my.salesforce.com/services/data/v68.0/jobs/ingest/7505fEXAMPLE4C2AAM/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Accept: application/json" -H "X-PrettyPrint:1" -X GET
    ```

    **Example response body**

    ```nolang
    { "id" : "7505fEXAMPLE4C2AAM",​
    "operation" : "insert",​
    "object" : "Account",​
    "createdById" : "0055fEXAMPLEtG4AAM",​
    "createdDate" : "2022-01-02T21:33:43.000+0000",​
    "systemModstamp" : "2022-01-02T21:38:31.000+0000",​
    "state" : "JobComplete",​
    "concurrencyMode" : "Parallel",​
    "contentType" : "CSV",​
     "apiVersion" : 68.0,​
    "jobType" : "V2Ingest",​
    "lineEnding" : "LF",​
    "columnDelimiter" : "COMMA",​
    "numberRecordsProcessed" : 7,​
    "numberRecordsFailed" : 0,​
    "retries" : 0,​
    "totalProcessingTime" : 886,​
    "apiActiveProcessingTime" : 813,​
    "apexProcessingTime" : 619 }
    ```

6.  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/7505fEXAMPLE4C2AAM/successfulResults/ -H 'Authorization: Bearer 00DE0X0A0M0PeLE!AQcAQH0dMHEXAMPLEzmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1EXAMPLEDUkWe6H34r1AAwOR8B8fLEz6nEXAMPLE' -H "Content-Type: application/json" -H "Accept: text/csv" -H "X-PrettyPrint:1" -X GET
    ```

    The response contains CSV formatted data, with each row containing a record ID (`sf__Id`) and information on whether that record was successfully processed or not (`sf__Created`).

    **Example response body**

    ```nolang
    "sf__Id","sf__Created",Name,ShippingCity,NumberOfEmployees,AnnualRevenue,Website,Description
    "0018c00002FInboAAD","true","Lorem Ipsum","Milano","2676","9.12260031E8","https://ft.com/lacus/at.jsp","Lorem ipsum dolor sit amet"
    "0018c00002FInbpAAD","true","Posuere Inc","Bodø","141603","8.9685281E8","http://webs.com/in/faucibus/orci/luctus/et/ultrices/posuere.json","consectetur adipiscing elit"
    "0018c00002FInbqAAD","true","Angeles Urban","Aykol","197724","2.57060529E8","http://odnoklassniki.ru/sapien.aspx","sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
    "0018c00002FInbrAAD","true","Madaline Neubert Shoes","Xukou","190305","7.1664061E7","https://blogs.com/faucibus/orci/luctus/et/ultrices/posuere/cubilia.json","Ut enim ad minim veniam"
    "0018c00002FInbsAAD","true","Times Online UK","Varadero","121802","5.8284123E7","http://timesonline.co.uk/eu/magna.html","quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
    "0018c00002FInbtAAD","true","The Washington Post","Hengdaohezi","190944","1.64329406E8","http://washingtonpost.com/vestibulum/proin/eu/mi/nulla/ac/enim.png","Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur"
    "0018c00002FInbuAAD","true","Amazon","Quintães","80285","6.84173825E8","http://amazon.co.uk/potenti/cras/in/purus/eu.png","Excepteur sint occaecat cupidatat non proident"
    ```

    To get details about records that encountered an error during processing, use a GET request using 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).
