Voyado
Datafly Signal syncs identified contacts to Voyado Engage server-to-server using the Engage Contacts API (v3). When a visitor identifies themselves — signs up, logs in, or submits a form — Signal creates or updates their Engage contact with their name, email, phone, locale, and marketing-consent preferences.
Voyado’s Engage API is server-side only — client-side calls are blocked by CORS. Signal delivers from your own infrastructure, so the API key never reaches the browser.
Prerequisites
Before configuring Voyado in Signal, you need a Voyado Engage tenant and an API key.
Step 1: Find Your Tenant Name
Your tenant name is the first part of your Engage URL. If you sign in at https://acme.voyado.com, your tenant name is acme. Use the matching staging tenant (https://acme.staging.voyado.com → acme.staging) when testing against a staging environment.
Step 2: Create an API Key
- In Engage, go to Configure > API connections.
- Create a new API key. Voyado recommends a unique key per integration, so name it something identifiable (e.g. “Datafly Signal”).
- Copy the key — you will paste it into Signal.
The API key is sent in the apikey HTTP header. Never put it in a URL or expose it client-side.
Step 3: Confirm Your Contact Type
New contacts are created with a contact type. If you don’t specify one, Engage defaults to Member. If your instance uses a custom contact type for web sign-ups, note its exact name.
Configure in Signal
Configuration Fields
| Field | Required | Description |
|---|---|---|
tenant | Yes | Your Voyado tenant name (e.g. acme for https://acme.voyado.com). |
api_key | Yes | Engage API key from Configure > API connections. Sent in the apikey header. |
contact_type | No | Contact type for new contacts. Defaults to Member if blank. |
Management UI Setup
Add the integration
Go to Integrations > Add Integration > Voyado.
Enter your credentials
Fill in your tenant name and api_key, and optionally a contact_type.
Select consent categories
Choose the consent category that gates marketing (typically marketing). Signal maps the visitor’s marketing-consent decision to Voyado’s acceptsEmail, acceptsSms, and acceptsPostal preferences.
Save
Click Save. The integration is now live.
API Endpoint
POST https://{tenant}.voyado.com/api/v3/contacts?contactType={contact_type}&source=datafly-signalAuthentication is the apikey request header. Each request also sends User-Agent: Datafly-Signal/1.0 and Content-Type: application/json, both required by Engage.
Voyado dedupes contacts on the unique identifier in the body (email or mobilePhone), so sending the same identified visitor again updates the existing contact rather than creating a duplicate.
Identity Signals
Voyado is a first-party CRM and stores raw contact details — it does not accept hashed match keys. Signal sends these fields in plaintext to your own Voyado instance:
| Signal trait | Voyado field | Notes |
|---|---|---|
email | email | Lowercased and trimmed. Primary unique identifier. |
phone | mobilePhone | Normalised to E.164. Paired with countryCode. |
first_name | firstName | |
last_name | lastName | |
country | countryCode | ISO country code; Engage auto-populates the country name. |
user_id | externalId | Your own stable customer ID, stored as Engage externalId. |
| (consent) | preferences.acceptsEmail / acceptsSms / acceptsPostal | Driven by the visitor’s marketing-consent decision. |
Engage requires at least one unique identifier (email or mobilePhone) per contact. Identity events without an email or phone are not delivered.
How to Send Contact Data
Call datafly.identify() when a user signs up, logs in, or submits a form:
datafly.identify("user-123", {
email: "jane.doe@example.com",
phone: "+46 70 123 45 67",
firstName: "Jane",
lastName: "Doe",
country: "SE"
});Event Mapping
The Voyado Contacts API accepts profile data, not behavioural events. Signal therefore delivers only identity-bearing events to Voyado; all other events (page views, product views, purchases) are dropped because they carry no contact identifier.
Default preset
| Signal event | Voyado action |
|---|---|
Signed Up | Create / update contact |
Identified | Create / update contact |
Example: Sign-up
Datafly.js call:
datafly.track("Signed Up", { method: "email" });
// ...with traits previously set via datafly.identify():
datafly.identify("user-123", {
email: "jane.doe@example.com",
phone: "+46 70 123 45 67",
firstName: "Jane",
lastName: "Doe",
country: "SE"
});Voyado payload sent by Signal (visitor granted marketing consent):
{
"email": "jane.doe@example.com",
"firstName": "Jane",
"lastName": "Doe",
"mobilePhone": "+46701234567",
"countryCode": "SE",
"lang": "sv",
"externalId": "user-123",
"preferences": {
"acceptsEmail": true,
"acceptsSms": true,
"acceptsPostal": true
}
}A successful create returns HTTP 201 Created with the full contact record; an update of an existing contact returns the updated contact.
Testing
Use your staging tenant
Point the tenant field at your staging tenant (e.g. acme.staging) so test contacts don’t land in production.
Trigger an identify
Sign up or log in on your site, or fire datafly.identify() from the browser console with a test email.
Verify in Engage
In Engage, search Contacts for the test email. The contact should appear with the name, phone, and consent preferences you sent. Re-running the same identify should update the existing contact, not create a second one.
Troubleshooting
| Problem | Solution |
|---|---|
401 / 403 responses | The apikey is wrong, revoked, or lacks contact permissions. Regenerate it under Configure > API connections. |
404 responses | The tenant name is wrong. Check the first part of your Engage URL and whether you should be using a staging tenant. |
400 responses | The contact is missing a unique identifier — ensure email or phone is set via datafly.identify(). |
| Contact not appearing | Confirm the event is Signed Up or Identified and that traits include an email or phone. Other events are dropped by design. |
| Wrong contact type | Set the contact_type field to a type that exists in your Engage instance. |
| Consent flags wrong | Check the consent category mapped in Signal matches the category your CMP uses for marketing. |