You can import CSV files with contact data to your audience. This option lets you add new contacts, update existing ones, and create segments based on imported contacts.
Typical use cases:
- Import trade show leads collected at industry events with up-to-date contact preferences.
- Update contact demographic information from your CRM system or third-party data providers.
- Migrate contacts from legacy systems while maintaining consent compliance.
Only the columns that you map to contact attributes are imported to the audience. The Consent column is mapped separately within the Consent object.
File requirements
Your CSV file must meet these specifications:
- Encoding: UTF-8
- Format: CSV, comma-separated
- Header row: Optional
- Maximum size: 5 GB
- Contact information: All contacts must be reachable by email or phone. Contacts with no contact information won't be imported. To learn more about the processing flow, see Prepare contact data for import.
Phone numbers
If a file contains phone numbers, they must be formatted according to the ISO E.164 standard: +[country code][area code][phone number]
.
No spaces, dashes, or special characters are allowed. If the + symbol is missing before a phone number, it will be added automatically in Connect.
Dates
If a file contains dates, they must be in one of the following formats:
YYYY-MM-DD
MM/DD/YYYY
DD/MM/YYYY
YYYY/MM/DD
DD.MM.YYYY
YYYY-MM-DDTHH:mm:ssZ
Tip
Be careful when opening CSV files in Excel as it can automatically convert a date like
02/10/2025
to an unsupported format such as2/10/25
. To prevent this, use a text editing app such as Notepad or Visual Studio Code.
Approaches to consent management
When adding new contacts to the audience, it is important to set proper consent statuses that reflect people's willingness (or refusal) to receive communications from your company.
You can take one of the following approaches when importing contacts from a file.
Approach A: Apply the same status to all contacts
You can set a common consent status to all contacts using the status
property. Here is an example for the Email channel.
{
"consent": {
"channels": {
"channel": "EMAIL",
"status": "OPT_IN_UNVERIFIED"
}
}
}
If your marketing team manages consent on the consent group basis, use the consentGroups
property instead of channels
. The common status will be effective within the consent group you specify.
{
"consent": {
"consentGroups": {
"consentGroupId": "{CONSENT_GROUP_ID}",
"status": "OPT_IN_UNVERIFIED"
}
}
}
To get the IDs of available consent groups, use the dataSets
query. For more information about it, see Query an audience.
query {
dataSets {
nodes {
consentGroups {
name
id
}
}
}
}
{
"data": {
"dataSets": {
"nodes": [
{
"consentGroups": [
{
"name": "Newsletters",
"id": "{CONSENT_GROUP_ID_1}"
},
{
"name": "Promotions",
"id": "{CONSENT_GROUP_ID_2}"
},
{
"name": "Information",
"id": "{CONSENT_GROUP_ID_3}"
},
{
"name": "Custom",
"id": "{CONSENT_GROUP_ID_4}"
}
]
}
]
}
}
}
Warning
When submitting consent preferences, use either consent groups or channels in your mutation. Using both at the same time would result in an error.
Example: A retail company imports 50,000 contacts from a recent marketing campaign. Since all contacts filled out the same opt-in form, the team applies OPT_IN_UNVERIFIED
status to everyone for the Email channel, streamlining the import process.
Approach B: Import statuses from a file
You can import a current consent status for each contact. If you choose to follow this approach, you must add the Consent column to the file and provide one of the following values for each contact: OPT_IN
, OPT_IN_UNVERIFIED
or OPT_OUT
. Do not use null
, N/A
or any other values. If you leave the field blank for a contact, their status for the Email channel will be automatically set to OPT_IN
.
Here is an example for the Email channel. It means that column 6 in the CSV file has consent statuses for the Email channel.
{
"consent": {
"channels": {
"channel": "EMAIL",
"columnIndex": 6
}
}
}
If your marketing team manages consent on the consent group basis, use the consentGroups
property instead of channels
. The following example means that column 6 in the CSV file has consent statuses for the specified consent group.
{
"consent": {
"consentGroups": {
"consentGroupId": "{CONSENT_GROUP_ID}",
"columnIndex": 6
}
}
}
Example: An e-commerce business exports contacts from their legacy CRM system, including historical consent preferences. Each contact has their own consent status (opted in, opted out, or unverified), which needs to be preserved during migration to maintain compliance and customer trust.
Approach C: Ignore consent settings
If you omit the consent
property, all new contacts will be automatically opted in to the Email channel. The statuses of existing contacts will stay unchanged.
Warning
This approach should only be used when you have verified consent through other means and documented the legal basis for communication.
Initial setup
To start importing contacts, you need to establish access to our SFTP server.
- Run the following command in your terminal emulator. Feel free to replace "Acoustic Connect key" with another unique name.
ssh-keygen -t ed25519 -C "Acoustic Connect key" -f key
- Navigate to the directory from which you ran the command and find two new files there: a private key (key) and a public key (key.pub).
Warning
For security reasons, don't share the private key with anyone.
- Run the following mutation to register your public key in our API. Replace "YOUR_PUBLIC_KEY" with the content from key.pub.
mutation updatePublicKey {
updatePublicKeyForConnectUser(
publicKey: "YOUR_PUBLIC_KEY"
) {
publicKey
}
}
{
"data": {
"updatePublicKeyForConnectUser": {
"publicKey": "YOUR_PUBLIC_KEY"
}
}
}
- Create a new connection in an FTP client such as FileZilla. The settings are described below.

- Navigate to the directory allocated for your subscription.
- (optional) Create a sub-directory for contacts.
- Upload your files.
Note
When the import job is completed, the files will be deleted from the SFTP server.
Settings for the SFTP connection
Host
Use a host associated with your Connect domain.
Connect domain | SFTP host |
---|---|
prod-us-east-1 | s-acca2da9ec374c47b.server.transfer.us-east-1.amazonaws.com |
prod-eu-central-1 | s-0f495b8f35324396a.server.transfer.eu-central-1.amazonaws.com |
prod-ap-southeast-2 | s-9596192dde684690a.server.transfer.ap-southeast-2.amazonaws.com |
Other settings
- Protocol: SFTP – SSH File Transfer Protocol
- Port: 22
- Logon type: key file
- Key file: Specify a path to the private key file on your hard drive.
- User: Your Acoustic Connect email address
- Requirements: 3-100 characters, Latin letters, numbers 0-9, underscores (_), hyphens (-), periods (.)
- Not allowed: plus (+), quotes ("), or other special characters
Mutation structure
Example
Let's say you have uploaded the following contact data to the SFTP server.
Contact Key | First Name | Last Name | Phone Number | Last Order | |
---|---|---|---|---|---|
ESX3845 | [email protected] | Kate | Reese | +91555551234 | 2022-02-01T16:04:38Z |
RUT8175 | [email protected] | Maximilian | Tsiolkovsky | +37455551234 | 2024-06-01T16:04:30Z |
BBA0627 | [email protected] | Amalia | Ahmed | +2355551234 | 2024-11-01T16:04:38Z |
ESX4985 | [email protected] | Antonio | |||
BBN8971 | [email protected] | Jillian | S. | +37555551234 | 2025-11-01T16:04:38Z |
PPO4467 | [email protected] | Chris | Jr. |
Use the following mutation to import the file to Connect.
mutation ($importInput: ImportInput!) {
createImportJob(importInput: $importInput) {
id
}
}
{
"data": {
"createImportJob": {
"id": "{JOB_ID}"
}
}
}
The mutation requires a JSON object.
{
"importInput": {
"dataSetId": "{AUDIENCE_ID}",
"jobName": "Import new contacts",
"importType": "ADD_UPDATE",
"createSegment": false,
"fileLocation": {
"type": "SFTP",
"filename": "prospects-03-05-2025.csv",
"folder": "contacts"
},
"consent": {
"enableOverrideExistingOptOut": false,
"channels": {
"channel": "EMAIL",
"status": "OPT_IN_UNVERIFIED"
}
},
"skipFirstRow": true,
"mappings": [
{
"columnIndex": 1,
"attributeName": "Contact Key"
},
{
"columnIndex": 2,
"attributeName": "Email"
},
{
"columnIndex": 3,
"attributeName": "First Name"
},
{
"columnIndex": 4,
"attributeName": "Last Name"
},
{
"columnIndex": 5,
"attributeName": "Phone Number"
},
{
"columnIndex": 6,
"attributeName": "Last Order"
}
]
}
}
Mutation arguments
importInput
(required): A JSON object with import settings.
Import input object
attributes
: Object - Use this object if your file contains new audience attributes.consent
: Object - Consent settings for the contacts.createSegment
(required): Boolean - Lets you create a segment based on the imported contacts. The segment will be available as soon as the import job is complete.dataSetId
(required): String - The ID of your audience.dateFormat
: Enum - Add this property if your file contains dates and their format isn'tYYYY-MM-DDTHH:mm:ssZ
. Valid values:YEAR_MONTH_DAY_DASH_SEPARATED_WITH_TIME
(default),YEAR_MONTH_DAY_DASH_SEPARATED
,MONTH_DAY_YEAR_SLASH_SEPARATED
,DAY_MONTH_YEAR_SLASH_SEPARATED
,YEAR_MONTH_DAY_SLASH_SEPARATED
,DAY_MONTH_YEAR_DOT_SEPARATED
.fileLocation
(required): Object - Use this object to locate the file on the FTP server.importType
(required): Enum - The method of file processing. Valid value:ADD_UPDATE
. TheADD_UPDATE
method lets you add new contacts to the audience and update existing ones.jobName
(required): String - The name you want to assign to the import job.mappings
(required): Array of objects - Create a separate object for each imported attribute.notifications
: Array of objects - Create an object for each recipient you want to add.segmentName
: String - If you setcreateSegment
totrue
, you must assign a name to the new segment.skipFirstRow
: Boolean - Set the value totrue
if the file has a header row (default:false
).
Attributes object
create
: Array of objects - Create new contact attributes during import. Each object in the array supports the following fields:category
: String - Assign an attribute to a category. Use the Query the categories of contact attributes query to get the list of available values.decimalPrecision
: Integer - The number of decimal places to display. Applies to numeric attributes.identifyAs
: Object - See Identification object.name
(required): String - The name of the new attribute.type
(required): Enum - The data type of the attribute. Valid values:TEXT
,NUMBER
,DATE
,BOOLEAN
.
Channels object
Used within the consent
object to manage consent by communication channel.
channel
(required): Enum - The type of communication channel. Valid values:EMAIL
,SMS
,WHATSAPP
.columnIndex
: Integer - The number of the Consent column in your file. If you submit this property, do not use thestatus
property in the same mutation.status
: Enum - Use this field to set a common consent status within the channel for all contacts in the import file. Valid values:OPT_IN
,OPT_IN_UNVERIFIED
,OPT_OUT
. If you submit this property, do not map any consent-related columns to the audience usingcolumnIndex
.
Consent object
Used within the importInput
object to define consent preferences.
channels
: Object - Use this object to submit consent statuses for a particular media channel.channels
cannot be used together withconsentGroups
in the same mutation.consentGroups
: Object - Use this object to submit consent statuses for a particular consent group.consentGroups
cannot be used together withchannels
in the same mutation.enableOverrideExistingOptOut
: Boolean - Set the value totrue
to allow overwriting theOPT_OUT
statuses of existing contacts who previously unsubscribed from receiving communications (default:false
).
Consent groups object
Used within the consent
object to manage consent by consent group.
columnIndex
: Integer - The number of the Consent column in your file. If you submit this property, do not use thestatus
property in the same mutation.consentGroupId
(required): String - The ID of a consent group in your audience.status
: Enum - Use this field to set a common consent status within the consent group for all contacts in the import file. Valid values:OPT_IN
,OPT_IN_UNVERIFIED
,OPT_OUT
. If you submit this property, do not map any consent-related columns to the audience usingcolumnIndex
.
File location object
Used within the importInput
object to specify where the CSV file is located.
filename
(required): String - The name and extension of the file.folder
: String - The subfolder on the SFTP server where the file is located. If you have uploaded the file to the root folder, you don't need this field.type
(required): Enum - The method of file delivery. Valid value:SFTP
.
Identification object
Used within the attributes
object to creating new contact attributes.
channels
: Enum or array of enums - If a text attribute is addressable, specify its communication channel. Valid values:EMAIL
,SMS
,WHATSAPP
. A phone number can be associated with two channels (SMS and WhatsApp).key
: Boolean - Set totrue
if you are adding a key attribute to uniquely identify contacts in the audience.
Mappings object
Used within the importInput
object to map CSV columns to audience attributes.
Both fields are required for each object in the array:
attributeName
(required): String - The name of the audience attribute that the column from your CSV file will be mapped to. If your audience uses contact keys, you must map the key attribute to a file column name.columnIndex
(required): Integer - The index number of the column in the import file.
Notifications object
Used within the importInput
object to configure job completion notifications.
channel
(required): Enum - Add this property if you want to receive a notification when the import job is complete. Valid value:EMAIL
.destination
(required): String - The email address for notification delivery.
Response fields
The mutation returns a JSON response containing:
data
(required): Object - Root response object.createImportJob
(required): Object - Type of operation performed.id
(required): String - The ID assigned to the import job. Use this ID to check the current job status in Connect (Data management > Job monitoring). You will get a configuration summary and a report on how many records have been processed.
Example usage
Let's say your loyalty program categorizes customers as Gold, Silver, or Bronze based on their purchase history. When importing contacts from your CRM, you create the "Customer Tier" attribute and populate it with tier values. By creating a segment of all imported contacts, you can immediately launch a targeted campaign welcoming these loyalty members and offering tier-specific promotions.
{
"importInput": {
"dataSetId": "{AUDIENCE_ID}",
"jobName": "Import contacts with new attribute",
"importType": "ADD_UPDATE",
"createSegment": true,
"segmentName": "Imported contacts - Customer tiers",
"fileLocation": {
"type": "SFTP",
"filename": "contacts-with-tiers.csv",
"folder": "contacts"
},
"consent": {
"enableOverrideExistingOptOut": false,
"channels": {
"channel": "EMAIL",
"status": "OPT_IN_UNVERIFIED"
}
},
"attributes": {
"create": [
{
"name": "Customer Tier",
"type": "TEXT",
"category": "Demographic"
}
]
},
"skipFirstRow": true,
"mappings": [
{
"columnIndex": 1,
"attributeName": "Contact Key"
},
{
"columnIndex": 2,
"attributeName": "Email"
},
{
"columnIndex": 3,
"attributeName": "First Name"
},
{
"columnIndex": 4,
"attributeName": "Last Name"
},
{
"columnIndex": 5,
"attributeName": "Phone Number"
},
{
"columnIndex": 6,
"attributeName": "Last Order"
},
{
"columnIndex": 7,
"attributeName": "Customer Tier"
}
]
}
}