# Java v2.0.X

### Introduction

\\

#### SDK overview

Welcome to the Flagship Java SDK documentation!

The following article will guide you through the steps to get Flagship up and running on your Java servers or scripts using our client library with preconfigured methods to implement the Decision API.

#### Release notes

[See here](doc:java-sdk)

#### SDK features

That SDK version helps you :

* Set a [visitor ID](doc:glossary#visitor-id)
* Update [user context](doc:glossary#user-context)
* Assign campaigns via the [Decision API](doc:decision-api#campaigns)
* Get modifications
* Activate campaigns
* Send hits to our [Universal Collect](doc:universal-collect-documentation)

#### Prerequisites

* **Java**: version 1.8 or later
* Your server/device must have access to the internet.

#### Good to know

* Github repository: <https://github.com/flagship-io/flagship-java>
* Weight: 103.0 ko
* Support Java 8
* Open-source app: <https://github.com/flagship-io/flagship-java>

\
\\

### Getting Started

\\

#### Installation

First, add the following repository in your dependency manager:

```groovy
maven { url 'https://abtasty.jfrog.io/artifactory/flagship-java' }
```

```xml
<repositories>
    	<repository>
      		<id>com.abtasty</id>
      		<url>https://abtasty.jfrog.io/artifactory/flagship-java</url>
    	</repository>
  </repositories>
```

Then import the Java SDK using either Maven or Gradle dependency management:

```groovy
implementation 'com.abtasty:flagship-java:2.0.0'
```

```xml
<dependency>
    <groupId>com.abtasty</groupId>
    <artifactId>flagship-java</artifactId>
    <version>2.0.0</version>
</dependency>
```

**Manual installion**

For manual installation, jar files are available at :\
\
<https://abtasty.jfrog.io/artifactory/flagship-java/com/abtasty/flagship-java/>

Add the needed dependency :

```groovy
implementation 'org.json:json:20201115'
```

```xml
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20201115</version>
</dependency>
```

#### Initialization

To initialize and start the SDK, simply call the `start` function of the `Flagship` class, in the most appropriate location for your application.

```java
Flagship.start("your_env_id", "your_api_key");
```

| Parameter | Type           | Description                                                                                               |
| --------- | -------------- | --------------------------------------------------------------------------------------------------------- |
| envId     | String         | Environment id provided by Flagship.                                                                      |
| apiKey    | String         | Api authentication key provided by Flagship.                                                              |
| config    | FlagshipConfig | (optional) Custom flagship configuration. It can be DecisionApi (default) or Bucketing see Decision Mode. |

**Flagship configuration : FlagshipConfig.**

This class aims to help you to configure the SDK via the following two available config implementations: DecisionApi and Bucketing. **See**[**Decision Mode**](https://github.com/flagship-io/Gitbook/blob/main/SDKs/java-sdk/v2.0#decision-mode) **section**.

```java
Flagship.start("your_env_id", "your_api_key", new FlagshipConfig.DecisionApi() // Will start the SDK with Api mode.
              .withLogManager(new CustomLogManager())
              .withLogLevel(LogManager.Level.ALL)
              .withStatusListener(newStatus -> {
                  if (newStatus == Flagship.Status.READY)
                      System.out.println("SDK is ready to use.");
              })
              .withTimeout(200));
```

```java
// Start SDK in Bucketing mode.
Flagship.start("your_env_id", "your_api_key", new FlagshipConfig.Bucketing() // Will start the SDK with Bucketing mode.
              .withLogManager(new CustomLogManager())
              .withLogLevel(LogManager.Level.ALL)
              .withStatusListener(newStatus -> {
                  if (newStatus == Flagship.Status.READY)
                      System.out.println("SDK is ready to use.");
              })
              .withPollingIntervals(20, TimeUnit.SECONDS)
              .withTimeout(200));
```

\\

* **`public FlagshipConfig<T> withLogLevel(LogManager.Level level)`**

  This method specifies the mode which filters SDK logs.

  | Parameter | Type                   | Description                                                                                                  |
  | --------- | ---------------------- | ------------------------------------------------------------------------------------------------------------ |
  | level     | LogManager.Level level | The levels in ascending order are : NONE(0), EXCEPTIONS(1), ERROR(2), WARNING(3), DEBUG(4), INFO(5), ALL(6). |

\\

* **`public FlagshipConfig<T> withLogManager(LogManager logManager)`**

  Specify a custom implementation of LogManager in order to receive logs from the SDK.

  | Parameter  | Type       | Description                          |
  | ---------- | ---------- | ------------------------------------ |
  | logManager | LogManager | Custom implementation of LogManager. |

\\

* **`public FlagshipConfig<T> withTimeout(int timeout)`**

  Specify timeout for api request.

  | Parameter | Type | Description                                                  |
  | --------- | ---- | ------------------------------------------------------------ |
  | timeout   | int  | Milliseconds for connect and read timeouts. Default is 2000. |

\\

* **`public FlagshipConfig<T> withStatusListener(Flagship.StatusListener listener)`**

  Define a new listener in order to get a callback when the SDK status has changed. **See**[**SDK status**](https://github.com/flagship-io/Gitbook/blob/main/SDKs/java-sdk/v2.0#status) **section**.

  | Parameter | Type                    | Description                                      |
  | --------- | ----------------------- | ------------------------------------------------ |
  | listener  | Flagship.StatusListener | Callback to trigger when SDK status has changed. |

\\

***Only available for Bucketing:***

* **`public FlagshipConfig<T> withPollingIntervals(long time, TimeUnit timeUnit)`**

  Define time interval between two bucketing updates. Default is 60 seconds. MICROSECONDS and NANOSECONDS Unit are ignored.

  | Parameter | Type     | Description                                         |
  | --------- | -------- | --------------------------------------------------- |
  | time      | Long     | time value.                                         |
  | timeUnit  | TimeUnit | time unit. Must be greater or equal to MILLISECONDS |

\\

**Decision Mode**

**`DecisionApi`Mode**

When the SDK is running in `DecisionApi` mode, the campaign assignments and targeting validation take place server-side. In this mode, each call to the `synchronizeModifications` method to refresh the modifications will create an HTTP request.

**`Bucketing`Mode**

When the SDK is running in `Bucketing` mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. [**Learn more**](doc:bucketing)

\\

**SDK Status**

List of the possible SDK status :

| Status           | Description                                                                                                                                   |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| NOT\_INITIALIZED | Flagship SDK has not been started or initialized successfully.                                                                                |
| STARTING         | Flagship SDK is starting.                                                                                                                     |
| POLLING          | Flagship SDK has been started successfully but is still polling campaigns. (Only when Bucketing mode is used)                                 |
| PANIC            | Flagship SDK is ready but is running in Panic mode: All visitor's features are disabled except 'synchronization' which refreshes this status. |
| READY            | Flagship SDK is ready to use.                                                                                                                 |

\\

It is possible to get the current status via the method getStatus() from the Flagship class.

* **`public Status getStatus()`**

  Return the current SDK status

```java
Status status = Flagship.getStatus()
```

\\

### Create a new visitor

\\

The `visitor` instance is a helper object that lets you manage the context and campaigns for a user identified by a unique ID.

The user context is a property dataset that defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.

For example, if you want to enable or disable a specific feature based on VIP status, you would pass this attribute as a key-value pair in the user context so that the Decision API can enable or disable the corresponding feature flag for the user.

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id")
                .context(new HashMap<String, Object>() {{
                    put("age", 32);
                    put("isVip", true);
                }})
                .hasConsented(true)
                .isAuthenticated(true)
                .build();
```

\\

* **`public static Visitor.Builder visitorBuilder(String visitorId)`**

  Visitor builder class that creates a new visitor.

  | Parameter | Type   | Description                |
  | --------- | ------ | -------------------------- |
  | visitorId | String | Unique visitor identifier. |

**Visitor Builder methods :**

* **`public Builder isAuthenticated(boolean isAuthenticated)`**

  Specify if the visitor is authenticated or anonymous. Default value is false.

  | Parameter       | Type    | Description                                                          |
  | --------------- | ------- | -------------------------------------------------------------------- |
  | isAuthenticated | Boolean | True for authenticated user, false for anonymous. (false by default) |
* **`public Builder hasConsented(boolean hasConsented)`**

  Specify if the visitor has consented to personal data usage. When false some features will be deactivated, cache will be deactivated and cleared. Default value is True.

  | Parameter    | Type    | Description                                                          |
  | ------------ | ------- | -------------------------------------------------------------------- |
  | hasConsented | Boolean | True when user has given consent, false otherwise. (true by default) |
* **`public Builder context(HashMap<String, Object> context)`**

  Specify visitor initial context key / values used for targeting.\
  Context keys must be String, and values types must be one of the following: Number, Boolean, String.

  | Parameter | Type                     | Description      |
  | --------- | ------------------------ | ---------------- |
  | context   | HashMap\<String, Object> | Initial context. |

\\

> 🚧 \* User context keys must have a type of `String`
>
> * User context values must have a type of `String`, `Boolean`, `Number`.

\\

* **`public Visitor build()`**

  Return the newly created visitor.

\
\\

### Updating the visitor context

\\

The user context is a property dataset that defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.

The following method from the `Visitor` instance allows you to set new context values matching the given keys.

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id")
                .context(new HashMap<String, Object>() {{
                    put("age", 32);
                    put("isVip", true);
                }})
                .build();

visitor.updateContext("lastPurchaseDate", 1615384464);
```

\\

**`public <T> void updateContext(String key, T value)`**

Upsert the visitor context values, matching the given keys, used for targeting. Only String, Boolean, Number typed values are accepted.

| Parameter | Type   | Description    |
| --------- | ------ | -------------- |
| key       | String | Context key.   |
| value     | T      | Context value. |

\\

**`public void updateContext(HashMap<String, Object> context)`**

Upsert the visitor context values, matching the given keys, used for targeting. Only String, Boolean, Number typed values are accepted.

| Parameter | Type                     | Description              |
| --------- | ------------------------ | ------------------------ |
| context   | HashMap\<String, Object> | HashMap of keys, values. |

\\

> 🚧 \* User context keys must have a type of `String`
>
> * User context values must have a type of `String`, `Boolean`, `Number`.

\\

**`public <T> void updateContext(FlagshipContext<T> flagshipContext, T value)`**

Upsert the visitor context values with Flagship predefined context key. \*\*[See FlagshipContext](https://github.com/flagship-io/Gitbook/blob/main/SDKs/java-sdk/v2.0#predefined-user-context-keys--flagshipcontext)

| Parameter       | Type            | Description            |
| --------------- | --------------- | ---------------------- |
| flagshipContext | FlagshipContext | Predefined context key |
| value           | T               | value to add.          |

\
\\

**`public <T> void clearContext()`**

Clear all the visitor context values used for targeting.

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id")
              .context(new HashMap<String, Object>() {{
                  put("age", 32);
                  put("isVip", true);
              }})
              .build();
visitor.clearContext();
```

\\

**`public HashMap<String, Object> getContext()`**

Get visitor current context key / values.

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id")
              .context(new HashMap<String, Object>() {{
                  put("age", 32);
                  put("isVip", true);
              }})
              .build();
HashMap<String, Object visitorContext = visitor.getContext();
```

\
\\

### Managing visitor campaigns

\\

#### Synchronizing campaigns

The `synchronize_modifications()` method of the `visitor` instance automatically calls the Flagship Decision API to run campaign assignments according to the current user context and retrieve applicable modifications.

These modifications are then stored in the SDK and updated asynchronously when `synchronizeModifications()` is called.

\\

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build();

visitor.updateContext("postcode", "31200");

visitor.synchronizeModifications();

visitor.synchronizeModifications().get(); // Synchronous Blocking call

visitor.synchronizeModifications().whenComplete((instance, error) -> { // Asynchronous non blocking call
    // Synchronization has been completed.
});
```

\\

**`public CompletableFuture<Visitor> synchronizeModifications()`**

This function will call the decision api and update all the campaigns modifications from the server according to the visitor context.

| Return                       | Description                                                               |
| ---------------------------- | ------------------------------------------------------------------------- |
| `CompletableFuture<Visitor>` | Return a CompletableFuture to manage sync/async call to the decision api. |

\\

#### Getting modifications

Once the campaign has been **assigned** and **synchronized**, all the modifications are stored in the SDK. You can retrieve these modifications using the following functions from the `Visitor` instance:

\\

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build();
visitor.updateContext("isVip", true);
visitor.synchronizeModifications().whenComplete((instance, error) -> {
    Boolean displayVipFeature = visitor.getModification("displayVipFeature", false);

});
```

\\

**`public <T> T getModification(String key, T defaultValue, boolean activate)`**

Retrieve a modification value by its key. If no modification match the given key or if the stored value type and default value type do not match, default value will be returned.

| Parameter    | Type    | Description                                                                                                                                                                          |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| key          | String  | key associated to the modification.                                                                                                                                                  |
| defaultValue | T       | default value to return.                                                                                                                                                             |
| activate     | boolean | (optional) et this parameter to true to automatically report on our server that the current visitor has seen this modification. It is possible to call activateModification() later. |

\\

> 🚧 \* Default value must be one of the following type : `String`, `Boolean`, `Number`, `JSONArray`, 'JSONObject'.

#### Getting campaign information

You may need to send campaign IDs to a third party for reporting and/or analytics purposes. It is possible to retrieve campaigns IDs for a specific modification key.

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build();
visitor.updateContext("isVip", true);
visitor.synchronizeModifications().get();
JSONObject info = visitor.getModificationInfo("displayVipFeature")
```

**`public JSONObject getModificationInfo(String key)`**

| Parameter | Type   | Description                           |
| --------- | ------ | ------------------------------------- |
| key       | String | Key associated with the modification. |

It returns a JSONObject containing `campaignId`, `variationGroupId`, `variationId` and `isReference` keys & values or null if the modification is not found (the user is not affected to the campaign linked to the modification).

#### Activating modifications

Once a modification is displayed on the screen for a user, you must send an activate event to tell Flagship that the user has seen this specific variation.

There are two options for activating a modification:

1. Pass an `activate=true` parameter to the **getModification()** function
2. Use the following **activateModification()** method from the visitor instance.

\\

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build();
visitor.updateContext("isVip", true);
visitor.synchronizeModifications().whenComplete((instance, error) -> {

    Boolean displayVipFeature = visitor.getModification("displayVipFeature", false, true); //send an activation event.

    //or

    Boolean displayVipFeature = visitor.getModification("displayVipFeature", false);

    visitor.activateModification("displayVipFeature");

});
```

\\

**`public void activateModification(String key)`**

Report this user has seen this modification.

| Parameter | Type   | Description                                   |
| --------- | ------ | --------------------------------------------- |
| key       | String | key associated to the modification to report. |

\
\\

### Managing visitor consent

The Visitor class provides a method to let you manage visitor consent for data privacy usage. When False, ***campaign activation*** and ***hits*** will be disabled and cache cleared.

**`public void setConsent(Boolean hasConsented)`**

| Parameter    | Type    | Description                                                                                                                      |
| ------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| hasConsented | Boolean | Set visitor consent for private data usage. When false some features will be deactivated, cache will be deactivated and cleared. |

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build();
  visitor.setConsent(false);
```

> 🚧 When consent is not given: Hits, Activations will be deactivated and all the cached visitor data will be cleared until consent is given again.\
> Only consent tracking requests will enabled in order to clear server-side cached data.

\
\\

### Experience Continuity

In some situations, you may want experience consistency between an anonymous visitor and an authenticed visitor. Flagship provides the following two methods in order to help you to specify when a visitor is authenticated or not.

#### Authenticate

**`public void authenticate(visitorId: String)`**

| Parameter | Type   | Description                          |
| --------- | ------ | ------------------------------------ |
| visitorId | String | id of the new authenticated visitor. |

#### Unauthenticate

**`public void unauthenticate()`**

#### Code example

```java
Visitor visitor1 = Flagship.visitorBuilder("visitor_unique_id").build(); // anonymous visitor lands on your app.

  // Once the visitor log in and is authenticated on your app.
  visitor.authenticate("visitor_id");


  // Once the visitor log out and is unauthenticed on your app.
  visitor.unauthenticate();
```

\
\\

### Hit Tracking

\\

This section helps you track your users in your application and learn how to build hits in order to feed campaign goals. For more information about our measurement protocol, read our [Universal Collect documentation](doc:universal-collect-documentation).

There are four different types of Hits available:

* Page
* Screen
* Transaction
* Item
* Event

**They must all be built and sent with the following function from the`Visitor` instance:**

\\

```java
visitor.sendHit(new Page("https://www.my_domain_com/my_page"))
```

\\

**`public void sendHit(Hit hit)`**

Report this user has seen this modification.

| Parameter | Type | Description  |
| --------- | ---- | ------------ |
| hit       | Hit  | Hit to send. |

\\

#### Hit common optional parameters

\\

```java
Screen screen = new Screen("screen location")
                .withResolution(200, 100)
                .withLocale("fr_FR")
                .withIp("127.0.0.1")
                .withSessionNumber(2);
 visitor.sendHit(screen);
```

\\

| Parameter         | Type     | Description                  |
| ----------------- | -------- | ---------------------------- |
| withIp            | String   | Optional. User IP            |
| withResolution    | int, int | Optional. Screen resolution. |
| withLocale        | String   | Optional. User language      |
| withSessionNumber | int      | Optional. Session number     |

\\

#### Page

\\

This hit should be sent each time a visitor arrives on a new page on the server side.

```java
Page page = new Page("https://www.my_domain_com/my_page")

visitor.sendHit(page);
```

\\

**`public Page(String location)`**

| Builder Parameter | Type   | Description |
| ----------------- | ------ | ----------- |
| location          | String | Valid url.  |

\\

#### Screen

\\

This hit should be sent each time a visitor arrives on an interface on the client side.

```java
Screen screen = new Screen("your_screen_name")

visitor.sendHit(screen);
```

\\

**`public Screen(String location)`**

| Builder Parameter | Type   | Description     |
| ----------------- | ------ | --------------- |
| location          | String | Interface name. |

\\

#### Transaction

\\

This hit should be sent when a user complete a Transaction.

```java
Transaction transaction = new Transaction("#12345", "affiliation")
                .withCouponCode("code")
                .withCurrency("EUR")
                .withItemCount(1)
                .withPaymentMethod("creditcard")
                .withShippingCosts(9.99f)
                .withTaxes(19.99f)
                .withTotalRevenue(199.99f)
                .withShippingMethod("1day");
visitor.sendHit(transaction);
```

\\

**`Transaction(String transactionId, String affiliation)`**

| Builder Parameter  | Type   | Description                                                                                                                        |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| transactionId      | String | Unique identifier for your transaction.                                                                                            |
| affiliation        | String | The name of the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                                   |
| withTotalRevenue   | float  | (optional) Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts. |
| withShippingCosts  | float  | (optional) The total shipping cost of your transaction.                                                                            |
| withShippingMethod | String | (optional) The shipping method for your transaction.                                                                               |
| withTaxes          | float  | (optional) Specifies the total amount of taxes in your transaction.                                                                |
| withCurrency       | String | (optional) Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.                  |
| withPaymentMethod  | String | (optional) Specifies the payment method used for your transaction.                                                                 |
| withItemCount      | int    | (optional) Specifies the number of items in your transaction.                                                                      |
| withCouponCode     | String | (optional) Specifies the coupon code used by the customer in your transaction.                                                     |

\\

#### Item

\\

This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.

```java
Item item = new Item("#12345", "product", "sku123")
                .withItemCategory("test")
                .withItemPrice(199.99f)
                .withItemQuantity(1);
visitor.sendHit(item);
```

\\

**`Item(String transactionId, String productName, String productSku)`**

| Builder Parameter | Type   | Description                                                 |
| ----------------- | ------ | ----------------------------------------------------------- |
| transactionId     | String | Unique identifier for your transaction.                     |
| productName       | String | Name of your item.                                          |
| productSku        | String | Specifies the SKU or item code.                             |
| withItemCategory  | String | (optional) Specifies the category that the item belongs to. |
| withItemPrice     | float  | (optional) Specifies the price for a single item/unit.      |
| withItemQuantity  | int    | (optional) Specifies the number of items purchased.         |

\\

> 📘 The `Item` hit isn't available yet in the Flagship reporting view.

\\

#### Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

\\

```java
Event event = new Event(Event.EventCategory.USER_ENGAGEMENT, "action")
                .withEventLabel("label")
                .withEventValue(100);
visitor.sendHit(event);
```

\\

**`public Event(EventCategory category, String action)`**

| Builder Parameter | Type          | Description                                                                                                                                                                         |
| ----------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| category          | EventCategory | Specifies the category of your event. NOTE: This value must be either `'ACTION_TRACKING'` or `'USER_ENGAGEMENT'`.                                                                   |
| action            | String        | Event name that will also serve as the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                                                             |
| withEventLabel    | String        | (optional) Additional description of your event.                                                                                                                                    |
| withEventValue    | Number        | (optional) Specifies the monetary value associated with an event (e.g. you earn 10 to 100 euros depending on the quality of lead generated). NOTE: this value must be non-negative. |

\\

### Appendix

#### Predefined user context keys : FlagshipContext

The Flagship SDK contains predefined user context keys.

The keys marked as **Yes** in the **Auto-set by SDK** column will be automatically set, while the ones marked as **No** need to be set by the customer.

> 📘 Check the values sent by the SDK by enabling the logs.

You can overwrite these keys at any time. The key-value pairs will be sent to the server in the user context and can be edited in the [Persona](doc:glossary#persona) section of the Flagship platform.

| SDK Variable Name    | Description                                            | Context variable name   | Type       | Auto-set by SDK | Example       |
| -------------------- | ------------------------------------------------------ | ----------------------- | ---------- | --------------- | ------------- |
| DEVICE\_LOCALE       | Language of the device                                 | sdk\_deviceLanguage     | String     | No              | fra           |
| DEVICE\_TYPE         | Type of the device                                     | sdk\_deviceType         | DeviceType | No              | Mobile        |
| DEVICE\_MODEL        | Model of the device                                    | sdk\_deviceModel        | String     | No              | samsung E1200 |
| LOCATION\_CITY       | City geolocation                                       | sdk\_city               | String     | No              | toulouse      |
| LOCATION\_REGION     | Region geolocation                                     | sdk\_region             | String     | No              | occitanie     |
| LOCATION\_COUNTRY    | Country geolocation                                    | sdk\_country            | String     | No              | France        |
| LOCATION\_LAT        | Current Latitude                                       | sdk\_lat                | Double     | No              | 43.623647     |
| LOCATION\_LONG       | Current Longitude                                      | sdk\_long               | Double     | No              | 1.445397      |
| IP                   | IP of the device                                       | sdk\_ip                 | String     | No              | 127.0.0.1     |
| OS\_NAME             | Name of the OS                                         | sdk\_osName             | String     | No              | android / iOS |
| OS\_VERSION\_NAME    | Version name of the OS                                 | sdk\_osVersionName      | String     | No              | 9.0.0         |
| OS\_VERSION\_CODE    | Version code of the OS                                 | sdk\_osVersionCode      | Number     | No              | 24            |
| CARRIER\_NAME        | Name of the carrier or mobile virtual network operator | sdk\_carrierName        | String     | No              | free          |
| INTERNET\_CONNECTION | What is the internet connection                        | sdk\_internetConnection | String     | No              | 5g            |
| APP\_VERSION\_NAME   | Version name of the app                                | sdk\_versionName        | String     | No              | 1.1.2-beta    |
| APP\_VERSION\_CODE   | Version code of the app                                | sdk\_versionCode        | Number     | No              | 40            |
| INTERFACE\_NAME      | Name of the interface                                  | sdk\_interfaceName      | String     | No              | ProductPage   |
| FLAGSHIP\_CLIENT     | Flagship SDK client (Reserved)                         | fs\_client              | String     | Yes             | Java          |
| FLAGSHIP\_VERSION    | Version of the Flagship SDK (Reserved)                 | fs\_version             | String     | Yes             | 2.0.0         |
| FLAGSHIP\_VISITOR    | Current visitor id (Reserved)                          | fs\_users               | String     | Yes             | 2.0.0         |

> 📘 To overwrite the keys, use the [`updateContext`](#update-context-with-predefined-keys-of-context) method


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.abtasty.com/server-side/sdks/java/archived-versions/java-v2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
