SDK for Java Reference Guide
You can use the SDK for Java on the server side to facilitate the process of generating or establishing client identity using EUID, retrieving advertising tokens for bidstream use, and automatically refreshing EUID tokens. If you have the applicable permissions, you can also decrypt EUID tokens to access the raw EUID and map personal data to raw EUIDs.
Functionality
This SDK simplifies integration with EUID for any publishers, DSPs, advertisers, and data providers who are using Java for their server-side coding. The following table shows the functions it supports.
Encrypt Raw EUID to EUID Token | Decrypt EUID Token to Raw EUID | Generate EUID Token from Personal Data | Refresh EUID Token | Map Personal Data to Raw EUIDs | Monitor Rotated Salt Buckets |
---|---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ✅ | — |
EUID Account Setup
To integrate with EUID, you'll need to have an EUID account. If you haven't yet created an account, first follow the steps described on the Account Setup page.
API Permissions
To use this SDK, you'll need to complete the EUID account setup by following the steps described in the Account Setup page.
You'll be granted permission to use specific functions offered by the SDK, and given credentials for that access. Bear in mind that there might be functions in the SDK that you don't have permission to use. For example, publishers get a specific API permission to generate and refresh tokens, but the SDK might support other activities that require a different API permission.
For details, see API Permissions.
Version
The SDK requires Java version 1.8 or later.
GitHub Repository/Binary
This SDK is in the following open-source GitHub repository:
The binary is published on the Maven repository:
This SDK is valid for both UID2 and EUID. The SDK, and some of its technical components, are named UID2, but are equally applicable for EUID.
Initialization
The initialization step depends on the role, as shown in the following table.
Role | Create Instance of Class | Link to Instructions |
---|---|---|
Publisher | PublisherUid2Client | Usage for Publishers |
Advertiser/Data Provider | IdentityMapV3Client | Usage for Advertisers/Data Providers |
DSP | BidstreamClient | Usage for DSPs |
Sharer (not currently supported for EUID) | SharingClient | Not applicable |
You will need to provide the values necessary for the SDK to authenticate with the EUID service.
Parameter | Description |
---|---|
baseUrl/uid2BaseUrl | The endpoint for the EUID service. See Environments. |
clientApiKey | The API key. See EUID Credentials. |
base64SecretKey | The client secret. See EUID Credentials. |
Interface
The BidstreamClient
class allows you to decrypt EUID tokens into raw EUIDs.
For details on the bidding logic for handling user opt-outs, see DSP Integration Guide.
The SharingClient
class allows you to encrypt raw EUIDs into EUID tokens and decrypt EUID tokens into raw EUIDs (not currently supported).
When you use an SDK, you do not need to store or manage decryption keys.
Encryption Response Content
When encrypting with the SharingClient
class, the SDK returns the information shown in the following table.
Method | Description |
---|---|
getStatus() | The encryption result status. For a list of possible values and definitions, see Encryption Response Statuses. |
getEncryptedData() | The encrypted EUID token. |
Encryption Response Statuses
Encryption response codes, and their meanings, are shown in the following table.
Value | Description |
---|---|
SUCCESS | The raw EUID was successfully encrypted and an EUID token was returned. |
NOT_AUTHORIZED_FOR_KEY | The requester does not have authorization to use the encryption key. |
NOT_AUTHORIZED_FOR_MASTER_KEY | The requester does not have authorization to use the master key. |
NOT_INITIALIZED | The client library is waiting to be initialized. |
KEYS_NOT_SYNCED | The client has failed to synchronize keys from the EUID service. |
ENCRYPTION_FAILURE | A generic encryption failure occurred. |
Decryption Response Content
Whether decrypting with the BidstreamClient
class, the SDK returns the information shown in the following table.
Methods | Description |
---|---|
getStatus() | The decryption result status. For a list of possible values and definitions, see Decryption Response Statuses. |
getUid() | The raw EUID for the corresponding EUID token. |
getEstablished() | The timestamp indicating when a user first established the EUID with the publisher. |
Decryption Response Statuses
Decryption response codes, and their meanings, are shown in the following table.
Value | Description |
---|---|
SUCCESS | The EUID token was decrypted successfully and a raw EUID was returned. |
NOT_AUTHORIZED_FOR_KEY | The requester does not have authorization to decrypt this EUID token. |
NOT_INITIALIZED | The client library is waiting to be initialized. |
INVALID_PAYLOAD | The incoming EUID token is not a valid payload. |
EXPIRED_TOKEN | The incoming EUID token has expired. |
KEYS_NOT_SYNCED | The client has failed to synchronize keys from the EUID service. |
VERSION_NOT_SUPPORTED | The client library does not support the version of the encrypted token. |
INVALID_TOKEN_LIFETIME | The token has an invalid timestamp. |
Usage for Publishers
As a publisher, there are two ways to use the SDK for Java:
- Basic Usage is for publishers who want to use this SDK's HTTP implementation (synchronous OkHttp).
- Advanced Usage is for publishers who prefer to use their own HTTP library.
For an example application that demonstrates both Basic and Advanced usage, see Java Integration Example.
The integration example is labelled as UID2, but it applies equally to EUID.
Basic Usage
If you're using the SDK's HTTP implementation, follow these steps.
-
Create an instance of
PublisherUid2Client
as an instance variable:private final PublisherUid2Client publisherUid2Client = new PublisherUid2Client(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
-
Call a function that takes the user's email address or phone number as input and generates a
TokenGenerateResponse
object. The following example uses an email address:TokenGenerateResponse tokenGenerateResponse = publisherUid2Client.generateTokenResponse(TokenGenerateInput.fromEmail("user@example.com").doNotGenerateTokensForOptedOut());
important-
Be sure to call the POST /token/generate endpoint only when you have a legal basis to convert the user’s personal data to EUID tokens for targeted advertising.
-
Always apply
doNotGenerateTokensForOptedOut()
. This applies a parameter similar to settingoptout_check=1
in the call to the POST /token/generate endpoint (see Unencrypted JSON Body Parameters).
-
Basic Usage, Client-Server Integration
If you're using client-server integration (see Client-Server Integration Guide for JavaScript), follow this step:
-
Send this identity as a JSON string back to the client (to use in the identity field), using the following:
tokenGenerateResponse.getIdentityJsonString()
noteIf the user has opted out, this method returns
null
, so be sure to handle that case.
Basic Usage, Server-Side Integration
If you're using server-side integration (see Publisher Integration Guide, Server-Side), follow these steps:
-
Store this identity as a JSON string in the user's session, using the
tokenGenerateResponse.getIdentityJsonString()
function.If the user has opted out, this method returns
null
, so be sure to handle that case. -
To retrieve the user's EUID token, use the following:
IdentityTokens identity = tokenGenerateResponse.getIdentity();
if (identity != null) { String advertisingToken = identity.getAdvertisingToken(); } -
When the user accesses another page, or on a timer, determine whether a refresh is needed:
-
Retrieve the identity JSON string from the user's session, and then call the following function that takes the identity information as input and generates an
IdentityTokens
object:IdentityTokens identity = IdentityTokens.fromJsonString(identityJsonString);
-
Determine if the identity can be refreshed (that is, the refresh token hasn't expired):
if (identity == null || !identity.isRefreshable()) {
// we must no longer use this identity (for example, remove this identity from the user's session)
} -
Determine if a refresh is needed:
if (identity.isDueForRefresh()) {..}
-
-
If needed, refresh the token and associated values:
TokenRefreshResponse tokenRefreshResponse = publisherUid2Client.refreshToken(identity);
-
Store
tokenRefreshResponse.getIdentityJsonString()
in the user's session.If the user has opted out, this method returns
null
, indicating that the user's identity should be removed from the session. To confirm optout, you can use thetokenRefreshResponse.isOptout()
function.
Advanced Usage
-
Create an instance of
PublisherUid2Helper
as an instance variable:private final PublisherUid2Helper publisherUid2Helper = new PublisherUid2Helper(EUID_SECRET_KEY);
-
Call a function that takes the user's email address or phone number as input and creates a secure request data envelope. See Encrypting requests. The following example uses an email address:
EnvelopeV2 envelope = publisherUid2Helper.createEnvelopeForTokenGenerateRequest(TokenGenerateInput.fromEmail("user@example.com").doNotGenerateTokensForOptedOut());
-
Using an HTTP client library of your choice, post this envelope to the POST token/generate endpoint, including headers and body:
-
Headers: Depending on your HTTP library, this might look something like the following:
.putHeader("Authorization", "Bearer " + EUID_API_KEY)
.putHeader("X-UID2-Client-Version", PublisherUid2Helper.getVersionHttpHeader())
-
Body:
envelope.getEnvelope()
important-
Be sure to call the POST /token/generate endpoint only when you have a legal basis to convert the user’s personal data to EUID tokens for targeted advertising.
- Always apply
doNotGenerateTokensForOptedOut()
. This applies a parameter similar to settingoptout_check=1
in the call to the POST /token/generate endpoint (see Unencrypted JSON Body Parameters).
- Always apply
-
-
If the HTTP response status code is not 200, see Response Status Codes to determine next steps. Otherwise, convert the EUID identity response content into a
TokenGenerateResponse
object:TokenGenerateResponse tokenGenerateResponse = publisherUid2Helper.createTokenGenerateResponse({response body}, envelope);
Advanced Usage, Client-Server Integration
If you're using client-server integration (see Client-Server Integration Guide for JavaScript), follow this step:
-
Send this identity as a JSON string back to the client (to use in the identity field) using the following:
tokenGenerateResponse.getIdentityJsonString()
cautionThis method returns null if the user has opted out, so be sure to handle that case.
Advanced Usage, Server-Side Integration
If you're using server-side integration (see Publisher Integration Guide, Server-Side):
-
Store this identity as a JSON string in the user's session, using:
tokenGenerateResponse.getIdentityJsonString()
.This method returns null if the user has opted out, so be sure to handle that case.
-
To retrieve the user's EUID token, use:
IdentityTokens identity = tokenGenerateResponse.getIdentity();
if (identity != null) { String advertisingToken = identity.getAdvertisingToken(); } -
When the user accesses another page, or on a timer, determine whether a refresh is needed:
-
Retrieve the identity JSON string from the user's session, and then call the following function that generates an
IdentityTokens
object:IdentityTokens identity = IdentityTokens.fromJsonString(identityJsonString);
-
Determine whether the identity can be refreshed (that is, the refresh token hasn't expired):
if (identity == null || !identity.isRefreshable()) {
// we must no longer use this identity (for example, remove this identity from the user's session)
} -
Determine whether a refresh is needed:
if (identity.isDueForRefresh()) {..}
-
-
If a refresh is needed, call the POST token/refresh endpoint, with the following:
-
Headers: Depending on your HTTP library, this might look something like the following:
.putHeader("Authorization", "Bearer " + EUID_API_KEY)
.putHeader("X-UID2-Client-Version", PublisherUid2Helper.getVersionHttpHeader())
. -
Body:
identity.getRefreshToken()
-
-
If the refresh HTTP response status code is 200:
TokenRefreshResponse tokenRefreshResponse = PublisherUid2Helper.createTokenRefreshResponse({response body}, identity);
-
Store
tokenRefreshResponse.getIdentityJsonString()
in the user's session.If the user has opted out, this method returns null, indicating that the user's identity should be removed from the session. To confirm optout, you can use the
tokenRefreshResponse.isOptout()
function.
Usage for Advertisers/Data Providers
-
Create an IdentityMapV3Client as an instance variable:
final private IdentityMapV3Client identityMapV3Client = new IdentityMapV3Client(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
-
Create an IdentityMapV3Input object. You can use emails, phone numbers, or both, hashed or raw:
IdentityMapV3Input input = IdentityMapV3Input.fromEmails(Arrays.asList("user@example.com", "user2@example.com"));
Or combine multiple identity types:
IdentityMapV3Input input = new IdentityMapV3Input()
.withEmail("user@example.com")
.withPhone("+12345678901")
.withHashedEmail("preHashedEmail")
.withHashedPhone("preHashedPhone"); -
Call a function that takes the
input
and generates an IdentityMapV3Response object:IdentityMapV3Response identityMapResponse = identityMapV3Client.generateIdentityMap(input);
-
Retrieve the mapped and unmapped results:
HashMap<String, IdentityMapV3Response.MappedIdentity> mappedIdentities = identityMapResponse.getMappedIdentities();
HashMap<String, IdentityMapV3Response.UnmappedIdentity> unmappedIdentities = identityMapResponse.getUnmappedIdentities(); -
Process the results. For successfully mapped identities:
IdentityMapV3Response.MappedIdentity mappedIdentity = mappedIdentities.get("user@example.com");
if (mappedIdentity != null) {
String currentUid = mappedIdentity.getCurrentRawUid(); // Current raw EUID
String previousUid = mappedIdentity.getPreviousRawUid(); // Previous raw EUID (nullable, only available for 90 days after rotation)
Instant refreshFrom = mappedIdentity.getRefreshFrom(); // When to refresh this identity
} else {
IdentityMapV3Response.UnmappedIdentity unmappedIdentity = unmappedIdentities.get("user@example.com");
UnmappedIdentityReason reason = unmappedIdentity.getReason(); // OPTOUT, INVALID_IDENTIFIER, or UNKNOWN
}
Note: The SDK automatically handles email normalization and hashing, ensuring that raw email addresses and phone numbers do not leave your server.
Usage Example
IdentityMapV3Client client = new IdentityMapV3Client(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
// Example 1: Single identity type
IdentityMapV3Input emailInput = IdentityMapV3Input.fromEmails(
Arrays.asList("user@example.com", "optout@example.com")
);
IdentityMapV3Response emailResponse = client.generateIdentityMap(emailInput);
// Process email results
emailResponse.getMappedIdentities().forEach((email, identity) -> {
System.out.println("Email: " + email);
System.out.println("Current UID: " + identity.getCurrentRawUid());
System.out.println("Previous UID: " + identity.getPreviousRawUid());
System.out.println("Refresh from: " + identity.getRefreshFrom());
});
emailResponse.getUnmappedIdentities().forEach((email, identity) -> {
System.out.println("Unmapped email: " + email + " - Reason: " + identity.getReason());
});
// Example 2: Mixed identity types in single request
IdentityMapV3Input mixedInput = new IdentityMapV3Input()
.withEmail("user1@example.com")
.withPhone("+12345678901")
.withHashedEmail("preHashedEmailValue")
.withHashedPhone("preHashedPhoneValue");
IdentityMapV3Response mixedResponse = client.generateIdentityMap(mixedInput);
Migration From Version Using v2 Identity Map
The following sections provide general information and guidance for migrating to the latest version of this SDK, which references POST /identity/map
version 3, including:
Version 3 Improvements
Version 3 of the POST /identity/map
endpoint provides the following improvements over v2:
- Support for multiple identity types: You can process both email addresses and phone numbers in a single request.
- Simpler refresh management: You can just re-map any raw EUID when it reaches the refresh timestamp, rather than monitoring salt buckets, which is a separate API call.
- Availability of previous raw EUID: You can see the previous EUID for 90 days after rotation.
- Improved performance: The new API version uses significantly less bandwidth for the same amount of personal data.
Required Changes
To upgrade, follow these steps:
1. Update dependency version
Update the dependency version referenced in your code, as shown in the following example.
<dependency>
<groupId>com.uid2</groupId>
<artifactId>uid2-client</artifactId>
<version>4.8.0</version>
</dependency>
2. Change client class
Update the client class referenced in your code, as shown in the following example.
// Before
IdentityMapClient identityMapClient = new IdentityMapClient(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
// After
IdentityMapV3Client identityMapClient = new IdentityMapV3Client(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
3. Update import statements
Update import statements, as shown in the following example.
import com.uid2.client.IdentityMapV3Client;
import com.uid2.client.IdentityMapV3Input;
import com.uid2.client.IdentityMapV3Response;
import com.uid2.client.UnmappedIdentityReason;
Recommended Changes
The following changes are optional but allow you to take advantage of new v3 features. The required changes are sufficient for basic functionality, but these recommended changes enable improved capabilities.
-
Mix identity types in a single request - Process both email addresses and phone numbers together:
// Before - single identity type only
IdentityMapInput input = IdentityMapInput.fromEmails(Arrays.asList("user@example.com"));
// After - can mix identity types (new v3 capability)
IdentityMapV3Input input = new IdentityMapV3Input()
.withEmail("user@example.com")
.withPhone("+12345678901")
.withHashedEmail("preHashedEmail")
.withHashedPhone("preHashedPhone"); -
Access previous EUIDs - Get both current and previous EUIDs for 90-day measurement continuity:
// Before - only current EUID available
IdentityMapResponse response = client.generateIdentityMap(input);
MappedIdentity mapped = response.getMappedIdentities().get("user@example.com");
String uid = mapped.getRawUid();
// After - access to both current and previous EUIDs
IdentityMapV3Response response = client.generateIdentityMap(input);
IdentityMapV3Response.MappedIdentity mapped = response.getMappedIdentities().get("user@example.com");
String currentUid = mapped.getCurrentRawUid();
String previousUid = mapped.getPreviousRawUid(); // Available for 90 days after rotation
Instant refreshFrom = mapped.getRefreshFrom(); -
Use structured error reasons - Get unmapped reasons as strongly-typed enums instead of strings:
// Before - string-based error reasons
IdentityMapResponse.UnmappedIdentity unmapped = identityMapResponse.getUnmappedIdentities().get("user@example.com");
String reason = unmapped.getReason();
// After - structured enum-based error reasons
IdentityMapV3Response.UnmappedIdentity unmapped = response.getUnmappedIdentities().get("user@example.com");
UnmappedIdentityReason reason = unmapped.getReason(); // Enum: OPTOUT, INVALID_IDENTIFIER, UNKNOWN
// Or continue using string reasons if preferred
String rawReason = unmapped.getRawReason();
Previous SDK Version (using POST /identity/map v2)
An earlier version of the SDK for Java, which references the POST /identity/map
v2 endpoint is also available, for backwards compatibility. Migrate to the current SDK for improved performance, multi-identity type support, and better UID rotation management. New integrations should not use this version.
For details, see Migration From Version Using v2 Identity Map.
To use the earlier version, follow these instructions.
-
Create an instance of IdentityMapClient as an instance variable.
final private IdentityMapClient identityMapClient = new IdentityMapClient(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
-
Call a function that takes email addresses or phone numbers as input and generates an IdentityMapResponse object. The following example uses email addresses:
IdentityMapResponse identityMapResponse = identityMapClient.generateIdentityMap(IdentityMapInput.fromEmails(Arrays.asList("email1@example.com", "email2@example.com")));
Note: The SDK hashes input values before sending them. This ensures that raw email addresses and phone numbers do not leave your server.
-
Retrieve the mapped and unmapped results as follows:
Map<String, IdentityMapResponse.MappedIdentity> mappedIdentities = identityMapResponse.getMappedIdentities();
Map<String, IdentityMapResponse.UnmappedIdentity> unmappedIdentities = identityMapResponse.getUnmappedIdentities(); -
Iterate through the mapped and unmapped results, or do a lookup. The following example does a lookup:
IdentityMapResponse.MappedIdentity mappedIdentity = mappedIdentities.get("email1@example.com");
if (mappedIdentity != null) {
String rawUid = mappedIdentity.getRawUid();
} else {
IdentityMapResponse.UnmappedIdentity unmappedIdentity = unmappedIdentities.get("email1@example.com");
String reason = unmappedIdentity.getReason();
}
Usage for DSPs
The following instructions provide an example of how a DSP can decode bidstream tokens using the SDK for Java.
-
Create a
BidstreamClient
:BidstreamClient client = new BidstreamClient(EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY);
-
Refresh once at startup, and then periodically (recommended refresh interval is hourly):
client.refresh();
-
Decrypt a token into a raw EUID. Pass the token, and then do one of the following:
- If the bid request originated from a publisher's website, pass the domain name. The domain name must be all lower case, without spaces and without subdomain. For example, for
Subdomain.DOMAIN.com
, passdomain.com
instead. - If the bid request originated from a mobile app, pass the app name.
- Otherwise, pass
null
.
DecryptionResponse decrypted = client.decryptTokenIntoRawUid(uidToken, domainOrAppName);
//If decryption succeeded, use the raw EUID.
if (decrypted.isSuccess())
{
//Use decrypted.getUid()
}
else
{
// Check decrypted.getStatus() for the failure reason.
} - If the bid request originated from a publisher's website, pass the domain name. The domain name must be all lower case, without spaces and without subdomain. For example, for
For a full example, see the ExampleBidStreamClient
method in test/IntegrationExamples.java.