One of the most efficient ways to add or update contacts using the v2 API is by using the Import Contacts multipart endpoint. You will need to create a file in one of the supported types with the contact information you want to import.
Why is using multipart bulk activity your best bet for adding and updating contacts?
- You can easily package the contact data by exporting it from your database to a file.
- The POST creates an asynchronous background job
- No risk of hitting API call limits – you can add/update up to 20,000 contacts with a single API call
- Only individual contacts with format problems fail, not the entire job
- monitor status using the location value in the response header
What’s needed
There are 3 major elements you need to make this happen:
- The contact data to import.
- The list(s) you want to add the contacts to.
- The multipart post code that calls the endpoint and passes the file.
Contact data format
File types
The Import Contacts bulk activity endpoint supports the following file types:
|
|
File format
The import file consists of columns, one for each contact property included, and rows, one for each contact being imported.
Contact Properties
You can include the following contact properties in your import file. You must name the column containing the property as shown below:
|
|
Limitations
There are two limitations you need to be aware of when using the Import Contacts bulk activity endpoint:
- File size: the import file must be less than 4 megabytes.
- Number of contacts: Each POST can import a maximum 20,000 contacts.
The activity request will fail if the payload is greater than 4 MBs or if there are more 20,000 contacts.
Examples
Here are a few code examples using the Import Contacts multipart endpoint to import contacts from a file to a contact list.
CURL Example
This example CURL script uploads the file contacts.txt to the import contacts multipart endpoint, adding the contacts to listId=5. It assumes that the data file is located in the same directory from which the script is run, otherwise you must use an absolute path to the data file.
curl -i -H "Authorization: Bearer <Oauth2.0_access_token>" -H "Content-Type: multipart/form-data" -H "Accept: application/json" -X POST -F 'lists=5' -F 'file_name=contacts.txt' -F 'data=@contacts.txt' "https://api.constantcontact.com/v2/activities/addcontacts?api_key=<api_key>"
Java Example
Here’s an example of a multipart encoded post written in Java that imports the file contacts.txt, adding the contact to contact list 1 (listId=1).
final HttpClient httpclient = new DefaultHttpClient(); final HttpPost httppost = new HttpPost("https://api.constantcontact.com/v2/activities/addcontacts?api_key=<api_key>"); httppost.addHeader("Authorization", "Bearer <OAuth2.0_access_token>"); httppost.addHeader("Accept", ”application/json”); httppost.addHeader("content-type", "multipart/form-data"); final File fileToUse = new File("/path_to_file/contacts.txt"); //e.g. /temp/contact.txt final FileBody data = new FileBody(fileToUse); final String listIds = "1"; final StringBody lists = new StringBody(listIds); final StringBody fileName = new StringBody(fileToUse.getName()); final MultipartEntity reqEntity = new MultipartEntity(); reqEntity.addPart("file_name", fileName); reqEntity.addPart("lists", lists); reqEntity.addPart("data", data); httppost.setEntity(reqEntity); final HttpResponse response = httpclient.execute(httppost); final HttpEntity resEntity = response.getEntity(); EntityUtils.consume(resEntity); httpclient.getConnectionManager().shutdown(); }
Java SDK
The Constant Contact Java SDK includes methods for all bulk activities, including the import contacts multipart bulk activity endpoint. Here’s a snippet of code that uses the ctct.addBulkContactsMultipart Java SDK method to import the contacts in file.xlsx and add them to contact lists 4 and 5.
System.out.println("Multipart test..."); File f = new File("file.xlsx"); ArrayList listIds = new ArrayList(); listIds.add("4"); listIds.add("5"); try { ContactsResponse response1 = ctct.addBulkContactsMultipart("file.xlsx", f, listIds); System.out.println(response1.toJSON()); } catch (ConstantContactServiceException e) { List errors = e.getErrorInfo(); for (CUrlRequestError error : errors) { System.out.println(error.getErrorMessage()); } }
Ruby Example
This example coded in Ruby is available along with all supporting files in the Constant Contact GitHub Ruby repository.
# # myapp.rb # ConstantContact # #Copyright (c) 2014 Constant Contact. All rights reserved. require 'rubygems' require 'sinatra' require 'active_support' require 'yaml' require 'constantcontact' # This is a Sinatra application (http://www.sinatrarb.com/). # Update config.yml with your data before running the application. # Run this application like this : ruby myapp.rb # Name this action according to your # Constant Contact API Redirect URL, see config.yml get '/cc_callback' do cnf = YAML::load(File.open('config/config.yml')) @oauth = ConstantContact::Auth::OAuth2.new( :api_key => cnf['api_key'], :api_secret => cnf['api_secret'], :redirect_url => cnf['redirect_url'] ) @error = params[:error] @user = params[:username] @code = params[:code] if @code begin @lists = [] response = @oauth.get_access_token(@code) @token = response['access_token'] cc = ConstantContact::Api.new(cnf['api_key']) lists = cc.get_lists(@token) if lists lists.each do |list| # Select the first list, by default selected = list == lists.first @lists << { 'id' => list.id, 'name' => list.name, 'selected' => selected } end end rescue => e message = parse_exception(e) @error = "An error occured when saving the contacts : " + message end erb :contacts_multipart else erb :callback end end # Name this action according to your # Constant Contact API Redirect URL, see config.yml post '/cc_callback' do cnf = YAML::load(File.open('config/config.yml')) @error = params[:error] @user = params[:username] @code = params[:code] @token = params[:token] if @code cc = ConstantContact::Api.new(cnf['api_key']) @activity = params[:activity] lists = params[:lists] || {} lists['checkboxes'] = [] if lists['checkboxes'].blank? @lists = [] if lists['ids'] lists['ids'].each do |key, list_id| list_name = lists['names'][key] selected = !(lists['checkboxes'].blank? || lists['checkboxes'][key].blank?) @lists << { 'id' => list_id, 'name' => list_name, 'selected' => selected } end end begin if @activity # Validate raise 'Please select a file' if @activity['file'].blank? file_name = @activity['file'][:filename] contents = @activity['file'][:tempfile].read add_to_lists = [] lists['ids'].each do |key, list_id| add_to_lists << list_id if lists['checkboxes'][key] end add_to_lists = add_to_lists.join(',') if /remove_contacts/.match(file_name) cc.add_remove_contacts_from_lists_activity_from_file(@token, file_name, contents, add_to_lists) elsif /add_contacts/.match(file_name) cc.add_create_contacts_activity_from_file(@token, file_name, contents, add_to_lists) end redirect '/cc_callback' end rescue => e message = parse_exception(e) @error = "An error occured when saving the contacts : " + message #puts e.backtrace end erb :contacts_multipart else erb :callback end end def parse_exception(e) if e.respond_to?(:response) hash_error = JSON.parse(e.response) message = hash_error.first['error_message'] else message = e.message end message.to_s end
Leave a Comment