Edit in GitHubLog an issue

User identification and bucketing

User Identification#

There are multiple ways in which a user can be identified within Adobe Target. Target uses the following identifiers:

Field NameDescription
tntIDThe tntId is the primary identifier in Target for a user. You can supply this ID, or Target will auto-generate it if the request doesn’t contain one.
thirdPartyIdThe thirdPartyId is your company’s identifier for the user, which you can send with every call. When a user logs in to a company's site, the company typically creates an ID that is tied to the visitor's account, loyalty card, membership number, or other applicable identifiers for that company.
marketingCloudVisitorIdThe marketingCloudVisitorId is used to merge and share data between different Adobe solutions. The marketingCloudVisitorId is required for integrations with Adobe Analytics and Adobe Audience Manager.
customerIdsAlong with the Experience Cloud Visitor ID, additional customer IDs and an authenticated status for each visitor can also be utilized.

Target ID (tntID)#

The Target ID, or tntId, can be considered a device ID. This tntId is generated automatically by Adobe Target if it is not provided in the request. Subsequent requests need to include this tntId in order for the right content to be delivered to a device used by the same user.

The following sample call demonstrates a situation in which a tntId is not passed to Target.

Node.js SDK#

Copied to your clipboard
1const TargetClient = require("@adobe/target-nodejs-sdk");
2
3const CONFIG = {
4 client: "acmeclient",
5 organizationId: "1234567890@AdobeOrg"
6};
7
8const targetClient = TargetClient.create(CONFIG);
9
10targetClient.getOffers({
11 request: {
12 execute: {
13 mboxes: [{
14 name: "some-mbox"
15 }]
16 }
17 }
18})
19.then(console.log)
20.catch(console.error);

Java SDK#

Copied to your clipboard
1ClientConfig config = ClientConfig.builder()
2 .client("acmeclient")
3 .organizationId("1234567890@AdobeOrg")
4 .build();
5TargetClient targetClient = TargetClient.create(config);
6
7Context context = new Context().channel(ChannelType.WEB);
8MboxRequest mbox = new MboxRequest()
9 .name("some-mbox")
10 .index(0);
11ExecuteRequest executeRequest = new ExecuteRequest()
12 .mboxes(Arrays.asList(mbox));
13
14TargetDeliveryRequest request = TargetDeliveryRequest.builder()
15 .context(context)
16 .execute(executeRequest)
17 .build();
18
19TargetDeliveryResponse offers = targetClient.getOffers(request);

In the absence of a tntId, Adobe Target generates a tntId and provides it in the response, as follows.

Copied to your clipboard
1{
2 "status": 200,
3 "requestId": "5b586f83-890c-46ae-93a2-610b1caa43ef",
4 "client": "acmeclient",
5 "id": {
6 "tntId": "10abf6304b2714215b1fd39a870f01afc.35_0"
7 },
8 "edgeHost": "mboxedge35.tt.omtrdc.net",
9 ...
10}

In this example, the generated tntId is 10abf6304b2714215b1fd39a870f01afc.35_0. Please note this tntId needs to be used for the same user across sessions.

Third Party ID (thirdPartyId)#

If your organization uses an ID to identify your visitor, you can use thirdPartyID to deliver content. At hirdPartyID is a persistent ID that your business utilizes to identify an end user, regardless of whether they interact with your business from web, mobile, or IoT channels. In other words, the thirdPartyId references user profile data that can be utilized across channels. However, you must provide the thirdPartyID for every Adobe Target Delivery API call you make.

The following sample call demonstrates the use of a thirdPartyId.

Node.js SDK#

Copied to your clipboard
1const TargetClient = require("@adobe/target-nodejs-sdk");
2
3const CONFIG = {
4 client: "acmeclient",
5 organizationId: "1234567890@AdobeOrg"
6};
7
8const targetClient = TargetClient.create(CONFIG);
9
10targetClient.getOffers({
11 request: {
12 id: {
13 thirdPartyId: "B234A029348"
14 },
15 execute: {
16 mboxes: [{
17 name: "some-mbox"
18 }]
19 }
20 }
21})
22.then(console.log)
23.catch(console.error);

Java SDK#

Copied to your clipboard
1ClientConfig config = ClientConfig.builder()
2 .client("acmeclient")
3 .organizationId("1234567890@AdobeOrg")
4 .build();
5TargetClient targetClient = TargetClient.create(config);
6
7VisitorId id = new VisitorId()
8 .thirdPartyId("B234A029348");
9Context context = new Context().channel(ChannelType.WEB);
10MboxRequest mbox = new MboxRequest()
11 .name("some-mbox")
12 .index(0);
13ExecuteRequest executeRequest = new ExecuteRequest()
14 .mboxes(Arrays.asList(mbox));
15
16TargetDeliveryRequest request = TargetDeliveryRequest.builder()
17 .context(context)
18 .execute(executeRequest)
19 .build();
20
21TargetDeliveryResponse offers = targetClient.getOffers(request);

In this scenario, Adobe Target will generate a tntId since it was not passed into the original call, which will be mapped to the provided thirdPartyId.

Marketing Cloud Visitor ID (marketingCloudVisitorId)#

The marketingCloudVisitorId is a universal and persistent ID that identifies your visitors across all solutions in the Adobe Experience Cloud. When your organization implements the ID service, this ID lets you identify the same site visitor and their data in different Experience Cloud solutions, including Adobe Target, Adobe Analytics, and Adobe Audience Manager. Please note the marketingCloudVisitorId is required when integrating Target with Analytics and Audience Manager.

The following sample call demonstrates how a marketingCloudVisitorId that was retrieved from the Experience Cloud ID Service is passed to Target.

Node.js SDK#

Copied to your clipboard
1const TargetClient = require("@adobe/target-nodejs-sdk");
2
3const CONFIG = {
4 client: "acmeclient",
5 organizationId: "1234567890@AdobeOrg"
6};
7
8const targetClient = TargetClient.create(CONFIG);
9
10targetClient.getOffers({
11 request: {
12 id: {
13 marketingCloudVisitorId: "10527837386392355901041112038610706884"
14 },
15 execute: {
16 mboxes: [{
17 name: "some-mbox"
18 }]
19 }
20 }
21})
22.then(console.log)
23.catch(console.error);

Java SDK#

Copied to your clipboard
1ClientConfig config = ClientConfig.builder()
2 .client("acmeclient")
3 .organizationId("1234567890@AdobeOrg")
4 .build();
5TargetClient targetClient = TargetClient.create(config);
6
7VisitorId id = new VisitorId()
8 .marketingCloudVisitorId("10527837386392355901041112038610706884");
9Context context = new Context().channel(ChannelType.WEB);
10MboxRequest mbox = new MboxRequest()
11 .name("some-mbox")
12 .index(0);
13ExecuteRequest executeRequest = new ExecuteRequest()
14 .mboxes(Arrays.asList(mbox));
15
16TargetDeliveryRequest request = TargetDeliveryRequest.builder()
17 .context(context)
18 .execute(executeRequest)
19 .build();
20
21TargetDeliveryResponse offers = targetClient.getOffers(request);

In this scenario, Target will generate a tntId since it was not passed into the original call, which will be mapped to the provided marketingCloudVisitorId.

Customer ID (customerIds)#

Customer IDs can be added to, or associated with, an Experience Cloud Visitor ID. Whenever sending customerIds, the marketingCloudVisitorId must also be provided. Furthermore, an authentication status can be provided along with each customerId for each visitor. The following authentication statuses may be used:

Authentication StatusUser Status
unknownUnknown or never authenticated. This state can be used for scenarios such as that in which a visitor lands on your site by clicking a display advert.
authenticatedThe user is currently authenticated with an active session on your website or app.
logged_outThe user was authenticated but actively logged out. The user intended to disconnect from the authenticated state. The user no longer wants to be treated as authenticated.

Please note that only when the customerId is in an authenticated state will Target reference the user profile data that is stored and linked to the customerId. If the customerId is in an unknown or logged_out state, it will be ignored, and any user profile data that may be associated with that customerId will not be leveraged for audience targeting.

Node.js SDK#

Copied to your clipboard
1const TargetClient = require("@adobe/target-nodejs-sdk");
2
3const CONFIG = {
4 client: "acmeclient",
5 organizationId: "1234567890@AdobeOrg"
6};
7
8const targetClient = TargetClient.create(CONFIG);
9
10targetClient.getOffers({
11 request: {
12 id: {
13 marketingCloudVisitorId : "10527837386392355901041112038610706884",
14 customerIds: [{
15 id: "134325423",
16 integrationCode : "crm_data",
17 authenticatedState : "authenticated"
18 }]
19 },
20 execute: {
21 mboxes: [{
22 name: "some-mbox"
23 }]
24 }
25 }
26})
27.then(console.log)
28.catch(console.error);

Java SDK#

Copied to your clipboard
1ClientConfig config = ClientConfig.builder()
2 .client("acmeclient")
3 .organizationId("1234567890@AdobeOrg")
4 .build();
5TargetClient targetClient = TargetClient.create(config);
6
7CustomerId customerId = new CustomerId()
8 .id("134325423")
9 .integrationCode("crm_data")
10 .authenticatedState(AuthenticatedState.AUTHENTICATED);
11VisitorId id = new VisitorId()
12 .marketingCloudVisitorId("10527837386392355901041112038610706884")
13 .customerIds(Arrays.asList(customerId));
14Context context = new Context().channel(ChannelType.WEB);
15MboxRequest mbox = new MboxRequest()
16 .name("some-mbox")
17 .index(0);
18ExecuteRequest executeRequest = new ExecuteRequest()
19 .mboxes(Arrays.asList(mbox));
20
21TargetDeliveryRequest request = TargetDeliveryRequest.builder()
22 .context(context)
23 .execute(executeRequest)
24 .build();
25
26TargetDeliveryResponse offers = targetClient.getOffers(request);

The example above demonstrates how to send a customerId with an authenticatedState. When sending a customerId, the integrationCode, id, and authenticatedState as well as the marketingCloudVisitorId are required. The integrationCode is the alias of the customer attributes file you provided through CRS.

Merged Profile#

You can combine tntId, thirdPartyID, and marketingCloudVisitorId in the same request. In this scenario, Adobe Target will maintain the mapping of all these IDs and pin it to a visitor. Learn how profiles are merged and synced in real time using the different identifiers.

Node JS SDK#

Copied to your clipboard
1const TargetClient = require("@adobe/target-nodejs-sdk");
2
3const CONFIG = {
4 client: "acmeclient",
5 organizationId: "1234567890@AdobeOrg"
6};
7
8const targetClient = TargetClient.create(CONFIG);
9
10targetClient.getOffers({
11 request: {
12 id: {
13 tntId: "d359234570e044f14e1faeeba02d6ab23439914e.35_0",
14 thirdPartyId: "B234A029348",
15 marketingCloudVisitorId : "10527837386392355901041112038610706884"
16 },
17 execute: {
18 mboxes: [{
19 name: "some-mbox"
20 }]
21 }
22 }
23})
24.then(console.log)
25.catch(console.error);

Java SDK#

Copied to your clipboard
1ClientConfig config = ClientConfig.builder()
2 .client("acmeclient")
3 .organizationId("1234567890@AdobeOrg")
4 .build();
5TargetClient targetClient = TargetClient.create(config);
6
7VisitorId id = new VisitorId()
8 .tntId("d359234570e044f14e1faeeba02d6ab23439914e.35_0")
9 .thirdPartyId("B234A029348")
10 .marketingCloudVisitorId("10527837386392355901041112038610706884");
11Context context = new Context().channel(ChannelType.WEB);
12MboxRequest mbox = new MboxRequest()
13 .name("some-mbox")
14 .index(0);
15ExecuteRequest executeRequest = new ExecuteRequest()
16 .mboxes(Arrays.asList(mbox));
17
18TargetDeliveryRequest request = TargetDeliveryRequest.builder()
19 .context(context)
20 .execute(executeRequest)
21 .build();
22
23TargetDeliveryResponse offers = targetClient.getOffers(request);

The example above demonstrates how you can combine tntId, thirdPartyID, and marketingCloudVisitorId in the same request.

Bucketing#

Your users are bucketed into seeing an experience depending on how you set up your Adobe Target activities. In Adobe Target, bucketing is:

  • Deterministic: MurmurHash3 is used to ensure that your user is bucketed and sees the right variation every single time as long as the user ID is consistent.
  • Sticky: Adobe Target stores the variation that your user sees in the user profile to ensure the variation is consistently shown to that user across sessions and channels. Variations and stickiness are guaranteed when using server-side decisioning. When on-device decisioning is used, stickiness is not guaranteed.

End-to-end bucketing workflow#

Before diving into the actual bucketing algorithm, it is important to highlight that similar steps are used both to select activities based on their traffic allocation percentage, as well as to select an experience within an activity.

Activity selection steps:#

  1. Generate a device ID, usually a UUID
  2. Get the client code
  3. Get the activity ID
  4. Get the salt, which is usually some string like "activity"
  5. Compute the hash using MurmurHash3
  6. Get the absolute value of the hash
  7. Divide the hash absolute value by 10000
  8. Divide the remainder by 10000, which should produce a value between 0 and 1
  9. Multiply the result by 100%
  10. Compare activity traffic allocation percentage against the obtained percentage. If the traffic allocation percentage is lower, then the activity is selected. Otherwise, the activity is skipped.

Experience selection steps:#

  1. Generate a device ID, usually a UUID
  2. Get the client code
  3. Get the activity ID
  4. Get the salt, which is usually some string like "experience"
  5. Compute the hash using MurmurHash3
  6. Get the absolute value of the hash
  7. Divide the hash absolute value by 10000
  8. Divide the remainder by 10000, which should produce a value between 0 and 1
  9. Multiply the result by the total number of experiences within the activity
  10. Round the result. This should produce the experience index.

Example#

Assume the following:

  • Client C with client code acmeclient
  • Activity A that has ID 1111 and three experiences E1, E2, E3
  • Experiences have the following distribution: E1 - 33%, E2 - 33%, E3 - 34%

The selection flow looks like this:

  1. Device ID 702ff4d0-83b1-4e2e-a0a6-22cbe460eb15
  2. Client code acmeclient
  3. Activity ID 1111
  4. Salt experience
  5. Value to hash acmeclient.1111.702ff4d0-83b1-4e2e-a0a6-22cbe460eb15.experience, hash value -919077116
  6. Absolute value of the hash 919077116
  7. Remainder after division by 10000, 7116
  8. Value after remainder is divided by 10000, 0.7116
  9. Result after multiplying the value against the total number of experiences 3 * 0.7116 = 2.1348
  10. The experience index is 2, which means the third experience, since we are using 0 based indexing.
Was this helpful?
  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.