Bulk write contacts API
To create multiple contacts at once, the /contacts/bulk API endpoint can be used.
POST /api/v2/contacts/bulk
You can also use this same endpoint to update multiple existing contacts at once:
PATCH /api/v2/contacts/bulk
Caution
The maximum number of contacts allowed in one bulk request is 4000. The rate limit for this endpoint is the same as for other endpoints.
Caution
If you are planning to do a large migration of contacts, and you have an XML export activated, first get in touch with your Voyado team.
Query string parameters
There are two optional parameters that can be added to the query string:
avoidTriggeringExport: This prevents your bulk contact request from triggering the BI and XML contact exports. The default value is "false" so you only need to include this if you want it to be true. You can read more about this parameter here.
Caution
The avoidTriggeringExport parameter only has an effect when doing a bulk update (that is, when using the PATCH operation).
contactType: This allows you to specify the contact type of the contacts you are creating (or updating). If not specified, your default contact type configured in Engage will be used.
A request using these parameters (a bulk update in this case) would look like this:
PATCH /api/v2/contacts/bulk?avoidTriggeringExport=true&contactType=Contact
In this example, all the contacts updated will be of contactType "Contact".
Creation payload
The data needed to bulk create contacts has the same requirements as when creating an individual contact using the /contacts endpoint. This means, at a bare minimum, that the key attribute must be included in the payload (in this case, it's email).
See the create contact page on the recommended way to create contacts.
This is a basic bulk creation payload:
[ { "firstName": "Anna", "lastName": "Arkberg", "city": "Examplecity", "email": "anna@example.com" }, { "firstName": "Berit", "lastName": "Berlucci", "city": "Examplecity", "email": "berit@example.com" } ]
If you have specified a contactType in the query string then all these new contacts will be created with that type. If it's not specified, the new contacts will all be created using whatever default contactType you have configured in Engage.
Consents and preferences
There is an important difference between creating contacts individually with the contacts endpoint and creating them in bulk using the contacts/bulk endpoint discussed here.
Consents and preferences are sent as object arrays in the basic create endpoint:
{ "firstName": "Anna", "lastName": "Arkberg", "city": "Examplecity", "email": "anna@example.com", "preferences": { "acceptsEmail": true, "acceptsPostal": true, "acceptsSms": true }, "consents": [{ "id": "memberConsent", "value": true, "date": "2022-01-01T00:00:00+0100", "source": "ECOM", "comment": "Approved member terms at checkout" }] }
But in the bulk API case contact data is sent "flat", as can be seen here in these two contacts:
[ { "firstName": "Anna", "lastName": "Arkberg", "city": "Examplecity", "email": "anna@example.com", "acceptsEmail":true, "acceptsPostal":false, "acceptsSms":false, "memberConsent":true }, { "firstName": "Berit", "lastName": "Berlucci", "city": "Examplecity", "email": "berit@example.com", "acceptsEmail":true, "acceptsPostal":false, "acceptsSms":true, "memberConsent":false } ]
Note that here memberConsent is sent as an attribute and a value, not as an object. In Engage, this consent's date attribute will be the date of the bulk import and the source will be set to "Import".
Caution
In Engage, the consents acceptsEmail and acceptsSms should not be changed from "true" to "false" unless the contact has actively opted out of communication, for example through My Pages or by unchecking a pre-selected opt-in during checkout.
Update payload
When doing a bulk update through the API, you will need to specify the unique contact ID for each contact, along with the value or values you want to change.
Warning
When updating contacts over the API be sure to ONLY send the fields you want to update and nothing else. This applies for individual as well as bulk updates. Any empty fields added to your update payload (string.Empty, null, "" or whatever) will overwrite the current values on the contact. If you do not want to change a field, then do not add it to the update call.
[ { "contactId": "a9cc2989-6a39-4168-b48d-afda77a0139c", "lastName": "Berg", "city": "Exampelopolis" }, { "contactId": "4823f5ab-9d03-41d2-ae1f-afda99a013cb", "lastName": "Ek", "city": "Exampelholm" }, { "contactId": "8afa642d-d4e2-4040-a573-2dc20ea6b9a0", "lastName": "Sten", "city": "Exampelholm" } ]
Warning
All items in a bulk contact update must have the same properties, as seen in the example above. If they don't, a HTTP 422: Properties differ between contacts error will be thrown and you risk some contact data becoming overwritten with empty values.
Warning
All contacts sent in a bulk update must have the same contactType. You either send this in the query string, or else not specify it and the default value will be used. This means you cannot mix contacts of different contactType in the same bulk update request.
Full update payload example
Here is a full update payload with all the contact attributes you can send.
Important
In practice, you'll rarely send all of these attributes at once in a contact update, and will just be updating some of them. The complete list shown here is just for reference.
[ { "street": "Example Avenue 12", "lastName": "Person", "firstName": "Test", "zipCode": "string", "careOf": "careOf", "city": "Examplecity", "countryCode": "SE", "consent": "true", "acceptsEmail":true, "acceptsPostal":false, "acceptsSms":false, "email": "test.person@test.com", "mobilePhone": "+46700111222", "age": 65, "birthDay": "2004-04-11", "gender": "Female", "socialSecurityNumber": "190703316893", "discoveryKey": "87bd3b56-a1fd-4060-9962-4f08ef047251", "lang": "en", "registrationStoreId": "SE", "labels": "Label1,Label2" } ]
Responses
If your request has been successful, you'll get a 202: Accepted response. Your data is now ready for processing. A unique batch ID for your request will also be returned as a GUID.
Caution
Save this batch ID as you'll need it to check the status of your batch job.
If the request has not been successful, you'll get one of the following HTTP error codes:
422: UnprocessableEntity
503: ServiceUnavailable
Status
Your batch job can take time to be processed. You can check the current status of the job by calling this endpoint with the batch ID:
GET /api/v2/contacts/bulk/status?batchId={batchId}
This will return an object containing one of the following:
"status": "Received": Your payload has been received.
"status": "InProgress": Processing of your data is in progress.
"status": "Done": Your contacts should now be created / updated.
"status": "The request is invalid.": The batch ID you sent could not be found.
"status": "Error": There was an error.
The progress of your batch will be recorded in the integration log.
The log is especially useful when finding out what happened if things go wrong. Read about the integration log here.
Starting the job
Once you get back a status of "Received" your data is ready to be processed. This happens on a schedule, so it might not be completed right away. Keep checking the /status endpoint to see when it's done.
Wrong contact type
Note
If a bulk update contains a contact of the wrong contactType, that contact will be skipped and the job will continue.
Contacts that already exists
Note
If a bulk update contains a contact that already exists in Engage, that contact will be skipped and the job will continue.