1. Introduction
The cross device network(XDN) provides functionality to import data in three ways.
It currently has two options for importing attribute data(e.g. cookies and hashed emails) via the Trusted Third Party:
-
by executing an HTTP request for each login event, usually executed from the end user’s browser/device
-
by uploading bulk data containing many ids at once, usually executed directly by a partner. Additionally, the onboarding of non-cookie data for the creation of custom segments is supported.
The data always has to pass through a Trusted Third Party to ensure that no plain text email address can be found in the xDN.
The services are described in detail below.
If you have questions or feedback please do not hesitate to contact us.
2. Single event data (realtime)
2.1. Direct API Call
You can use this API to send single events in (near) realtime, usually shortly after a user has performed a login using his email address. The API can be called from the user’s browser (clientside) or server-to-server from your backend systems. However, for clientside integrations we recommend using the tracking script instead (see emetriq provided Tracking-Script)
This service expects a GET request using the following syntax:
https://xdn-ttp.de/lns/import-event-<partner>?guid=<guid>&adf=<adformId>&wtk=<webtrekkId>&gdpr=<0|1>&gdpr_consent=<consent_string>[&idfa=...]
<partner>-
This is a special ID assigned to the partner by emetriq.
<guid>-
a
Base64encodedSHA-256of user’s email address (in lower case andUTF-8encoded). For event imports it is necessary to URL encode it. See Example GUID hashing for comparing your implementation with expected results. <gdpr>-
0 signals GDPR does not apply in the user’s country, 1 signals GDPR applies in the user’s country
<gdpr_consent>-
a
Base64encoded string which represents the consent string of the user (IAB TCF V2.0) <adformId>,<webtrekkId>,[…]-
any other IDs that the partner wants to transmit to the xDN. The number of URL parameters may vary. Refer to Parameters for a list of valid IDs.
The TTP will respond with a HTTP 302 response. The redirect-URL, that the HTTP client (usually the
user’s browser) gets returned, can be found at the Location headerfield and looks like the following example:
https://lns-ev.xplosion.de/xdn-import/import-event?partner=<partner>guid=<hashed>&adf=<adf-id>&wtk=<adf-id>
|
Note
|
The IDs will be validated. In case the TTP detects invalid IDs the redirect URL will only contain the valid ones. |
2.2. emetriq provided Tracking-Script
We provide a tracking-pixel script for easy integration of the event import.
If your website has an IAB TCFv2 compatible cmp available, the gdpr as well as the gdpr_consent parameter are filled automatically by the tracking pixel and do not have to be added to the call.
Also, if the guid parameter is passed as clear-text, it will be hashed before sending it to the API.
| environment | Script-Tag |
|---|---|
prod |
<script type="text/javascript" src="&idfa=…"></script> |
<partner>-
This is a special ID assigned to the partner by emetriq.
<guid>-
a
Base64encodedSHA-256of user’s email address (in lower case andUTF-8encoded). For event imports it is necessary to URL encode it. See Example GUID hashing for comparing your implementation with expected results. If the guid is passed in plain text, it will automatically be encoded <guid>,<idfa>,[…]-
any other IDs that the partner wants to transmit to the xDN. The number of URL parameters may vary. Refer to Parameters for a list of valid IDs.
<gdpr>-
(optional if using a TCFv2 compatible CMP) 0 signals GDPR does not apply in the user’s country, 1 signals GDPR applies in the user’s country
<gdpr_consent>-
(optional if using a TCFv2 compatible CMP) a
Base64encoded string which represents the consent string of the user (IAB TCF V2.0)
3. Bulk data
3.1. Credential Management
All bulk endpoints require authentication to be used.
During the onboarding phase a temporary password and a username are sent to the provided e-mail address. Please log in once to verify your account and change the password using the URL given below. After setting the password you can start using the credentials for the API.
| environment | URL |
|---|---|
prod |
Resetting passwords
Click the forgot password link on the login page to request a new password.
Changing the associated e-mail address
Notify the support team to request changing the e-mail address.
3.2. Login data
The service expects a secure PUT request using the following syntax:
https://xdn-ttp.de/import/<partner> @body: gzipped text file
This endpoint is protected with HTTP basic authentication (see Authentication).
-
The format is:
<idtype>|<idtype>(|<idtype>)*|<gdpr>|<gdpr_consent>(|ip)(|event_day)
-
For example:
guid|adid|gdpr|gdpr_consent|ip|event_day 13E17D5C3E84C647EC3CFE83|8fcd9161-4361-48bd-9dd4-aa190a6ffe4b|1|COslbOslbAAAAAENAHCAAAAAAAAAAAAAAAAAAAAA|95.116.57.21|2022-05-31 23E17D5C3E84C647EC3CFE83|33c8a20d-5694-45af-ac06-5d95050649d8|1|COslbOslbAAAfAENAHCAAAAAAAAAAAAAAAAAAAAA|95.116.57.22|2022-05-31
guid|idfa|adid|gdpr|gdpr_consent 83E17D5C3E84C647EC3CGO64|33C8A20D-5694-45AF-AC06-5D95050649D8|aa200052-683a-47b3-afc9-447aa19e1e47|1|COslbOslbAAA4AENAHCAAAAAAAAAAAAAAAAAAAAA 33E17D5C3E84C647EC3CFE83||aa200052-683a-47b3-afc9-447aa19e1e47|1|COslbOslbAAA4AENAHCAAAAAAAAAAAAAAAAAAAAA 42E17D5C3E84C647EC3CFE92|33C8A20D-5694-45AF-AC06-5D95050649D8||1|COslbOslbAAA4AENAHCAAAAAAAAAAAAAAAAAAAAA
-
example curl command:
curl -u user \ -X PUT \ "https://xdn-ttp.de/import/<partner>" \ -H "Content-Type: application/text" \ -H "Content-Encoding: gzip" \ --upload-file <path_to_gzipped_file>
For a list of idtypes, please refer to the list of Parameters.
|
Note
|
ip: the user’s public IP address (Ipv4 or Ipv6) in plain text (optional). If the field is specified, event_day must be specified as well.
|
|
Note
|
event_day is the day in UTC the event occurred. Should only be specified if ip is given.
|
|
Note
|
For performance reasons, please make sure to batch users per upload (with a maximum of 128 MB per PUT request).
|
Authentication
See Credential Management for details about access to the xDN.
Requests have to provide an HTTP basic authentication header. The value <username>:<password> must be Base64 encoded.
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
3.3. Segment data
|
Note
|
Deprecated. Please migrate to ID agnostic logins with meta data upload. |
The service awaits a secure PUT request using the following syntax:
https://xdn-ttp.de/data-onboarding/<partner>?segment-id=<segment-id> @body: gzipped text file
The segment-id parameter should be a unique identifier that you can choose to identify a segment, for example "existing_customers".
The data should be uploaded in a text file with one GUID (see Parameters) per line. The file should be gzipped.
Additionally, the service provides a secure PUT testupload endpoint for testing and analytic purposes.
https://xdn-ttp.de/test-data-onboarding/<partner>?segment-id=<segment-id> @body: gzipped text file``
Files uploaded to this endpoint will be matched against the xDN to provide guidance on how many matches can be expected when uploading against the data-onboarding above.
-
example curl command:
curl -u user \ -X PUT \ "https://xdn-ttp.de/[test-]data-onboarding/<partner>?segment-id=<segment-id>" \ -H "Content-Type: application/text" \ -H "Content-Encoding: gzip" \ --upload-file <path_to_gzipped_file>
3.4. Mobile Ad Identifier data
|
Note
|
Deprecated. Please migrate to ID agnostic logins with meta data upload. |
The service awaits a secure PUT request using the following syntax:
https://xdn-ttp.de/data-onboarding/maid-data-activation/<partner>?segment-id=<segment-id> @body: gzipped text file
The segment-id parameter should be a unique identifier that you can choose to identify a segment, for example "existing_customers".
The data should be uploaded as a file with one mobile ad identifier and its type per line. The file should be gzipped.
-
Formatting examples can be seen below:
01234567-1234-1444-abcd-89abcdef0123, idfa 76543210-1234-2321-ef01-98abcDEf0123, adid 76543210-1234-3321-ef01-a23456abcdef,adid 76543210-aBCd-4321-ef01-b9aBcdef0123,idfa
-
example curl command:
curl -u user \ -X PUT \ "https://xdn-ttp.de/data-onboarding/maid-data-activation/<partner>?segment-id=<segment-id>" \ -H "Content-Type: application/text" \ -H "Content-Encoding: gzip" \ --upload-file <path_to_gzipped_file>
3.5. Logins with meta data
|
Note
|
Deprecated. Please migrate to ID agnostic logins with meta data upload. |
The service awaits a secure PUT request using the following syntax:
https://xdn-ttp.de/data-onboarding/<partner>?export-name=<export-name> @body: gzipped text file
This endpoint is protected by HTTP basic authentication. The username and password for your partner id can be requested directly at emetriq (see Authentication).
The export-name parameter should be a unique identifier that you can choose to identify an upload, for example "my_customers".
The data should be uploaded in a text file with one GUID (see Parameters) and meta data per line which is pipe separated. Meta Data is a key_value store which is comma separated. Example:
13E17D5C3E84C647EC3CFE83ED7A75715BFCD6849E435EEC90B02E090FA3D036|{"key": "value"},{"key2": "value2"},{"key3": "value3"}
23E17D5C3E84C647EC3CFE83ED7A75715BFCD6849E435EEC90B02E090FA3D036|{"key": "value"},{"key2": "value2"},{"key3": "value3"}
33E17D5C3E84C647EC3CFE83ED7A75715BFCD6849E435EEC90B02E090FA3D036|{"key": "value"},{"key2": "value2"},{"key3": "value3"}
-
example curl command:
curl -u user \ -X PUT \ "https://xdn-ttp.de/data-onboarding/<partner>?export-name=<export-name>" \ -H "Content-Type: application/text" \ -H "Content-Encoding: gzip" \ --upload-file <path_to_gzipped_file>
3.6. ID agnostic logins with meta data
The service awaits a secure PUT request using the following syntax:
https://xdn-ttp.de/id-agnostic-data-activation/<partner>/<idtype>?export-name=<export-name> @body: gzipped csv file
The <partner> path parameter represents your partner id provided by emetriq. The <idtype> path parameter represents the type of id contained in this upload. Please keep in mind, that only a single type of id can be transferred per upload.
This endpoint is protected by HTTP basic authentication. The username and password for your partner id can be requested directly at emetriq (see Authentication).
The export-name parameter should be a unique identifier that you can choose to identify an upload, for example "my_customers".
The data should be uploaded as a pipe separated, gzipped csv file with a header line containing at least a column named id.
Additionally, one can provide information about the id via added columns.
The content should contain one ID (see Parameters) per line, additional information can be provided via the columns defined in the header row.
Example:
id|date|plz some-id|1969-03-19|12345 another-id|2009-03-21|76543
-
example curl command:
curl -u user \ -X PUT \ "https://xdn-ttp.de/id-agnostic-data-activation/<partner>/<idtype>?export-name=<export-name>" \ -H "Content-Type: application/text" \ -H "Content-Encoding: gzip" \ --upload-file <path_to_gzipped_file>
Authentication
See Credential Management for details about access to the xDN.
Requests have to provide an HTTP basic authentication header. The value <username>:<password> must be Base64 encoded.
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Appendix A: Example GUID hashing
For the best performance of the xDN it is important to make sure that the hashing involved in the creation of the GUID is identical across all involved parties.
SHA-256 and Base64 must be applied to all E-mail addresses (see Parameters) before uploading, regardless of the
interface. Additionally, URL enconding must be applied if the guid is sent as part of a query string
(see Single event data (realtime)).
Input string: mail SHA-256 + Base64 encoded string: ANjT8Rc50vNTcJmYK0Z0wp/Fmo/aNQ/KE3lhOtuwkRk= URL encoded string: ANjT8Rc50vNTcJmYK0Z0wp%2FFmo%2FaNQ%2FKE3lhOtuwkRk%3D
Input string: MAIL SHA-256 + Base64 encoded string: ANjT8Rc50vNTcJmYK0Z0wp/Fmo/aNQ/KE3lhOtuwkRk= URL encoded string: ANjT8Rc50vNTcJmYK0Z0wp%2FFmo%2FaNQ%2FKE3lhOtuwkRk%3D
Input string: mail@mail.mail SHA-256 + Base64 encoded string: MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk= URL encoded string: MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D
Input string: MAIL@MAIL.MAIL SHA-256 + Base64 encoded string: MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk= URL encoded string: MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D
Input string: mail-mail@mail.mail SHA-256 + Base64 encoded string: 0rrzLTV+7ZAzq94LOIBv+om+6keiwJWaPaYWV8fHx7E= URL encoded string: 0rrzLTV%2B7ZAzq94LOIBv%2Bom%2B6keiwJWaPaYWV8fHx7E%3D
Input string: xdn-support@emetriq.com SHA-256 + Base64 encoded string: I+F9XD6ExkfsPP6D7Xp1cVv81oSeQ17skLAuCQ+j0DY= URL encoded SHA-256 + Base64 encoded string: I%2BF9XD6ExkfsPP6D7Xp1cVv81oSeQ17skLAuCQ%2Bj0DY%3D
A.1. Code Examples
import hashlib
import base64
import urllib
sha256_and_b64 = base64.b64encode(hashlib.sha256('MAIL@MAIL.MAIL'.lower()).digest())
assert sha256_and_b64 == 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk='
url_encoded_string = urllib.quote_plus(sha256_and_b64)
assert url_encoded_string == 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D'
import hashlib
import base64
from urllib.parse import quote_plus
sha256_and_b64 = base64.b64encode(hashlib.sha256(b'MAIL@MAIL.MAIL'.lower()).digest()).decode('utf-8')
assert sha256_and_b64 == 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk='
url_encoded_string = quote_plus(sha256_and_b64)
assert url_encoded_string == 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D'
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class HashingExample{
public static void main(String args[]){
try {
String sha256AndB64 = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest("MAIL@MAIL.MAIL".toLowerCase().getBytes(StandardCharsets.UTF_8)));
assert sha256AndB64.equals("MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk=");
String urlEncodedString = URLEncoder.encode(sha256AndB64, "UTF-8");
assert urlEncodedString.equals("MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D");
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e){
e.printStackTrace();
}
}
}
const sha256_and_b64 = sjcl.codec.base64.fromBits(sjcl.hash.sha256.hash("MAIL@MAIL.MAIL".toLowerCase()));
if (sha256_and_b64 !== "MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk=") {
throw new Error("invalid hash")
}
const url_encoded_string = encodeURIComponent(sha256_and_b64);
if (url_encoded_string !== 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D') {
throw new Error("invalid encoded")
}
const crypto = require('crypto')
const sha256_and_b64 = crypto.createHash('sha256').update('MAIL@MAIL.MAIL'.toLowerCase()).digest('base64');
if (sha256_and_b64 !== "MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk=") {
throw new Error("invalid hash")
}
const url_encoded_string = encodeURIComponent(sha256_and_b64);
if (url_encoded_string !== 'MtyIVbYaGCezip0joJQwmLCrPYrDeWGyDJBH5ZqbKZk%3D') {
throw new Error("invalid encoded")
}
Appendix B: Parameters
Proper care must be taken that non-URL-safe characters are correctly URL-encoded.
|
Note
|
The IDs will be validated. In case of an invalid ID it will return an HTTP status code 206 and the ID will not be considered. |
| Name | Hashed | Description |
|---|---|---|
|
yes |
The hashed email value. The email address in lowercase must be |
|
no |
Google Android Advertisement ID. Also used for Amazon FireOS AdID*. |
|
no |
iOS Identifier for Advertising for Apple mobile / AppleTV. |
|
no |
|
|
no |
|
|
no |
|
|
no |
|
|
no |
|
|
no |
|
|
no |
|
|
no |
|
|
no |
Auxiliary ID for joining web and batch based import data. |
|
no |
|
|
no |
Unified ID 1.0 formerly known as Trade Desk ID – ttd |
|
no |
Xandr Identifier |
|
no |
TIFA for Samsung (Tizen) SmartTV |
|
no |
|
|
no |
Id5 Identifier |
B.1. Overwriting timestamps
All events that are transmitted are tagged with the current timestamp on arrival. This can be overwritten with the espts parameter.
|
Note
|
Overwriting timestamps should only be used to tag events that happened in the past. |
Appendix C: Trusted Third Party (TTP)
The Trusted Third Party(TTP) is a service operated by AdCert that acts as a trustee between the partner and emetriq to make sure that emetriq does not get in contact with any unencrypted data.
C.1. Data Privacy Report
During the conceptualization of the XDN product it was paramount for the involved founding parties that the new product would be according to the new EU privacy regulations. At the time, the General Data Protection Regulation(GDPR) was already ratified by the EU and its members and it was just months until it would be enforced. Therefore, the expertise of an independent attorney at law was necessary to ensure that the product upholds the protection of the collected data. The resulting data privacy report (dt. Datenschutzgutachten) was the foundation for the architecture of the product involving the TTP as an acting trustee to mediate between the parties. Without the TTP it becomes questionable if the XDN is truly protecting the collected data. The report is shared with all active partners of the XDN.
C.2. Measures to ensure data protection
Since the TTP is processing all incoming and outgoing data from the XDN, there are technical and organizational measures in place to protect the service from tampering, access and data leaks.
C.3. AdCert
AdCert is the operator of the TTP and holds the salt and keystore for the hashing and encryption, respectively. The company is under the supervision of a data privacy attorney who was involved in the conceptualization and inception of the XDN from the start. Furthermore, AdCert and the data privacy attorney were the authors of the Data Privacy Report.
Last modified: 2026-03-12