3

I'm trying to import contacts into a contact list in Qualtrics. I am using python to do this.

Token = 'MyToken' #when running the code I put in my actual token and id
ContactsID = 'MyContactsID'

data = open('contacts.json', 'rb')
headers = {'X-API-TOKEN': Token, 'Content-Type':'application/json',}
r = requests.post('https://az1.qualtrics.com/API/v3/mailinglists/' + ContactsID +'/contactimports', headers=headers, data=data)
r.text

This code gives me the following error: '{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Invalid Content-Type. expected=multipart/form-data found=application/json","errorCode":"RP_0.1"},"requestId":null}}'

I changed the content type to multipart/form-data that it says it is expecting and received the response "413", which qualtrics explains means "The request body was too large. This can also happen in cases where a multipart/form-data request is malformed."

I have tested my json and verified that it is valid. Also, I don't know why the request body would be too large because it's only 13 contacts that I'm trying to import. Any ideas?

2 Answers2

2

With the help of Qualtrics Support, I was eventually able to get the following code to work:

Token = 'MyToken' #when running the code I put in my actual token and id
ContactsID = 'MyContactsID'

url = "https://az1.qualtrics.com/API/v3/mailinglists/" + ContactsID + "/contactimports/"
headers = {
   'content-type': "multipart/form-data; boundary=---BOUNDRY",
   'x-api-token': "Token"
   } 
files = {'contacts': ('contacts', open('contacts.json', 'rb'), 'application/json')}
request = requests.post(url, headers=headers, files=files)
print(request.text)

Please note that if you want to use this code, you will need to change "az1" in the URL to your own Qualtrics datacenter ID.

1

You need to use files = .. for a multipart request:

Token = 'MyToken' #when running the code I put in my actual token and id
ContactsID = 'MyContactsID'

data = open('contacts.json', 'rb')
headers = {'X-API-TOKEN': Token}
r = requests.post('https://az1.qualtrics.com/API/v3/mailinglists/' + ContactsID +'/contactimports',files={"file":data}, headers=headers)
r.text

Once you do requests will take care of the rest:

In [36]: url = 'http://httpbin.org/post' 
In [37]: headers = {'X-API-TOKEN': "123456789"}    
In [38]: files = {'file': open('a.csv', 'rb')}    
In [39]: r = requests.post(url, files=files, headers=headers)

In [40]: print r.text
{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "a,b,c\n1,2,3"
  }, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "152", 
    "Content-Type": "multipart/form-data; boundary=3830dbe5fa6141f69d3d85dee4ba6e78", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.10.0", 
    "X-Api-Token": "123456789"
  }, 
  "json": null, 
  "origin": "51.171.98.185", 
  "url": "http://httpbin.org/post"
}


In [41]: print(r.request.body)
--3830dbe5fa6141f69d3d85dee4ba6e78
Content-Disposition: form-data; name="file"; filename="a.csv"

a,b,c
1,2,3
--3830dbe5fa6141f69d3d85dee4ba6e78--

looking at the docs, you actually want something closer to:

Token = 'MyToken' #when running the code I put in my actual token and id
ContactsID = 'MyContactsID'

data = open('contacts.json', 'rb')

files = {'file': ('contact', data ,'application/json', {'X-API-TOKEN': Token})}
r = requests.post('https://az1.qualtrics.com/API/v3/mailinglists/' + ContactsID +'/contactimports',files=files)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321