Bulk Upload API
Overview
This API enables you to initiate a Consumer Append job using the REACH job processing queue. It takes an input CSV file of records, appends data (like email, phone, address, etc), and returns a downloadable enriched CSV file.
Authentication
All API requests must include a valid API key passed in the request headers. For more details please see Authentication
If your API key is missing, invalid, or expired, the API will return a 401 Unauthorized error.
API Workflow
-
Upload a CSV File: make a
POST
API request to upload a filehttps://api.versium.com/v2/lists
- The JSON response will contain meta information about the list, including the “id” field, which will be used in the API request to start a job.
-
Start a Job: make a
POST
API request to start the jobhttps://api.versium.com/v2/jobs?operation=b2cContactAppend&sub_jobs[]=<sub_job>&input_list_id=<list-id>
- The JSON response will contain meta information about the job, including a status URL to send subsequent API requests to.
-
Check Job Status: make a
GET
API request to get the job statushttps://api.versium.com/v2/jobs/<job-id>
- Once the job has completed creating the final, output csv file, this JSON response will contain an API endpoint to download the file.
-
Download Output List: make a
GET
API request to download the complete CSV filehttps://api.versium.com/v2/lists/<list-id>/download
- The response will be a stream of JSON objects, one object per line
1. Upload a CSV File
Method: POST
Endpoint:https://api.versium.com/v2/lists
Headers:
- Content-Type: multipart/form-data
- x-versium-api-key: your API key
Required Config params
name | description | value type | possible values |
---|---|---|---|
list | The CSV file | CSV | |
has_header | A Boolean for whether or not the file contains a header row. | Boolean | 1 or 0 |
header_map | A JSON objects that contains the mapping of columns indexes to know REACH input contact fields (see example below) | JSON object | REACH recognizes the following fields:
|
header_map example:
{
"email": 0,
"phone": 1,
"first": 2,
"last": 3,
"address": 4,
"city": 5,
"state": 6,
"zip": 7,
"country": 8
}
Example
Example: upload a list named consumer.csv, with header map of {"first":0,"last":1,"address":2,"city":3,"state":4}
Response Structure
Content-type: application/json
{
"versium": {
"version": "2.0",
"query_id": "de87092719ed76f66ee16c375cb4bfbe",
"query_time": 0.3544750213623047,
"results": {
"id": 953369,
"guid": "56749382-9ebe-4a71-93ab-e93f37c761ea",
"name": "consumer.csv",
"campaign_id": null,
"created_at": "2025-08-05T20:46:35.000000Z",
"finished_at": null,
"header_map": {
"first": 0,
"last": 1,
"address": 2,
"city": 3,
"state": 4
},
"has_header": true,
"delimiter_type": 1,
"records": 199,
"size": 9818,
"input_field_fill_rate": {
"first": 198,
"last": 198,
"address": 197,
"city": 198,
"state": 197
},
"column_count": 5,
"append_field_fill_rate": null,
"file_ready": true,
"source": "API",
"to_be_deleted": null,
"last_download_date": null,
"jobs": {
"withTimestamps": false
}
}
}
}
2. Start a Job
Method: POST
Endpoint: https://api.versium.com/v2/jobs?operation=b2cContactAppend&sub_jobs[]=<sub_job>&input_list_id=<list-id>
Required Config Params
name | description | value type | possibile values | notes |
---|---|---|---|---|
input_list_id | The id of the uploaded list to validate. | Integer | ||
match_type | The strength of match to enforce for appended data. | string | indiv hhld | “indiv” requires first and last as inputs. ”hhld” requires last as an input. |
operation | Which operation to perform. In this case, the value should be “b2cContactAppend”. | string | b2cContactAppend | |
sub_jobs[] | Which type of contact information to append. | array of strings | See the *sub_jobs[] options table below | You may provide multiple subjobs, but for improved accuracy and match rates, it is highly recommended to only select one at a time. |
project_id | The Id of the project to place the output list into. | integer | A valid project Id for the account. | Not required if project_name is provided. |
project_name | The name of the project to place the output list into. If the project doesn’t exist, it will be created. | string | Not required if project_id is provided. |
sub_jobs[] options
value | name | description |
---|---|---|
b2cEmailAppend | Email Address | Add an email address |
b2cAddressAppend | Postal Address | Add a postal address |
b2cPhoneAppend | Primary Phone Number | Add a phone number (could be landline or mobile or voip) |
b2cMobilePhoneAppend | Mobile Phone Only | Add a mobile phone number |
b2cMultiplePhoneAppend | Multiple Phone Numbers | Add multiple phone numbers |
b2cMultiMobilePhoneAppend | Multiple Mobile Only Phones | Add multiple mobile phone numbers |
b2cPhoneAppendHQ | Verified Primary Phone Number | Add a phone number (could be landline or mobile or voip) |
b2cMobilePhoneAppendHQ | Verified Mobile Phone Only | Add a mobile phone number |
b2cMultiplePhoneAppendHQ | Verified Multiple Phone Numbers | Add multiple phone numbers |
b2cMultiMobilePhoneAppendHQ | Verified Multiple Mobile Only Phones | Add multiple mobile phone numbers |
Optional Config Params
name | description | value type | possibile values | notes |
---|---|---|---|---|
callback_url | A URL to ping when the job has completed or failed. | string | ||
rcfg_suppression_ids | A comma-separated list of suppression list Ids to apply to this job. By default, all suppression lists are applied. | string | A comma-separated list of suppression list Ids | Your suppression list Ids can be found under the settings section of the REACH app: https://app.versium.com/account/suppressions |
Note: If a callback URL is provided in the Job Creation API request, when the job has completed or failed, a POST
request will be made to that URL. The body of the request will contain a JSON object identical to the JSON object returned by the** Job Status** API.
Example
Example of API call to perform a b2cEmailAppend on input_list 953369, perform a individual match type and save the new appended list in the project name BulkAPI_test:
https://api.versium.com/v2/jobs?operation=b2cContactAppend&sub_jobs[]=b2cEmailAppend&input_list_id=953369&match_type=indiv&project_name=BulkAPI_Test
Response Structure
Content-type: application/json
{
"versium": {
"version": "2.0",
"query_id": "a20049b1cd84a854494f35b11d2e9b8e",
"query_time": 0.3439779281616211,
"results": {
"id": 1204129,
"guid": "2c21f1a5-c42c-46b6-be2d-f13b3f334153",
"state": "dispatched",
"operation": "b2cContactAppend",
"created_at": "2025-08-05T20:50:00.000000Z",
"finished_at": null,
"config": {
"match_type": "indiv",
"sub_jobs": [
"b2cEmailAppend"
]
},
"output_list": {
"id": 953370,
"download_url": null,
"num_matches": 0,
"num_records": 0,
"project_id": 138866,
"insights": null
},
"state_url": "https://api.versium.com/v2/jobs/1204129",
"callback_url": null,
"suppression_input_list_ids": null,
"est_sec_remaining": null,
"progress_percentage": 0
}
}
}
3. Check the Job Status
Method: GET
Endpoint: https://api.versium.com/v2/jobs/<job-id>
Example
Obtaining the status of the previous example:
https://api.versium.com/v2/jobs/1204129
Response Structure
Content-type: application/json
{
"versium": {
"version": "2.0",
"query_id": "08789177c0db0e7f0b0cde17ee089ff9",
"query_time": 0.21101999282836914,
"results": {
"id": 1204129,
"guid": "2c21f1a5-c42c-46b6-be2d-f13b3f334153",
"state": "done",
"operation": "b2cContactAppend",
"created_at": "2025-08-05T20:50:00.000000Z",
"finished_at": "2025-08-05 20:50:45",
"config": {
"match_type": "indiv",
"sub_jobs": [
"b2cEmailAppend"
],
"sub_job_ids": [
1204130
]
},
"output_list": {
"id": 953370,
"download_url": "https://api.versium.com/v2/lists/953370/download",
"num_matches": 55,
"num_records": 199,
"project_id": 138866,
"insights": null
},
"state_url": "https://api.versium.com/v2/jobs/1204129",
"callback_url": null,
"suppression_input_list_ids": null,
"est_sec_remaining": 0,
"progress_percentage": 100
}
}
}
Note: When state
is "done"
, the job has completed, and the download_url
is available.
4. Download Output List
Method: GET
Endpoint: https://api.versium.com/v2/lists/\<list-id>/download
Response Structure
- Upon success, returns a streamed CSV file.
- First line: Header row.
- Each subsequent row: Input fields + appended contact data.
Example
To download the completed list of the above example:
https://api.versium.com/v2/lists/953370/download
Error responses
When an error occurs, the response object will contain an “errors” property, which is a string of arrays.
{
"versium": {
"version":"2.0",
"match_counts":{},
"num_matches":0,
"num_results":0,
"query_id":"48f9238a-ba98-4c45-97df-74f405c97527",
"query_time":7.340619087219238,
"results":[],
"errors": []
}
}
HTTP Status Codes
The api will attempt to return HTTP status codes for successful and failed requests. Use these codes to determine whether the request was successful. When an error code is returned, check the “errors” property in the response object for more details.
For more details, please see HTTP Status Codes