The Problem: You’re attempting to import data into HubSpot CRM using their API, but receive a 415 Unsupported Media Type error. Your current code uses application/json, which is incorrect for file uploads.
Understanding the “Why” (The Root Cause):
The HubSpot CRM import API expects data to be sent using multipart/form-data encoding for file uploads. Your code incorrectly attempts to send the CSV data within a JSON payload. The 415 Unsupported Media Type error indicates the server doesn’t recognize the application/json content type when it expects a file upload. Even if the content type were correct, embedding the CSV data directly into the JSON body isn’t how the HubSpot API handles file imports. The API requires both the import configuration (in JSON format) and the actual CSV file to be sent as separate parts of a single multipart request.
Step-by-Step Guide:
Step 1: Correct the Request and File Handling: The following code demonstrates the correct way to upload your CSV data to HubSpot using the requests library. It uses the files parameter to send both the CSV file and the JSON import request configuration in a single multipart/form-data request. Crucially, it reads the CSV file’s contents into memory before sending it, ensuring the API receives the data correctly. We also use a more robust error handling mechanism to provide clear feedback based on the server response.
from io import StringIO
import requests
import json
import pandas as pd
#Load your CSV into a pandas DataFrame
my_dataframe = pd.read_csv("contact_upload.csv")
#Convert the DataFrame to CSV in memory
csv_buffer = StringIO()
my_dataframe.to_csv(csv_buffer, index=False)
csv_content = csv_buffer.getvalue()
hubspot_token = 'your_hubspot_token' #Replace with your actual token
import_url = 'https://api.hubapi.com/crm/v3/imports' #Note: HTTPS
files = {
'files': ('contacts.csv', csv_content, 'text/csv'),
'importRequest': (None, json.dumps({
"name": "bulk_contact_import",
"columnMappings": [
{"ignored": False, "columnName": "Name", "propertyName": "firstname"},
{"ignored": False, "columnName": "Website", "propertyName": "website"},
{"ignored": False, "columnName": "Age", "propertyName": "age_field"}
# Add more mappings as needed...
]
}), 'application/json')
}
headers = {
'Authorization': f'Bearer {hubspot_token}'
}
response = requests.post(import_url, files=files, headers=headers)
if response.status_code == 200:
print('Upload completed successfully!')
print(response.json()) # Inspect the response for success details.
elif response.status_code == 400: # Example specific error handling
print(f"Bad Request: {response.json()}")
elif response.status_code == 401: # Example specific error handling
print("Unauthorized: Check your HubSpot token")
else:
print(f'Upload failed: {response.status_code} - {response.text}')
print(response.headers) #Inspect headers for any clues.
Step 2: Verify DataFrame Columns: Ensure that the column names in your pandas DataFrame (my_dataframe) precisely match the property names in your HubSpot CRM. Even minor discrepancies (case sensitivity, extra spaces) will cause import failures. Test with a small subset of your data first to pinpoint mapping issues.
Step 3: Authenticate Correctly: Double-check that your_hubspot_token is a valid and correctly formatted HubSpot API key with the necessary permissions for contact imports.
Step 4: Handle Potential Errors: Implement more robust error handling to address various HTTP status codes and API responses. The example shows basic handling of 400 and 401 errors but you should add more sophisticated error checks for various HubSpot API error codes.
Common Pitfalls & What to Check Next:
- Authentication: Incorrect or missing
hubspot_token.
- Rate Limits: HubSpot API has rate limits. For large datasets, consider pagination or batch processing.
- Data Validation: Thoroughly validate your data before importing. Check for data types, missing values, and inconsistencies.
- HubSpot Property Names: Confirm that all property names in your CSV match the exact names of your HubSpot properties. Use the HubSpot API to retrieve a list of your contact properties if needed.
- Character Encoding: Ensure your CSV file is encoded as UTF-8 without a Byte Order Mark (BOM).
Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!