Skip to main content

Example Flow

In order to provide the greatest level of control, bulk jobs are created, populated, and set to execute over several calls to the Salesloft API. In this section, we will create a basic person/upsert bulk job

Create the bulk job via a call to the bulk_jobs endpoint:

POST /v2/bulk_jobs

{
"type": "person/upsert"
}

In return, we receive the payload of the created job:

{
"data": {
"created_at": "2020-10-14T17:10:30.594437Z",
"errors": 0,
"id": 211,
"name": null,
"processed": 0,
"ready_to_execute": false,
"scopes": [],
"state": "open",
"total": 0,
"type": "person/upsert"
}
}

Using the id from the created bulk job, we can begin uploading data:

POST /v2/bulk_jobs/211/job_data

{
"data": [
{
"email_address": "test@gmail.com",
"first_name": "Test",
"upsert_key": "email_address"
},
{
"email_address": "test@gmail.com",
"first_name": "Test Second Maybe",
"upsert_key": "email_address"
}
]
}

In return, we receive a simple JSON object with a count of the number of records created:

{
"data": {
"records": 2
}
}

While we could continue to add additional data for this bulk job to process, for the purposes of this example we'll move on and mark this job as ready to execute:

PUT v2/bulk_jobs/211

{
"ready_to_execute": true
}

In return, we receive the updated bulk job with a new state:

{
"data": {
"created_at": "2020-10-14T17:10:30.594437Z",
"errors": 0,
"id": 211,
"name": null,
"processed": 0,
"ready_to_execute": true,
"scopes": [],
"state": "executing",
"total": 2,
"type": "person/upsert"
}
}

We can now poll the bulk_jobs endpoint to get an updated status:

GET v2/bulk_jobs/211

And in return we can see that the bulk job is still processing (1 record processed out of 2 total):

{
"data": {
"created_at": "2020-10-14T17:10:30.594437Z",
"errors": 0,
"id": 211,
"name": null,
"processed": 1,
"ready_to_execute": true,
"scopes": [],
"state": "executing",
"total": 2,
"type": "person/upsert"
}
}

Eventually, the job will be verified as complete and marked with the state "done":

GET v2/bulk_jobs/211

{
"data": {
"created_at": "2020-10-14T17:10:30.594437Z",
"errors": 0,
"id": 211,
"name": null,
"processed": 2,
"ready_to_execute": true,
"scopes": [],
"state": "done",
"total": 2,
"type": "person/upsert"
}
}

Once the bulk job has finished, we can call the results endpoint to see our results:

GET /v2/bulk_jobs/211/results

{
"data": [
{
"error": null,
"id": 227020,
"record": {
"email_address": "test@gmail.com",
"first_name": "Test",
"upsert_key": "email_address"
},
"resource": {
"person": {
"phone_extension": null,
"first_name": "Test",
"last_contacted_at": null,
"title": null,
"do_not_contact": false,
"person_company_industry": null,
"person_company_website": "http://gmail.com",
"phone": null,
"last_name": "aaaamcgooasdfasdfasdf",
"id": 361825,
"owner_crm_id": null,
"country": null,
"secondary_email_address": null,
"display_name": "Test aaaamcgooasdfasdfasdf",
"work_country": null,
"job_seniority": null,
"home_phone": null,
"bouncing": false,
"owner": {
"_href": "https://api.salesloft.com/v2/users/4248",
"id": 4248
},
"work_city": null,
"last_contacted_by": null,
"personal_website": null,
"work_state": null,
"custom_fields": {},
"email_address": "test@gmail.com",
"state": null,
"created_at": "2019-07-17T17:47:16.956460-04:00",
"crm_object_type": null,
"locale": null,
"personal_email_address": null,
"full_email_address": "\"Test aaaamcgooasdfasdfasdf\" <test@gmail.com>",
"city": null,
"last_replied_at": null,
"contact_restrictions": [],
"mobile_phone": null,
"counts": {
"calls": 0,
"emails_bounced": 0,
"emails_clicked": 0,
"emails_replied_to": 0,
"emails_sent": 0,
"emails_viewed": 0
},
"account": {
"_href": "https://api.salesloft.com/v2/accounts/6",
"id": 6
},
"person_stage": null,
"last_contacted_type": null,
"crm_url": null,
"crm_id": null,
"linkedin_url": null,
"person_company_name": null,
"import": null,
"tags": [],
"twitter_handle": null,
"updated_at": "2020-10-14T13:17:45.534824-04:00"
},
"upsert_type": "update"
},
"status": "success"
},
{
"error": null,
"id": 227021,
"record": {
"email_address": "test@gmail.com",
"first_name": "Test Second Maybe",
"upsert_key": "email_address"
},
"resource": {
"person": {
"phone_extension": null,
"first_name": "Test Second Maybe",
"last_contacted_at": null,
"title": null,
"do_not_contact": false,
"person_company_industry": null,
"person_company_website": "http://gmail.com",
"phone": null,
"last_name": "aaaamcgooasdfasdfasdf",
"id": 361825,
"owner_crm_id": null,
"country": null,
"secondary_email_address": null,
"display_name": "Test Second Maybe aaaamcgooasdfasdfasdf",
"work_country": null,
"job_seniority": null,
"home_phone": null,
"bouncing": false,
"owner": {
"_href": "https://api.salesloft.com/v2/users/4248",
"id": 4248
},
"work_city": null,
"last_contacted_by": null,
"personal_website": null,
"work_state": null,
"custom_fields": {},
"email_address": "test@gmail.com",
"state": null,
"created_at": "2019-07-17T17:47:16.956460-04:00",
"crm_object_type": null,
"locale": null,
"personal_email_address": null,
"full_email_address": "\"Test Second Maybe aaaamcgooasdfasdfasdf\" <test@gmail.com>",
"city": null,
"last_replied_at": null,
"contact_restrictions": [],
"mobile_phone": null,
"counts": {
"calls": 0,
"emails_bounced": 0,
"emails_clicked": 0,
"emails_replied_to": 0,
"emails_sent": 0,
"emails_viewed": 0
},
"account": {
"_href": "https://api.salesloft.com/v2/accounts/6",
"id": 6
},
"person_stage": null,
"last_contacted_type": null,
"crm_url": null,
"crm_id": null,
"linkedin_url": null,
"person_company_name": null,
"import": null,
"tags": [],
"twitter_handle": null,
"updated_at": "2020-10-14T13:17:44.321842-04:00"
},
"upsert_type": "update"
},
"status": "success"
}
],
"metadata": {
"filtering": {},
"paging": {
"per_page": 25
}
}
}

Note that each object returned corresponds to a row that you provided when uploading data to the job_data endpoint. The values that you passed for this row are listed in the "record" key and the resulting resource (the person in this example) is listed under the "resource" key. The value of that key will match the documentation, in this case being the resource from the Person Upsert endpoint.

These results will available for 30 days from the time the data was uploaded. At that point, we will delete the data in order to minimize any potential propagation of personally identifiable information.