Initiates a bulk import job by specifying the url for a zipped, delimited file, of no more than 20MB. A bulk import job can update and/or create multiple data types including, but not limited to, Contacts
, Contributions
, and ActivistCodes
. For a complete list of supported types, see the resources endpoint.
The zipped file can contain both update and creation records for a single resource type. It can also contain a header row. The header row is only there as a debugging aid, and is not used by the import process. See Property hasHeader
in the File object for more information on headers.
When the bulk import job is updating resources, if any non-required columns are left blank, those fields will not be updated. This process cannot be used to delete information; it can only update or create.
Request
Bulk Import Job
Property | Type | Description |
---|---|---|
description | string | Required; A description of the job, to be included in notifications (whether via email or webhook). Maximum length is 255 characters. No HTML or HTML special character syntax. More precisely, input must not match this regex: [<>]+|&# |
file | object | Required; A File object which describes the source file and columns to be acted on. The file can be up to 100 MB (100,000 KB) in size. |
actions | array | Required; An array of Action objects, each defining an action to be taken. |
File
Property | Type | Description |
---|---|---|
fileName | string | Required; Name of the delimited file within the zip file accessible by sourceUrl (e.g., MyImportData.csv ). |
hasHeader | bool | Optional; Indicates that the first line of the file should be skipped. A header row in the file will be not be used; column names are determined by the required columns array and the order that the columns appear in the file. Defaults to false. |
hasQuotes | bool | Optional; Indicates that fields are enclosed in quotation marks within each column of the file. Defaults to false . Important: If any instances of the delimiter character appear in your file itself, you will need to make sure to quote those strings and set this to true . This is very likely if you use commas as your delimiter, as commas appear in many fields you are likely to upload (eg. a Long Name of Names, with, commas in a .csv file). If you create your data with a spreadsheet program, it will probably quote the strings with delimiter in them automatically when saving. |
sourceUrl | string | Required; URL at which a zip file containing fileName can be accessed. The following URL schemes (“protocols”) are supported: SFTP, FTPS, HTTPS. If authentication is required, the username and password should be included in the URL (e.g., sftp://user:[email protected]/my_import_data.zip). |
columnDelimiter | string | Optional; Character that separates each each column; one of: CSV → comma (,) separated values, Tab → Tab separated values, Pipe → pipe (|) separated values. Defaults to CSV . |
columns | array | Required; An ordered array of Column objects, describing each column of the source file (from left to right). At least one column is required. |
Column
A column name
must be present for every column in the uploaded file, listed in the order in which they appear in the file from left to right. See mapping types for more information.
Property | Type | Description |
---|---|---|
name | string | Required; A column’s unique, alphanumeric name that can be referenced in actions (e.g., VanID) |
The first column of a file is restricted based on the ResourceType and MappingType and must match or be mapped to a specific column name; however the match is case insensitive.
ResourceType | MappingType | Required Column Name |
---|---|---|
Contacts | All Except For CreateOrUpdateContact | VanId |
Contributions | ContributionAdjustments | ContributionId |
Contributions | EditContributionData | ContactsContributionId |
ContributionAdjustments | ContributionAdjustments | ContributionId |
ContributionAdjustments | EditContributionData | ContactsContributionId |
Action
Required properties: actionType
, ResourceType
, and ResultFileSizeKbLimit
.
Property | Type | Description |
---|---|---|
actionType | string | Required; The string loadMappedFile . |
resourceType | string | Required; The type of resource being updated. Available options: Contacts , Contributions , ActivistCodes , or ContactsActivistCodes . |
resultFileSizeKbLimit | int | Required; The maximum size in kilobytes of any result file returned. |
mappingTypes | array | Required; Collection of mappings to apply to the file, translating uploaded tabular data to our object models |
columnsToIncludeInResultsFile | array | An array of Column objects to be included in the bulk import job’s results file (for example, to synchronize with an external ID to an external data source). |
Mapping types
The mappingTypes
array encodes a series of field mapping definitions. These define the supported methods for mapping out the flat data in your file, in order to translate it into datatypes understood by our import system.
The available mapping types can be discovered from the GET /bulkImportMappingTypes endpoint.
Property | Type | Description |
---|---|---|
name | string | Required; The name of the field mapping type |
fieldValueMappings | array | Optional; Any mappings, static values, or other options for this field mapping. This array is not needed if your input is using built-in mappings. For example, if your Columns array uses the names of our fields, your values are already in a format that will be accepted by our system, and no other options are required, it is not necessary to set these values. |
resultFileColumnName | array | Optional; A string to represent this mapping in the results file produced by bulk import, if the default string is not desired |
The fieldValueMappings
array contains definitions for the columns mapped as part of this field mapping. If a column or a property is left out of the array, default values will be used, wherever possible.
Property | Type | Description |
---|---|---|
fieldName | string | The name of this field’s column, as discovered by GET /bulkImportMappingTypes. |
columnName | string | If this column, as defined in the Columns array, does not have the same name as the fieldName , include the column name here. |
staticValue | string | If this field should be using a static value for the entire bulk import, instead of drawing a value from the uploaded file, set that value here. |
values | array | A collection of translations from values in the uploaded file to values as they should be imported into our system. |
The values
array is for those occasions where the uploaded file include data in some external format, and it needs to be translated into data as it is understood by our object models. For example, an external system creating the bulk import uploaded file encode types as “ccard”, “$$”, and “vmo”, which would be translated via the values
array into “Credit Card”, “Cash”, and “Venmo”.
Property | Type | Description |
---|---|---|
sourceValue | string | What string should be translated when it is found in this column in the uploaded file. |
targetValue | string | A string representation of the value to which the sourceValue should be translated. |
Examples
Example 1: Simple contacts import
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "GivenName" },
{ "name": "MiddleInitial" },
{ "name": "Surname" },
{ "name": "StreetAddress" },
{ "name": "City" },
{ "name": "State" },
{ "name": "ZipCode" },
{ "name": "EmailAddress" },
{ "name": "TelephoneNumber" },
{ "name": "Birthday" },
{ "name": "mStreet" },
{ "name": "mApt" },
{ "name": "mCity" },
{ "name": "mState" },
{ "name": "mZIP" },
{ "name": "mCountry" },
{ "name": "CodeId" }
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of new users with basic contact information",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "OriginSourceCode",
"fieldValueMappings": [
{ "fieldName": "CodeId" }
]
},
{
"name": "CreateOrUpdateContact",
"resultFileColumnName": "NewPerson",
"fieldValueMappings": [
{
"fieldName": "FirstName",
"columnName": "GivenName"
},
{
"fieldName": "MiddleName",
"columnName": "MiddleInitial"
},
{
"fieldName": "LastName",
"columnName": "Surname"
},
{
"fieldName": "AddressLine1",
"columnName": "StreetAddress"
},
{
"fieldName": "City",
"columnName": "City"
},
{
"fieldName": "StateOrProvince",
"columnName": "State"
},
{
"fieldName": "ZipOrPostal",
"columnName": "ZipCode"
},
{
"fieldName": "Email",
"columnName": "EmailAddress"
},
{
"fieldName": "Phone",
"columnName": "TelephoneNumber"
},
{
"fieldName": "DOB",
"columnName": "Birthday"
}
]
},
{
"name": "MailingAddress",
"fieldValueMappings": [
{
"fieldName": "MailingAddress",
"columnName": "mStreet"
},
{
"fieldName": "MailingAddressLine2",
"columnName": "mApt"
},
{
"fieldName": "MailingCity",
"columnName": "mCity"
},
{
"fieldName": "MailingStateOrProvince",
"columnName": "mState"
},
{
"fieldName": "MailingZipOrPostal",
"columnName": "mZIP"
},
{
"fieldName": "MailingCountryCode",
"columnName": "mCountry",
"values": [
{
"sourceValue": "America",
"targetValue": "US"
}
]
},
{
"fieldName": "MailingDisplayAsEntered",
"staticValue": "1"
}
]
}
]
}
]
}
Example 2: Repeated fields in import
In this example, a bulk upload of Contacts will be created that applies multiple ExternalID
fields to each uploaded Contact. One External ID, the one in the third column in the uploaded file, is of varying type, and draws its ExternalIDType
from the second column in the uploaded file. This is the external ID which will be included in the results file. The fourth column in the uploaded file contains another external ID. These are all hardcoded to the ExternalIDType
of “1”.
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "VANID" },
{ "name": "ExternalIdTypeID" },
{ "name": "ExternalId" },
{ "name": "ID2" }
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of external IDs",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"columnsToIncludeInResultsFile": [
{ "name": "ExternalIdTypeID" }
],
"mappingTypes": [
{
"name": "ApplyExternalID",
"fieldValueMappings": [
{ "fieldName": "ExternalIdTypeID" },
{ "fieldName": "ExternalId" }
]
},
{
"name": "ApplyExternalID",
"fieldValueMappings": [
{
"fieldName": "ExternalIdTypeID",
"staticValue": "1"
},
{
"fieldName": "ExternalId",
"columnName": "ID2"
}
]
}
]
}
]
}
Example 3: Apply custom fields to contacts
In this example, a bulk upload of Contacts will be created that applies multiple custom contact fields to each uploaded Contact. Multiple custom fields belonging to the same custom field group may be mapped, but you cannot mix custom fields from different custom field groups. Multiple custom contact groups may be added as separate mappingTypes.
POST /bulkImportJobs
{
"description": "A bulk import with custom contact fields",
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "VANID" },
{ "name": "CustomNumber_389" },
{ "name": "CF390" }
],
"columnDelimiter": "Csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "ApplyContactCustomFields",
"fieldValueMappings": [
{
"fieldName": "CustomFieldGroupID",
"staticValue": "1109"
},
{
"fieldName": "CF389",
"columnName": "CustomNumber_389"
},
{
"fieldName": "CF390"
}
]
}
]
}
]
}
Example 4: Apply Organizing Turfs to contacts
In this example, a bulk upload of Contacts will be created or updated with the mapped levels of organizing turf. You can only map one organizing turf per Contact and all turf levels must be supplied; any existing values will be overwritten. Supplying values outside the current turf hierarchy will result in a Failed
job status.
POST /bulkImportJobs
{
"description": "A bulk import with organizing turfs",
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "VANID" },
{ "name": "Region" },
{ "name": "Organizer" },
{ "name": "Team" }
],
"columnDelimiter": "Csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "ApplyOrganzingTurfs",
"fieldValueMappings": [
{
"fieldName": "CF123",
"columnName": "Region"
},
{
"fieldName": "CF124",
"columnName": "Organizer"
},
{
"fieldName": "CF125",
"columnName": "Team"
}
]
}
]
}
]
}
Example 5: Apply Jobs to contacts
In this example, a bulk upload of Contacts will be updated with all employer job information mapped from columns in the source file. Multiple jobs can be applied per Contact and any existing job record values will be overwritten. Supplying invalid values will result in a Failed
job status.
POST /bulkImportJobs
{
"description": "A bulk import with jobs",
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": true,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "VANID" },
{ "name": "Employer" },
{ "name": "EmployeeID" },
{ "name": "Worksite" },
{ "name": "WorkArea" },
{ "name": "Department" },
{ "name": "ShiftType" },
{ "name": "ScheduleType" },
{ "name": "MemberStatus" },
{ "name": "HireDate" },
{ "name": "StartDate" },
{ "name": "ProbationEndDate" },
{ "name": "IsTerminated" },
{ "name": "TerminatedDate" },
{ "name": "TerminatedReason" },
{ "name": "TerminatedBy" },
{ "name": "TerminatedNotes" },
{ "name": "IsExcluded" },
{ "name": "ExcludedDate" },
{ "name": "ExcludedReason" },
{ "name": "ExcludedBy" },
{ "name": "ExcludedNotes" },
{ "name": "MembershipCardSigned" },
{ "name": "MembershipCardSignedDate" },
{ "name": "MembershipCardReceivedDate" },
{ "name": "MembershipCardEnteredBy" },
{ "name": "AuthorizationCardSigned" },
{ "name": "AuthorizationCardSignedDate" },
{ "name": "AuthorizationCardReceivedDate" },
{ "name": "AuthorizationCardEnteredBy" },
{ "name": "Wage" },
{ "name": "WageType" },
{ "name": "WealthcareContribution" },
{ "name": "HoursPerWeek" },
{ "name": "SickDays" },
{ "name": "VacationDays" }
],
"columnDelimiter": "Csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "Jobs",
}
]
}
]
}
Example 6: Apply Names and Salutations to contacts
In this example, a bulk upload of Contacts will be updated with name and salutation information mapped from columns in the source file.
POST /bulkImportJobs
{
"description": "Load Contact Names",
"listeners": [{"type": "email", "value": "[email protected]" }],
"file": {
"fileName": "NamesImport.txt",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/NamesImport.zip",
"columns": [
{ "name": "VANID" },
{ "name": "Last" },
{ "name": "First" },
{ "name": "Middle" },
{ "name": "Suffix" },
{ "name": "Salutation" },
{ "name": "EnvelopeName" }
],
"columnDelimiter": "Tab"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "Salutations",
"fieldValueMappings": [
{
"fieldName": "LastName",
"columnName": "Last"
},
{
"fieldName": "FirstName",
"columnName": "First"
},
{
"fieldName": "MiddleName",
"columnName": "Middle"
},
{
"fieldName": "Suffix",
"columnName": "Suffix"
},
{
"fieldName": "Salutation",
"columnName": "Salutation"
},
{
"fieldName": "FormalSalutation",
"columnName": "Salutation"
},
{
"fieldName": "AdditionalSalutation",
"columnName": "Salutation"
},
{
"fieldName": "EnvelopeName",
"columnName": "EnvelopeName"
},
{
"fieldName": "FormalEnvelopeName",
"columnName": "EnvelopeName"
},
{
"fieldName": "AdditionalEnvelopeName",
"columnName": "EnvelopeName"
}
]
}
]
}
]
}
Example 7: Apply Relationships to contacts
In this example, a bulk upload of Contacts will be updated with relationship information mapped from columns in the source file.
POST /bulkImportJobs
{
"description": "Load Relationships",
"listeners": [{"type": "email", "value": "[email protected]" }],
"file": {
"fileName": "RelationshipsImport.txt",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/RelationshipsImport.zip",
"columns": [
{ "name": "VANID" },
{ "name": "Secondary" },
{ "name": "Relationship" },
{ "name": "Overwrite" }
],
"columnDelimiter": "csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "ApplyRelationships",
"fieldValueMappings": [
{
"fieldName": "SecondaryVANID",
"columnName": "Secondary"
},
{
"fieldName": "Relationship",
"values" : [
{
"sourceValue" : "Assistant",
"targetValue" : "Assistant"
}
]
},
{
"fieldName": "OverwriteExistingRelationship",
"columnName": "Overwrite"
}
]
}
]
}
]
}
Example 8: Apply Canvass Responses with SMS Opt-Ins
In this example, a bulk upload of Canvass Results will be created that applies a PhoneSmsOptInStatusID
to each VANID
and Phone
combination provided in the uploaded file. A single ContactTypeID
and ResultID
are mapped to designate that SMS Opt-In Statuses were retrieved from a texting outreach program. Additionally, we allow the Phone
that was attempted and the date the SMS Opt-In Status was collected to be mapped from the provided file.
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "VANID" },
{ "name": "PhoneNumber" },
{ "name": "SmsOptInStatus" },
{ "name": "SmsOptInStatusDate"}
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of canvass responses with SMS Opt-In Status",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "CanvassResults",
"fieldValueMappings": [
{
"fieldName": "ContactTypeID",
"staticValue": 37
},
{
"fieldName": "ResultID",
"staticValue": 14
},
{
"fieldName": "Phone",
"columnName": "PhoneNumber"
},
{
"fieldName": "PhoneOptInStatusID",
"columnName": "SmsOptInStatus"
},
{
"fieldName": "IsUpdateSMSOptInStatus",
"staticValue": true
},
{
"fieldName": "DateCanvassed",
"columnName": "SmsOptInStatusDate"
},
{
"fieldName": "CanvassedBy",
"staticValue": 1
}
]
}
]
}
]
}
Example 9: Load Early Vote Data
In this example, ballot application request date, ballot application status, and ballot request method added or updated for each VanID provided in the uploaded file. Any active early vote field can be mapped to a column or static value.
POST /bulkImportJobs
{
"description": "Load AVEV Data",
"file": {
"fileName": "my_bulk_upload.zip",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{
"name": "vanId"
},
{
"name": "ballot_application_request_date"
},
{
"name": "ballot_application_status"
},
{
"name": "ballot_request_method_id"
},
{
"name": "is_permanent_absentee"
}
],
"columnDelimiter": "csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "EarlyVoteDate",
"fieldValueMappings": [
{
"fieldName": "BallotApplicationRequested",
"columnName": "ballot_application_request_date"
},
{
"fieldName": "BallotApplicationStatusID",
"columnName": "ballot_application_status"
},
{
"fieldName": "BallotRequestTypeID",
"columnName": "ballot_request_method_id"
},
{
"fieldName": "IsPermanentAbsentee",
"columnName": "is_permanent_absentee"
}
]
}
]
}
]
}
Example 10: Upload and Delete Early Voting Locations
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "LocationName" },
{ "name": "LocationDetail" },
{ "name": "AddressLine1" },
{ "name": "City" },
{ "name": "Zip5" },
{ "name": "CountyWide" },
{ "name": "County" },
{ "name": "PrecinctIDs" },
{ "name": "Latitude" },
{ "name": "Longitude" },
{ "name": "Schedule" }
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of Early Voting Locations",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "EarlyVotingLocations",
"fieldValueMappings": [
{
"fieldName": "EarlyVotingLocationSiteTypeID",
"staticValue": 1
}
]
}
]
}
]
}
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "SiteType" }
],
"columnDelimiter": "Csv"
},
"description": "A bulk import for Deleting Early Voting Locations",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "DeleteEarlyVotingLocations",
"fieldValueMappings": [
{
"fieldName": "EarlyVotingLocationSiteTypeID",
"staticValue": 1
}
]
}
]
}
]
}
Response
A successful POST returns the jobId
of the bulk import job.
{
"jobId": 998877
}