You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@unomi.apache.org by sh...@apache.org on 2022/10/03 15:52:15 UTC

svn commit: r1904378 [2/2] - in /unomi/website/manual: 1_4_x/index.html 1_5_x/index.html 1_6_x/index.html latest/images/data-model-overview.png latest/images/data-model.png latest/index.html

Modified: unomi/website/manual/latest/index.html
URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/index.html?rev=1904378&r1=1904377&r2=1904378&view=diff
==============================================================================
--- unomi/website/manual/latest/index.html (original)
+++ unomi/website/manual/latest/index.html Mon Oct  3 15:52:15 2022
@@ -25,49 +25,62 @@
 <li><a href="#_scopes_declarations_are_now_required">1.1.1. Scopes declarations are now required</a></li>
 <li><a href="#_json_schemas">1.1.2. JSON Schemas</a></li>
 <li><a href="#_updated_data_model">1.1.3. Updated data model</a></li>
-<li><a href="#_removal_of_the_web_tracker">1.1.4. Removal of the Web Tracker</a></li>
-<li><a href="#_graphql_api_beta">GraphQL API (beta)</a></li>
-<li><a href="#_migrate_from_unomi_1_x">1.1.5. Migrate from Unomi 1.x</a></li>
-<li><a href="#_elasticsearch_compatibility">1.1.6. Elasticsearch compatibility</a></li>
+<li><a href="#_new_web_tracker">1.1.4. New Web Tracker</a></li>
+<li><a href="#_graphql_api_beta">1.1.5. GraphQL API - beta</a></li>
+<li><a href="#_migrate_from_unomi_1_x">1.1.6. Migrate from Unomi 1.x</a></li>
+<li><a href="#_elasticsearch_compatibility">1.1.7. Elasticsearch compatibility</a></li>
 </ul>
 </li>
 </ul>
 </li>
-<li><a href="#_quick_start">2. Quick start</a>
+<li><a href="#_discover_unomi">2. Discover Unomi</a>
 <ul class="sectlevel2">
 <li><a href="#_quick_start_with_docker">2.1. Quick start with Docker</a></li>
 <li><a href="#_quick_start_manually">2.2. Quick Start manually</a></li>
+<li><a href="#_getting_started_with_unomi">2.3. Getting started with Unomi</a>
+<ul class="sectlevel3">
+<li><a href="#_prerequisites">2.3.1. Prerequisites</a></li>
+<li><a href="#_running_unomi">2.3.2. Running Unomi</a></li>
 </ul>
 </li>
-<li><a href="#_first_steps_with_apache_unomi">3. First steps with Apache Unomi</a>
-<ul class="sectlevel2">
-<li><a href="#_getting_started_with_unomi">3.1. Getting started with Unomi</a>
+<li><a href="#_unomi_web_tracking_tutorial">2.4. Unomi web tracking tutorial</a>
 <ul class="sectlevel3">
-<li><a href="#_prerequisites">3.1.1. Prerequisites</a></li>
-<li><a href="#_running_unomi">3.1.2. Running Unomi</a></li>
+<li><a href="#_installing_the_web_tracker_in_a_web_page">2.4.1. Installing the web tracker in a web page</a></li>
+<li><a href="#_creating_a_scope_to_collect_the_data">2.4.2. Creating a scope to collect the data</a></li>
+<li><a href="#_using_tracker_in_your_own_javascript_projects">2.4.3. Using tracker in your own JavaScript projects</a></li>
+<li><a href="#_viewing_collected_events">2.4.4. Viewing collected events</a></li>
+<li><a href="#_viewing_the_current_profile">2.4.5. Viewing the current profile</a></li>
+<li><a href="#_adding_a_rule">2.4.6. Adding a rule</a></li>
+<li><a href="#_adding_personalization">2.4.7. Adding personalization</a></li>
+<li><a href="#_conclusion">2.4.8. Conclusion</a></li>
+<li><a href="#_next_steps">2.4.9. Next steps</a></li>
 </ul>
 </li>
-<li><a href="#_recipes">3.2. Recipes</a>
-<ul class="sectlevel3">
-<li><a href="#_introduction">3.2.1. Introduction</a></li>
-<li><a href="#_enabling_debug_mode">3.2.2. Enabling debug mode</a></li>
-<li><a href="#_how_to_read_a_profile">3.2.3. How to read a profile</a></li>
-<li><a href="#_how_to_update_a_profile_from_the_public_internet">3.2.4. How to update a profile from the public internet</a></li>
-<li><a href="#_how_to_search_for_profile_events">3.2.5. How to search for profile events</a></li>
-<li><a href="#_how_to_create_a_new_rule">3.2.6. How to create a new rule</a></li>
-<li><a href="#_how_to_search_for_profiles">3.2.7. How to search for profiles</a></li>
-<li><a href="#_getting_updating_consents">3.2.8. Getting / updating consents</a></li>
-<li><a href="#_how_to_send_a_login_event_to_unomi">3.2.9. How to send a login event to Unomi</a></li>
 </ul>
 </li>
-<li><a href="#_request_examples">3.3. Request examples</a>
+<li><a href="#_apache_unomi_recipes_and_requests">3. Apache Unomi Recipes and requests</a>
+<ul class="sectlevel2">
+<li><a href="#_recipes">3.1. Recipes</a>
 <ul class="sectlevel3">
-<li><a href="#_retrieving_your_first_context">3.3.1. Retrieving your first context</a></li>
-<li><a href="#_retrieving_a_context_as_a_json_object">3.3.2. Retrieving a context as a JSON object.</a></li>
-<li><a href="#_accessing_profile_properties_in_a_context">3.3.3. Accessing profile properties in a context</a></li>
-<li><a href="#_sending_events_using_the_context_servlet">3.3.4. Sending events using the context servlet</a></li>
-<li><a href="#_sending_events_using_the_eventcollector_servlet">3.3.5. Sending events using the eventcollector servlet</a></li>
-<li><a href="#_where_to_go_from_here">3.3.6. Where to go from here</a></li>
+<li><a href="#_introduction">3.1.1. Introduction</a></li>
+<li><a href="#_enabling_debug_mode">3.1.2. Enabling debug mode</a></li>
+<li><a href="#_how_to_read_a_profile">3.1.3. How to read a profile</a></li>
+<li><a href="#_how_to_update_a_profile_from_the_public_internet">3.1.4. How to update a profile from the public internet</a></li>
+<li><a href="#_how_to_search_for_profile_events">3.1.5. How to search for profile events</a></li>
+<li><a href="#_how_to_create_a_new_rule">3.1.6. How to create a new rule</a></li>
+<li><a href="#_how_to_search_for_profiles">3.1.7. How to search for profiles</a></li>
+<li><a href="#_getting_updating_consents">3.1.8. Getting / updating consents</a></li>
+<li><a href="#_how_to_send_a_login_event_to_unomi">3.1.9. How to send a login event to Unomi</a></li>
+</ul>
+</li>
+<li><a href="#_request_examples">3.2. Request examples</a>
+<ul class="sectlevel3">
+<li><a href="#_retrieving_your_first_context">3.2.1. Retrieving your first context</a></li>
+<li><a href="#_retrieving_a_context_as_a_json_object">3.2.2. Retrieving a context as a JSON object.</a></li>
+<li><a href="#_accessing_profile_properties_in_a_context">3.2.3. Accessing profile properties in a context</a></li>
+<li><a href="#_sending_events_using_the_context_servlet">3.2.4. Sending events using the context servlet</a></li>
+<li><a href="#_sending_events_using_the_eventcollector_servlet">3.2.5. Sending events using the eventcollector servlet</a></li>
+<li><a href="#_where_to_go_from_here">3.2.6. Where to go from here</a></li>
 </ul>
 </li>
 </ul>
@@ -130,338 +143,347 @@
 <li><a href="#_how_to_add_an_extension_through_the_api">5.3.3. How to add an extension through the API</a></li>
 </ul>
 </li>
-<li><a href="#_graphql_api">5.4. GraphQL API</a>
-<ul class="sectlevel3">
-<li><a href="#_enabling_the_api">5.4.1. Enabling/ the API</a></li>
-<li><a href="#_endpoints">5.4.2. Endpoints</a></li>
-<li><a href="#_graphql_schema">5.4.3. GraphQL Schema</a></li>
 </ul>
 </li>
+<li><a href="#_graphql_api">6. GraphQL API</a>
+<ul class="sectlevel2">
+<li><a href="#_introduction_3">6.1. Introduction</a></li>
+<li><a href="#_enabling_the_api">6.2. Enabling the API</a></li>
+<li><a href="#_endpoints">6.3. Endpoints</a></li>
+<li><a href="#_graphql_schema">6.4. GraphQL Schema</a></li>
 </ul>
 </li>
-<li><a href="#_migrations">6. Migrations</a>
+<li><a href="#_migrations">7. Migrations</a>
 <ul class="sectlevel2">
-<li><a href="#_from_version_1_6_to_2_0">6.1. From version 1.6 to 2.0</a></li>
-<li><a href="#_migration_overview">6.2. Migration Overview</a></li>
-<li><a href="#_updating_applications_consuming_unomi">6.3. Updating applications consuming Unomi</a>
+<li><a href="#_from_version_1_6_to_2_0">7.1. From version 1.6 to 2.0</a></li>
+<li><a href="#_migration_overview">7.2. Migration Overview</a></li>
+<li><a href="#_updating_applications_consuming_unomi">7.3. Updating applications consuming Unomi</a>
 <ul class="sectlevel3">
-<li><a href="#_data_model_changes">6.3.1. Data Model changes</a></li>
-<li><a href="#_create_json_schemas">6.3.2. Create JSON schemas</a></li>
+<li><a href="#_data_model_changes">7.3.1. Data Model changes</a></li>
+<li><a href="#_create_json_schemas">7.3.2. Create JSON schemas</a></li>
 </ul>
 </li>
-<li><a href="#_migrating_your_existing_data">6.4. Migrating your existing data</a>
+<li><a href="#_migrating_your_existing_data">7.4. Migrating your existing data</a>
 <ul class="sectlevel3">
-<li><a href="#_elasticsearch_version_and_capacity">6.4.1. Elasticsearch version and capacity</a></li>
-<li><a href="#_migrate_custom_data">6.4.2. Migrate custom data</a></li>
-<li><a href="#_perform_the_migration">6.4.3. Perform the migration</a></li>
+<li><a href="#_elasticsearch_version_and_capacity">7.4.1. Elasticsearch version and capacity</a></li>
+<li><a href="#_migrate_custom_data">7.4.2. Migrate custom data</a></li>
+<li><a href="#_perform_the_migration">7.4.3. Perform the migration</a></li>
 </ul>
 </li>
-<li><a href="#_from_version_1_5_to_1_6">6.5. From version 1.5 to 1.6</a></li>
-<li><a href="#_from_version_1_4_to_1_5">6.6. From version 1.4 to 1.5</a>
+<li><a href="#_from_version_1_5_to_1_6">7.5. From version 1.5 to 1.6</a></li>
+<li><a href="#_from_version_1_4_to_1_5">7.6. From version 1.4 to 1.5</a>
 <ul class="sectlevel3">
-<li><a href="#_data_model_and_elasticsearch_7">6.6.1. Data model and ElasticSearch 7</a></li>
-<li><a href="#_api_changes">6.6.2. API changes</a></li>
-<li><a href="#_migration_steps">6.6.3. Migration steps</a></li>
+<li><a href="#_data_model_and_elasticsearch_7">7.6.1. Data model and ElasticSearch 7</a></li>
+<li><a href="#_api_changes">7.6.2. API changes</a></li>
+<li><a href="#_migration_steps">7.6.3. Migration steps</a></li>
 </ul>
 </li>
-<li><a href="#_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">6.7. Important changes in public servlets since version 1.5.5 and 2.0.0</a></li>
+<li><a href="#_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">7.7. Important changes in public servlets since version 1.5.5 and 2.0.0</a></li>
 </ul>
 </li>
-<li><a href="#_queries_and_aggregations">7. Queries and aggregations</a>
+<li><a href="#_queries_and_aggregations">8. Queries and aggregations</a>
 <ul class="sectlevel2">
-<li><a href="#_query_counts">7.1. Query counts</a></li>
-<li><a href="#_metrics">7.2. Metrics</a></li>
-<li><a href="#_aggregations">7.3. Aggregations</a>
+<li><a href="#_query_counts">8.1. Query counts</a></li>
+<li><a href="#_metrics">8.2. Metrics</a></li>
+<li><a href="#_aggregations">8.3. Aggregations</a>
 <ul class="sectlevel3">
-<li><a href="#_aggregation_types">7.3.1. Aggregation types</a></li>
+<li><a href="#_aggregation_types">8.3.1. Aggregation types</a></li>
 </ul>
 </li>
 </ul>
 </li>
-<li><a href="#_profile_import_export">8. Profile import &amp; export</a>
+<li><a href="#_profile_import_export">9. Profile import &amp; export</a>
 <ul class="sectlevel2">
-<li><a href="#_importing_profiles">8.1. Importing profiles</a>
+<li><a href="#_importing_profiles">9.1. Importing profiles</a>
 <ul class="sectlevel3">
-<li><a href="#_import_api">8.1.1. Import API</a></li>
+<li><a href="#_import_api">9.1.1. Import API</a></li>
 </ul>
 </li>
-<li><a href="#_exporting_profiles">8.2. Exporting profiles</a>
+<li><a href="#_exporting_profiles">9.2. Exporting profiles</a>
 <ul class="sectlevel3">
-<li><a href="#_export_api">8.2.1. Export API</a></li>
+<li><a href="#_export_api">9.2.1. Export API</a></li>
 </ul>
 </li>
-<li><a href="#_configuration_in_details">8.3. Configuration in details</a></li>
+<li><a href="#_configuration_in_details">9.3. Configuration in details</a></li>
 </ul>
 </li>
-<li><a href="#_consent_management">9. Consent management</a>
+<li><a href="#_consent_management">10. Consent management</a>
 <ul class="sectlevel2">
-<li><a href="#_consent_api">9.1. Consent API</a>
+<li><a href="#_consent_api">10.1. Consent API</a>
 <ul class="sectlevel3">
-<li><a href="#_profiles_with_consents">9.1.1. Profiles with consents</a></li>
-<li><a href="#_consent_type_definitions">9.1.2. Consent type definitions</a></li>
-<li><a href="#_creating_update_a_visitor_consent">9.1.3. Creating / update a visitor consent</a></li>
-<li><a href="#_how_it_works_internally">9.1.4. How it works (internally)</a></li>
+<li><a href="#_profiles_with_consents">10.1.1. Profiles with consents</a></li>
+<li><a href="#_consent_type_definitions">10.1.2. Consent type definitions</a></li>
+<li><a href="#_creating_update_a_visitor_consent">10.1.3. Creating / update a visitor consent</a></li>
+<li><a href="#_how_it_works_internally">10.1.4. How it works (internally)</a></li>
 </ul>
 </li>
 </ul>
 </li>
-<li><a href="#_privacy_management">10. Privacy management</a>
+<li><a href="#_privacy_management">11. Privacy management</a>
 <ul class="sectlevel2">
-<li><a href="#_setting_up_access_to_the_privacy_endpoint">10.1. Setting up access to the privacy endpoint</a></li>
-<li><a href="#_anonymizing_a_profile">10.2. Anonymizing a profile</a></li>
-<li><a href="#_downloading_profile_data">10.3. Downloading profile data</a></li>
-<li><a href="#_deleting_a_profile">10.4. Deleting a profile</a></li>
-<li><a href="#_related">10.5. Related</a></li>
+<li><a href="#_setting_up_access_to_the_privacy_endpoint">11.1. Setting up access to the privacy endpoint</a></li>
+<li><a href="#_anonymizing_a_profile">11.2. Anonymizing a profile</a></li>
+<li><a href="#_downloading_profile_data">11.3. Downloading profile data</a></li>
+<li><a href="#_deleting_a_profile">11.4. Deleting a profile</a></li>
+<li><a href="#_related">11.5. Related</a></li>
 </ul>
 </li>
-<li><a href="#_cluster_setup">11. Cluster setup</a>
+<li><a href="#_cluster_setup">12. Cluster setup</a>
 <ul class="sectlevel2">
-<li><a href="#_cluster_setup_2">11.1. Cluster setup</a></li>
+<li><a href="#_cluster_setup_2">12.1. Cluster setup</a></li>
 </ul>
 </li>
-<li><a href="#_reference">12. Reference</a>
+<li><a href="#_reference">13. Reference</a>
 <ul class="sectlevel2">
-<li><a href="#_useful_apache_unomi_urls">12.1. Useful Apache Unomi URLs</a></li>
-<li><a href="#_how_profile_tracking_works">12.2. How profile tracking works</a>
+<li><a href="#_useful_apache_unomi_urls">13.1. Useful Apache Unomi URLs</a></li>
+<li><a href="#_how_profile_tracking_works">13.2. How profile tracking works</a>
 <ul class="sectlevel3">
-<li><a href="#_steps">12.2.1. Steps</a></li>
+<li><a href="#_steps">13.2.1. Steps</a></li>
 </ul>
 </li>
-<li><a href="#_context_request_flow">12.3. Context Request Flow</a></li>
-<li><a href="#_data_model_overview">12.4. Data Model Overview</a></li>
-<li><a href="#_scope">12.5. Scope</a>
+<li><a href="#_context_request_flow">13.3. Context Request Flow</a></li>
+<li><a href="#_data_model_overview">13.4. Data Model Overview</a></li>
+<li><a href="#_scope">13.5. Scope</a>
 <ul class="sectlevel3">
-<li><a href="#_example">12.5.1. Example</a></li>
+<li><a href="#_example">13.5.1. Example</a></li>
 </ul>
 </li>
-<li><a href="#_item">12.6. Item</a>
+<li><a href="#_item">13.6. Item</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition">12.6.1. Structure definition</a></li>
+<li><a href="#_structure_definition">13.6.1. Structure definition</a></li>
 </ul>
 </li>
-<li><a href="#_metadata">12.7. Metadata</a>
+<li><a href="#_metadata">13.7. Metadata</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_2">12.7.1. Structure definition</a></li>
-<li><a href="#_example_2">12.7.2. Example</a></li>
+<li><a href="#_structure_definition_2">13.7.1. Structure definition</a></li>
+<li><a href="#_example_2">13.7.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_metadataitem">12.8. MetadataItem</a>
+<li><a href="#_metadataitem">13.8. MetadataItem</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_3">12.8.1. Structure definition</a></li>
-<li><a href="#_example_3">12.8.2. Example</a></li>
+<li><a href="#_structure_definition_3">13.8.1. Structure definition</a></li>
+<li><a href="#_example_3">13.8.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_event">12.9. Event</a>
+<li><a href="#_event">13.9. Event</a>
 <ul class="sectlevel3">
-<li><a href="#_fields">12.9.1. Fields</a></li>
-<li><a href="#_event_types">12.9.2. Event types</a></li>
+<li><a href="#_fields">13.9.1. Fields</a></li>
+<li><a href="#_event_types">13.9.2. Event types</a></li>
 </ul>
 </li>
-<li><a href="#_profile">12.10. Profile</a>
+<li><a href="#_profile">13.10. Profile</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_4">12.10.1. Structure definition</a></li>
-<li><a href="#_example_4">12.10.2. Example</a></li>
+<li><a href="#_structure_definition_4">13.10.1. Structure definition</a></li>
+<li><a href="#_example_4">13.10.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_persona">12.11. Persona</a>
+<li><a href="#_persona">13.11. Persona</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_5">12.11.1. Structure definition</a></li>
-<li><a href="#_example_5">12.11.2. Example</a></li>
+<li><a href="#_structure_definition_5">13.11.1. Structure definition</a></li>
+<li><a href="#_example_5">13.11.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_consent">12.12. Consent</a>
+<li><a href="#_consent">13.12. Consent</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_6">12.12.1. Structure definition</a></li>
-<li><a href="#_example_6">12.12.2. Example</a></li>
+<li><a href="#_structure_definition_6">13.12.1. Structure definition</a></li>
+<li><a href="#_example_6">13.12.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_session">12.13. Session</a>
+<li><a href="#_session">13.13. Session</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_7">12.13.1. Structure definition</a></li>
-<li><a href="#_example_7">12.13.2. Example</a></li>
+<li><a href="#_structure_definition_7">13.13.1. Structure definition</a></li>
+<li><a href="#_example_7">13.13.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_segment">12.14. Segment</a>
+<li><a href="#_segment">13.14. Segment</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_8">12.14.1. Structure definition</a></li>
-<li><a href="#_example_8">12.14.2. Example</a></li>
+<li><a href="#_structure_definition_8">13.14.1. Structure definition</a></li>
+<li><a href="#_example_8">13.14.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_condition">12.15. Condition</a>
+<li><a href="#_condition">13.15. Condition</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_9">12.15.1. Structure definition</a></li>
-<li><a href="#_example_9">12.15.2. Example</a></li>
+<li><a href="#_structure_definition_9">13.15.1. Structure definition</a></li>
+<li><a href="#_example_9">13.15.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_rule">12.16. Rule</a>
+<li><a href="#_rule">13.16. Rule</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_10">12.16.1. Structure definition</a></li>
-<li><a href="#_example_10">12.16.2. Example</a></li>
+<li><a href="#_structure_definition_10">13.16.1. Structure definition</a></li>
+<li><a href="#_example_10">13.16.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_action">12.17. Action</a>
+<li><a href="#_action">13.17. Action</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_11">12.17.1. Structure definition</a></li>
-<li><a href="#_example_11">12.17.2. Example</a></li>
+<li><a href="#_structure_definition_11">13.17.1. Structure definition</a></li>
+<li><a href="#_example_11">13.17.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_list">12.18. List</a>
+<li><a href="#_list">13.18. List</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_12">12.18.1. Structure definition</a></li>
-<li><a href="#_example_12">12.18.2. Example</a></li>
+<li><a href="#_structure_definition_12">13.18.1. Structure definition</a></li>
+<li><a href="#_example_12">13.18.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_goal">12.19. Goal</a>
+<li><a href="#_goal">13.19. Goal</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_13">12.19.1. Structure definition</a></li>
-<li><a href="#_example_13">12.19.2. Example</a></li>
+<li><a href="#_structure_definition_13">13.19.1. Structure definition</a></li>
+<li><a href="#_example_13">13.19.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_campaign">12.20. Campaign</a>
+<li><a href="#_campaign">13.20. Campaign</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_14">12.20.1. Structure definition</a></li>
-<li><a href="#_example_14">12.20.2. Example</a></li>
+<li><a href="#_structure_definition_14">13.20.1. Structure definition</a></li>
+<li><a href="#_example_14">13.20.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_scoring_plan">12.21. Scoring plan</a>
+<li><a href="#_scoring_plan">13.21. Scoring plan</a>
 <ul class="sectlevel3">
-<li><a href="#_structure_definition_15">12.21.1. Structure definition</a></li>
-<li><a href="#_example_15">12.21.2. Example</a></li>
+<li><a href="#_structure_definition_15">13.21.1. Structure definition</a></li>
+<li><a href="#_example_15">13.21.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_event_types">12.22. Built-in Event types</a>
+<li><a href="#_built_in_event_types">13.22. Built-in Event types</a>
 <ul class="sectlevel3">
-<li><a href="#_login_event_type">12.22.1. Login event type</a></li>
-<li><a href="#_view_event_type">12.22.2. View event type</a></li>
-<li><a href="#_form_event_type">12.22.3. Form event type</a></li>
-<li><a href="#_update_properties_event_type">12.22.4. Update properties event type</a></li>
-<li><a href="#_identify_event_type">12.22.5. Identify event type</a></li>
-<li><a href="#_session_created_event_type">12.22.6. Session created event type</a></li>
-<li><a href="#_goal_event_type">12.22.7. Goal event type</a></li>
-<li><a href="#_modify_consent_event_type">12.22.8. Modify consent event type</a></li>
+<li><a href="#_login_event_type">13.22.1. Login event type</a></li>
+<li><a href="#_view_event_type">13.22.2. View event type</a></li>
+<li><a href="#_form_event_type">13.22.3. Form event type</a></li>
+<li><a href="#_update_properties_event_type">13.22.4. Update properties event type</a></li>
+<li><a href="#_identify_event_type">13.22.5. Identify event type</a></li>
+<li><a href="#_session_created_event_type">13.22.6. Session created event type</a></li>
+<li><a href="#_goal_event_type">13.22.7. Goal event type</a></li>
+<li><a href="#_modify_consent_event_type">13.22.8. Modify consent event type</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_condition_types">12.23. Built-in condition types</a>
+<li><a href="#_built_in_condition_types">13.23. Built-in condition types</a>
 <ul class="sectlevel3">
-<li><a href="#_existing_condition_type_descriptors">12.23.1. Existing condition type descriptors</a></li>
+<li><a href="#_existing_condition_type_descriptors">13.23.1. Existing condition type descriptors</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_action_types">12.24. Built-in action types</a>
+<li><a href="#_built_in_action_types">13.24. Built-in action types</a>
 <ul class="sectlevel3">
-<li><a href="#_existing_action_types_descriptors">12.24.1. Existing action types descriptors</a></li>
+<li><a href="#_existing_action_types_descriptors">13.24.1. Existing action types descriptors</a></li>
 </ul>
 </li>
-<li><a href="#_updating_events_using_the_context_servlet">12.25. Updating Events Using the Context Servlet</a>
+<li><a href="#_updating_events_using_the_context_servlet">13.25. Updating Events Using the Context Servlet</a>
 <ul class="sectlevel3">
-<li><a href="#_solution">12.25.1. Solution</a></li>
-<li><a href="#_defining_rules">12.25.2. Defining Rules</a></li>
+<li><a href="#_solution">13.25.1. Solution</a></li>
+<li><a href="#_defining_rules">13.25.2. Defining Rules</a></li>
 </ul>
 </li>
+<li><a href="#_unomi_web_tracker_reference">13.26. Unomi Web Tracker reference</a>
+<ul class="sectlevel3">
+<li><a href="#_custom_events">13.26.1. Custom events</a></li>
+<li><a href="#_integrating_with_tag_managers">13.26.2. Integrating with tag managers</a></li>
+<li><a href="#_cookiesession_handling">13.26.3. Cookie/session handling</a></li>
+<li><a href="#_javascript_api">13.26.4. JavaScript api</a></li>
 </ul>
 </li>
-<li><a href="#_integration_samples">13. Integration samples</a>
+</ul>
+</li>
+<li><a href="#_integration_samples">14. Integration samples</a>
 <ul class="sectlevel2">
-<li><a href="#_samples">13.1. Samples</a></li>
-<li><a href="#_login_sample">13.2. Login sample</a>
+<li><a href="#_samples">14.1. Samples</a></li>
+<li><a href="#_login_sample">14.2. Login sample</a>
 <ul class="sectlevel3">
-<li><a href="#_warning">13.2.1. Warning !</a></li>
-<li><a href="#_installing_the_samples">13.2.2. Installing the samples</a></li>
+<li><a href="#_warning">14.2.1. Warning !</a></li>
+<li><a href="#_installing_the_samples">14.2.2. Installing the samples</a></li>
 </ul>
 </li>
-<li><a href="#_twitter_sample">13.3. Twitter sample</a>
+<li><a href="#_twitter_sample">14.3. Twitter sample</a>
 <ul class="sectlevel3">
-<li><a href="#_overview">13.3.1. Overview</a></li>
-<li><a href="#_interacting_with_the_context_server">13.3.2. Interacting with the context server</a></li>
-<li><a href="#_retrieving_context_information_from_unomi_using_the_context_servlet">13.3.3. Retrieving context information from Unomi using the context servlet</a></li>
+<li><a href="#_overview">14.3.1. Overview</a></li>
+<li><a href="#_interacting_with_the_context_server">14.3.2. Interacting with the context server</a></li>
+<li><a href="#_retrieving_context_information_from_unomi_using_the_context_servlet">14.3.3. Retrieving context information from Unomi using the context servlet</a></li>
 </ul>
 </li>
-<li><a href="#_example_24">13.4. Example</a>
+<li><a href="#_example_24">14.4. Example</a>
 <ul class="sectlevel3">
-<li><a href="#_html_page">13.4.1. HTML page</a></li>
-<li><a href="#_javascript">13.4.2. Javascript</a></li>
+<li><a href="#_html_page">14.4.1. HTML page</a></li>
+<li><a href="#_javascript">14.4.2. Javascript</a></li>
 </ul>
 </li>
-<li><a href="#_conclusion">13.5. Conclusion</a></li>
-<li><a href="#_annex">13.6. Annex</a></li>
-<li><a href="#_weather_update_sample">13.7. Weather update sample</a></li>
+<li><a href="#_conclusion_2">14.5. Conclusion</a></li>
+<li><a href="#_annex">14.6. Annex</a></li>
+<li><a href="#_weather_update_sample">14.7. Weather update sample</a></li>
 </ul>
 </li>
-<li><a href="#_connectors">14. Connectors</a>
+<li><a href="#_connectors">15. Connectors</a>
 <ul class="sectlevel2">
-<li><a href="#_connectors_2">14.1. Connectors</a>
+<li><a href="#_connectors_2">15.1. Connectors</a>
 <ul class="sectlevel3">
-<li><a href="#_call_for_contributors">14.1.1. Call for contributors</a></li>
+<li><a href="#_call_for_contributors">15.1.1. Call for contributors</a></li>
 </ul>
 </li>
-<li><a href="#_salesforce_connector">14.2. Salesforce Connector</a>
+<li><a href="#_salesforce_connector">15.2. Salesforce Connector</a>
 <ul class="sectlevel3">
-<li><a href="#_getting_started">14.2.1. Getting started</a></li>
-<li><a href="#_properties">14.2.2. Properties</a></li>
-<li><a href="#_hot_deploying_updates_to_the_salesforce_connector_for_developers">14.2.3. Hot-deploying updates to the Salesforce connector (for developers)</a></li>
-<li><a href="#_using_the_salesforce_workbench_for_testing_rest_api">14.2.4. Using the Salesforce Workbench for testing REST API</a></li>
-<li><a href="#_setting_up_streaming_push_queries">14.2.5. Setting up Streaming Push queries</a></li>
-<li><a href="#_executing_the_unit_tests">14.2.6. Executing the unit tests</a></li>
+<li><a href="#_getting_started">15.2.1. Getting started</a></li>
+<li><a href="#_properties">15.2.2. Properties</a></li>
+<li><a href="#_hot_deploying_updates_to_the_salesforce_connector_for_developers">15.2.3. Hot-deploying updates to the Salesforce connector (for developers)</a></li>
+<li><a href="#_using_the_salesforce_workbench_for_testing_rest_api">15.2.4. Using the Salesforce Workbench for testing REST API</a></li>
+<li><a href="#_setting_up_streaming_push_queries">15.2.5. Setting up Streaming Push queries</a></li>
+<li><a href="#_executing_the_unit_tests">15.2.6. Executing the unit tests</a></li>
 </ul>
 </li>
-<li><a href="#_mailchimp_connector">14.3. MailChimp Connector</a>
+<li><a href="#_mailchimp_connector">15.3. MailChimp Connector</a>
 <ul class="sectlevel3">
-<li><a href="#_getting_started_2">14.3.1. Getting started</a></li>
+<li><a href="#_getting_started_2">15.3.1. Getting started</a></li>
 </ul>
 </li>
 </ul>
 </li>
-<li><a href="#_developers">15. Developers</a>
+<li><a href="#_developers">16. Developers</a>
 <ul class="sectlevel2">
-<li><a href="#_building">15.1. Building</a>
+<li><a href="#_building">16.1. Building</a>
 <ul class="sectlevel3">
-<li><a href="#_initial_setup">15.1.1. Initial Setup</a></li>
-<li><a href="#_building_2">15.1.2. Building</a></li>
-<li><a href="#_installing_an_elasticsearch_server">15.1.3. Installing an ElasticSearch server</a></li>
-<li><a href="#_deploying_the_generated_binary_package">15.1.4. Deploying the generated binary package</a></li>
-<li><a href="#_deploying_into_an_existing_karaf_server">15.1.5. Deploying into an existing Karaf server</a></li>
-<li><a href="#_jdk_selection_on_mac_os_x">15.1.6. JDK Selection on Mac OS X</a></li>
-<li><a href="#_running_the_integration_tests">15.1.7. Running the integration tests</a></li>
-<li><a href="#_testing_with_an_example_page">15.1.8. Testing with an example page</a></li>
-</ul>
-</li>
-<li><a href="#_ssh_shell_commands">15.2. SSH Shell Commands</a>
-<ul class="sectlevel3">
-<li><a href="#_using_the_shell">15.2.1. Using the shell</a></li>
-<li><a href="#_lifecycle_commands">15.2.2. Lifecycle commands</a></li>
-<li><a href="#_runtime_commands">15.2.3. Runtime commands</a></li>
-</ul>
-</li>
-<li><a href="#_writing_plugins">15.3. Writing Plugins</a></li>
-<li><a href="#_types_vs_instances">15.4. Types vs. instances</a></li>
-<li><a href="#_plugin_structure">15.5. Plugin structure</a></li>
-<li><a href="#_extension_points">15.6. Extension points</a>
-<ul class="sectlevel3">
-<li><a href="#_actiontype">15.6.1. ActionType</a></li>
-<li><a href="#_conditiontype">15.6.2. ConditionType</a></li>
-<li><a href="#_persona_2">15.6.3. Persona</a></li>
-<li><a href="#_propertymergestrategytype">15.6.4. PropertyMergeStrategyType</a></li>
-<li><a href="#_propertytype">15.6.5. PropertyType</a></li>
-<li><a href="#_rule_2">15.6.6. Rule</a></li>
-<li><a href="#_scoring">15.6.7. Scoring</a></li>
-<li><a href="#_segments">15.6.8. Segments</a></li>
-<li><a href="#_tag">15.6.9. Tag</a></li>
-<li><a href="#_valuetype">15.6.10. ValueType</a></li>
-</ul>
-</li>
-<li><a href="#_custom_plugins">15.7. Custom plugins</a>
-<ul class="sectlevel3">
-<li><a href="#_creating_a_plugin">15.7.1. Creating a plugin</a></li>
-<li><a href="#_deployment_and_custom_definition">15.7.2. Deployment and custom definition</a></li>
-<li><a href="#_predefined_segments">15.7.3. Predefined segments</a></li>
-<li><a href="#_predefined_rules">15.7.4. Predefined rules</a></li>
-<li><a href="#_predefined_properties">15.7.5. Predefined properties</a></li>
-<li><a href="#_predefined_child_conditions">15.7.6. Predefined child conditions</a></li>
-<li><a href="#_predefined_personas">15.7.7. Predefined personas</a></li>
-<li><a href="#_custom_action_types">15.7.8. Custom action types</a></li>
-<li><a href="#_custom_condition_types">15.7.9. Custom condition types</a></li>
+<li><a href="#_initial_setup">16.1.1. Initial Setup</a></li>
+<li><a href="#_building_2">16.1.2. Building</a></li>
+<li><a href="#_installing_an_elasticsearch_server">16.1.3. Installing an ElasticSearch server</a></li>
+<li><a href="#_deploying_the_generated_binary_package">16.1.4. Deploying the generated binary package</a></li>
+<li><a href="#_deploying_into_an_existing_karaf_server">16.1.5. Deploying into an existing Karaf server</a></li>
+<li><a href="#_jdk_selection_on_mac_os_x">16.1.6. JDK Selection on Mac OS X</a></li>
+<li><a href="#_running_the_integration_tests">16.1.7. Running the integration tests</a></li>
+<li><a href="#_testing_with_an_example_page">16.1.8. Testing with an example page</a></li>
+</ul>
+</li>
+<li><a href="#_ssh_shell_commands">16.2. SSH Shell Commands</a>
+<ul class="sectlevel3">
+<li><a href="#_using_the_shell">16.2.1. Using the shell</a></li>
+<li><a href="#_lifecycle_commands">16.2.2. Lifecycle commands</a></li>
+<li><a href="#_runtime_commands">16.2.3. Runtime commands</a></li>
+</ul>
+</li>
+<li><a href="#_writing_plugins">16.3. Writing Plugins</a></li>
+<li><a href="#_types_vs_instances">16.4. Types vs. instances</a></li>
+<li><a href="#_plugin_structure">16.5. Plugin structure</a></li>
+<li><a href="#_extension_points">16.6. Extension points</a>
+<ul class="sectlevel3">
+<li><a href="#_actiontype">16.6.1. ActionType</a></li>
+<li><a href="#_conditiontype">16.6.2. ConditionType</a></li>
+<li><a href="#_persona_2">16.6.3. Persona</a></li>
+<li><a href="#_propertymergestrategytype">16.6.4. PropertyMergeStrategyType</a></li>
+<li><a href="#_propertytype">16.6.5. PropertyType</a></li>
+<li><a href="#_rule_2">16.6.6. Rule</a></li>
+<li><a href="#_scoring">16.6.7. Scoring</a></li>
+<li><a href="#_segments">16.6.8. Segments</a></li>
+<li><a href="#_tag">16.6.9. Tag</a></li>
+<li><a href="#_valuetype">16.6.10. ValueType</a></li>
+</ul>
+</li>
+<li><a href="#_custom_plugins">16.7. Custom plugins</a>
+<ul class="sectlevel3">
+<li><a href="#_creating_a_plugin">16.7.1. Creating a plugin</a></li>
+<li><a href="#_deployment_and_custom_definition">16.7.2. Deployment and custom definition</a></li>
+<li><a href="#_predefined_segments">16.7.3. Predefined segments</a></li>
+<li><a href="#_predefined_rules">16.7.4. Predefined rules</a></li>
+<li><a href="#_predefined_properties">16.7.5. Predefined properties</a></li>
+<li><a href="#_predefined_child_conditions">16.7.6. Predefined child conditions</a></li>
+<li><a href="#_predefined_personas">16.7.7. Predefined personas</a></li>
+<li><a href="#_custom_action_types">16.7.8. Custom action types</a></li>
+<li><a href="#_custom_condition_types">16.7.9. Custom condition types</a></li>
 </ul>
 </li>
-<li><a href="#_migration_patches">15.8. Migration patches</a></li>
+<li><a href="#_migration_patches">16.8. Migration patches</a></li>
 </ul>
 </li>
 </ul>
@@ -533,12 +555,56 @@ If the received payload does not match a
 <p>The introduction of JSON schema required us to modify Apache Unomi data model, One of the key differences is the removal of open maps.</p>
 </div>
 <div class="paragraph">
-<p>For example, the following event model in Apache Unomi 1.x:</p>
+<p>The properties field in the events objects provided by unomi are now restricted by JSON schema.
+This means object properties must be declared in a JSON schema for an event to be accepted.</p>
+</div>
+<div class="paragraph">
+<p>A new property, flattenedProperties has been introduced to the event object, this property has been added to store the properties as
+flattened in Elasticsearch and should avoid mapping explosion for dynamic properties.</p>
+</div>
+<div class="paragraph">
+<p>If there is dynamic properties that you want to send with your event, you should use the flattenedProperties field of the event.</p>
+</div>
+<div class="paragraph">
+<p>It&#8217;s also necessary to specify the format of the values which are added to flattenedProperties by JSON schema but these value will be
+stored as flattened and will not create dynamic mapping contrary to the properties field of the events.</p>
+</div>
+<div class="paragraph">
+<p>Here is an example for objects that used dynamic properties for URL parameters:</p>
+</div>
+<div class="paragraph">
+<p>The following event example in Apache Unomi 1.x:</p>
 </div>
 <div class="listingblock">
 <div class="content">
 <pre class="highlight"><code>{
-    "TODO": "ADD JSON"
+    "eventType":"view",
+    "scope":"digitall",
+    "properties":{
+        "URLParameters":{
+           "utm_source":"source"
+        }
+    },
+    "target":{
+        "scope":"digitall",
+        "itemId":"30c0a9e3-4330-417d-9c66-4c1beec85f08",
+        "itemType":"page",
+        "properties":{
+           "pageInfo":{
+              "pageID":"30c0a9e3-4330-417d-9c66-4c1beec85f08",
+              "nodeType":"jnt:page",
+              "pageName":"Home",
+              ...
+           },
+           "attributes":{},
+           "consentTypes":[]
+        }
+    },
+    "source":{
+        "scope":"digitall",
+        "itemId":"ff5886e0-d75a-4061-9de9-d90dfc9e18d8",
+        "itemType":"site"
+    }
 }</code></pre>
 </div>
 </div>
@@ -548,28 +614,52 @@ If the received payload does not match a
 <div class="listingblock">
 <div class="content">
 <pre class="highlight"><code>{
-    "TODO": "ADD JSON"
+    "eventType":"view",
+    "scope":"digitall",
+    "flattenedProperties":{
+        "URLParameters":{
+           "utm_source":"source"
+        }
+    },
+    "target":{
+        "scope":"digitall",
+        "itemId":"30c0a9e3-4330-417d-9c66-4c1beec85f08",
+        "itemType":"page",
+        "properties":{
+           "pageInfo":{
+              "pageID":"30c0a9e3-4330-417d-9c66-4c1beec85f08",
+              "nodeType":"jnt:page",
+              "pageName":"Home",
+              ...
+           },
+           "attributes":{},
+           "consentTypes":[]
+        }
+    },
+    "source":{
+        "scope":"digitall",
+        "itemId":"ff5886e0-d75a-4061-9de9-d90dfc9e18d8",
+        "itemType":"site"
+    }
 }</code></pre>
 </div>
 </div>
 <div class="paragraph">
-<p>Most objects were refactored as part of this new release.</p>
-</div>
-<div class="paragraph">
 <p>If using the default Apache 1.x data model, our Unomi 2 migration process will handle the data model changes for you.
 If you are using custom events/objects, please refer to the detailed migration guide for more details.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_removal_of_the_web_tracker">1.1.4. Removal of the Web Tracker</h4>
+<h4 id="_new_web_tracker">1.1.4. New Web Tracker</h4>
+<div class="paragraph">
+<p>Apache Unomi 2.0 Web Tracker, located in <code>extensions/web-tracker/</code> has been completely rewritten. It is no longer based on an external library and is fully self-sufficient. It is based on an external contribution that has been used in production on many sites.</p>
+</div>
 <div class="paragraph">
-<p>Apache Unomi 2.0 Web Tracker, previously located in <code>extensions/web-tracker/</code> has been removed.
-We considered it as outdated and instead recommend implementing your own tracker logic based on your project
-use case.</p>
+<p>You can find more information about the new web tracker here: [TODO ADD LINK]</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_graphql_api_beta">GraphQL API (beta)</h4>
+<h4 id="_graphql_api_beta">1.1.5. GraphQL API - beta</h4>
 <div class="paragraph">
 <p>Apache Unomi 2.0 sees the introduction of a new (beta) GraphQL API.
 Available behind a feature flag (the API disabled by default), the GraphQL API is available for you to play with.</p>
@@ -582,7 +672,7 @@ Available behind a feature flag (the API
 </div>
 </div>
 <div class="sect3">
-<h4 id="_migrate_from_unomi_1_x">1.1.5. Migrate from Unomi 1.x</h4>
+<h4 id="_migrate_from_unomi_1_x">1.1.6. Migrate from Unomi 1.x</h4>
 <div class="paragraph">
 <p>To facilitate migration we prepared a set of scripts that will automatically handle the migration of your data from Apache Unomi 1.5+ to Apache Unomi 2.0.</p>
 </div>
@@ -596,7 +686,7 @@ More details about migration (incl. of c
 </div>
 </div>
 <div class="sect3">
-<h4 id="_elasticsearch_compatibility">1.1.6. Elasticsearch compatibility</h4>
+<h4 id="_elasticsearch_compatibility">1.1.7. Elasticsearch compatibility</h4>
 <div class="paragraph">
 <p>We currently recommend using Elasticsearch 7.17.5 with Apache Unomi 2.0,
 this ensure you are on a recent version that is not impacted by the log4j vulnerabilities (fixed in Elasticsearch 7.16.3).</p>
@@ -612,7 +702,7 @@ due to the above-mentioned log4j vulnera
 </div>
 </div>
 <div class="sect1">
-<h2 id="_quick_start">2. Quick start</h2>
+<h2 id="_discover_unomi">2. Discover Unomi</h2>
 <div class="sectionbody">
 <div class="sect2">
 <h3 id="_quick_start_with_docker">2.1. Quick start with Docker</h3>
@@ -700,19 +790,14 @@ make sure you are using the proper versi
 </ul>
 </div>
 </div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_first_steps_with_apache_unomi">3. First steps with Apache Unomi</h2>
-<div class="sectionbody">
 <div class="sect2">
-<h3 id="_getting_started_with_unomi">3.1. Getting started with Unomi</h3>
+<h3 id="_getting_started_with_unomi">2.3. Getting started with Unomi</h3>
 <div class="paragraph">
 <p>We will first get you up and running with an example. We will then lift the corner of the cover somewhat and explain
 in greater details what just happened.</p>
 </div>
 <div class="sect3">
-<h4 id="_prerequisites">3.1.1. Prerequisites</h4>
+<h4 id="_prerequisites">2.3.1. Prerequisites</h4>
 <div class="paragraph">
 <p>This document assumes working knowledge of <a href="https://git-scm.com/">git</a> to be able to retrieve the code for Unomi and the example.
 Additionally, you will require a working Java 8 or above install. Refer to <a href="http://www.oracle.com/technetwork/java/javase/">http://www.oracle.com/technetwork/java/javase/</a> for details on how to download and install Java SE 8 or greater.</p>
@@ -741,7 +826,7 @@ to get the latest information about Elas
 </div>
 </div>
 <div class="sect3">
-<h4 id="_running_unomi">3.1.2. Running Unomi</h4>
+<h4 id="_running_unomi">2.3.2. Running Unomi</h4>
 <div class="sect4">
 <h5 id="_start_unomi">Start Unomi</h5>
 <div class="paragraph">
@@ -777,16 +862,386 @@ requests you can do once your server is
 </div>
 </div>
 <div class="sect2">
-<h3 id="_recipes">3.2. Recipes</h3>
+<h3 id="_unomi_web_tracking_tutorial">2.4. Unomi web tracking tutorial</h3>
+<div class="paragraph">
+<p>In this tutorial we will guide through the basic steps of getting started with a web tracking project. You will see how to integrate the built-in web tracker with an existing web site and what this enables.</p>
+</div>
+<div class="sect3">
+<h4 id="_installing_the_web_tracker_in_a_web_page">2.4.1. Installing the web tracker in a web page</h4>
+<div class="paragraph">
+<p>Using the built-in tracker is pretty simple, simply add the following code to your HTML page :</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>&lt;script type="text/javascript" src="/tracker/unomi-web-tracker.min.js"&gt;&lt;/script&gt;</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or you can also use the non-minified version that is available here:</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>&lt;script type="text/javascript" src="/tracker/unomi-web-tracker.js"&gt;&lt;/script&gt;</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This will only load the tracker. To initialize it use a snipper like the following code:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    &lt;script type="text/javascript"&gt;
+        (function () {
+            const unomiTrackerTestConf = {
+                "scope": "unomi-tracker-test",
+                "site": {
+                    "siteInfo": {
+                        "siteID": "unomi-tracker-test"
+                    }
+                },
+                "page": {
+                    "pageInfo": {
+                        "pageID": "unomi-tracker-test-page",
+                        "pageName": document.title,
+                        "pagePath": document.location.pathname,
+                        "destinationURL": document.location.origin + document.location.pathname,
+                        "language": "en",
+                        "categories": [],
+                        "tags": []
+                    },
+                    "attributes": {},
+                    "consentTypes": []
+                },
+                "events:": [],
+                "wemInitConfig": {
+                    "contextServerUrl": document.location.origin,
+                    "timeoutInMilliseconds": "1500",
+                    "contextServerCookieName": "context-profile-id",
+                    "activateWem": true,
+                    "trackerSessionIdCookieName": "unomi-tracker-test-session-id",
+                    "trackerProfileIdCookieName": "unomi-tracker-test-profile-id"
+                }
+            }
+
+            // generate a new session
+            if (unomiWebTracker.getCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName) == null) {
+                unomiWebTracker.setCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName, unomiWebTracker.generateGuid(), 1);
+            }
+
+            // init tracker with our conf
+            unomiWebTracker.initTracker(unomiTrackerTestConf);
+
+            unomiWebTracker._registerCallback(() =&gt; {
+                console.log("Unomi tracker test successfully loaded context", unomiWebTracker.getLoadedContext());
+            }, 'Unomi tracker test callback example');
+
+            // start the tracker
+            unomiWebTracker.startTracker();
+        })();
+    &lt;/script&gt;</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_creating_a_scope_to_collect_the_data">2.4.2. Creating a scope to collect the data</h4>
+<div class="paragraph">
+<p>You might notice the <code>scope</code> used in the snippet. All events sent to Unomi must be associated with a scope, that must have been created before events are accepted. So in order to make sure the events are collected with the above Javascript code, we must create a scope with the following request.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/scopes' \
+  --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
+  --header 'Content-Type: application/json' \
+  --data-raw '{
+    "itemId": "unomi-tracker-test",
+    "metadata": {
+      "id": "unomi-tracker-test",
+      "name": "Unomi tracker Test Scope"
+    }
+  }'</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The authorization is the default username/password for the REST API, which is <code>karaf:karaf</code> and you that should definitely be changed as soon as possible by modifying the <code>etc/users.properties</code> file.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_using_tracker_in_your_own_javascript_projects">2.4.3. Using tracker in your own JavaScript projects</h4>
+<div class="paragraph">
+<p>The tracker also exists as an NPM library that you can integrate with your own Javascript projects. You can find the library here:</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>https://www.npmjs.com/package/apache-unomi-tracker</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Here&#8217;s an example on how to use it:</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>yarn add apache-unomi-tracker</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>You can then simply use it in your JS code using something like this:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">import {useTracker} from "apache-unomi-tracker";
+
+(function () {
+    const unomiWebTracker = useTracker();
+    const unomiTrackerTestConf = {
+        "scope": "unomi-tracker-test",
+        "site": {
+            "siteInfo": {
+                "siteID": "unomi-tracker-test"
+            }
+        },
+        "page": {
+            "pageInfo": {
+                "pageID": "unomi-tracker-test-page",
+                "pageName": document.title,
+                "pagePath": document.location.pathname,
+                "destinationURL": document.location.origin + document.location.pathname,
+                "language": "en",
+                "categories": [],
+                "tags": []
+            },
+            "attributes": {},
+            "consentTypes": []
+        },
+        "events:": [],
+        "wemInitConfig": {
+            "contextServerUrl": document.location.origin,
+            "timeoutInMilliseconds": "1500",
+            "contextServerCookieName": "context-profile-id",
+            "activateWem": true,
+            "trackerSessionIdCookieName": "unomi-tracker-test-session-id",
+            "trackerProfileIdCookieName": "unomi-tracker-test-profile-id"
+        }
+    }
+
+    // generate a new session
+    if (unomiWebTracker.getCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName) == null) {
+        unomiWebTracker.setCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName, unomiWebTracker.generateGuid(), 1);
+    }
+
+    // init tracker with our conf
+    unomiWebTracker.initTracker(unomiTrackerTestConf);
+
+    unomiWebTracker._registerCallback(() =&gt; {
+        console.log("Unomi tracker test successfully loaded context", unomiWebTracker.getLoadedContext());
+    }, 'Unomi tracker test callback example');
+
+    // start the tracker
+    unomiWebTracker.startTracker();
+})();</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_viewing_collected_events">2.4.4. Viewing collected events</h4>
+<div class="paragraph">
+<p>There are multiple ways to view the events that were received. For example, you could use the following cURL request:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/events/search' \
+  --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
+  --header 'Content-Type: application/json' \
+  --data-raw '{
+    "sortby" : "timeStamp:desc",
+    "condition" : {
+      "type" : "matchAllCondition"
+    }
+  }'</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Another (powerful) way to look at events is to use the SSH Console. You can connect to it with the following shell command:</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>ssh -p 8102 karaf@localhost</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Using the same username password (karaf:karaf) and then you can use command such as :</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>event-tail</code> to view in realtime the events as they come in (CTRL+C to stop)</p>
+</li>
+<li>
+<p><code>event-list</code> to view the latest events</p>
+</li>
+<li>
+<p><code>event-view EVENT_ID</code> to view the details of a specific event</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_viewing_the_current_profile">2.4.5. Viewing the current profile</h4>
+<div class="paragraph">
+<p>By default, Unomi uses a cookie called context-profile-id to keep track of the current profile. You can use this the value of this cookie which contains a UUID to lookup the details of the profile. For example with the SSH console you can simply to:</p>
+</div>
+<div class="literalblock">
+<div class="content">
+<pre>profile-view PROFILE_UUID</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Which will print out the details of the profile with the associated ID.
+Another interesting command is <code>profile-list</code> to list all the recently modified profiles</p>
+</div>
+<div class="paragraph">
+<p>You could also retrieve the profile details using the REST API by using a request such as this one:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request GET 'http://localhost:8181/cxs/profiles/PROFILE_UUID' \
+--header 'Authorization: Basic a2FyYWY6a2FyYWY=' \</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_adding_a_rule">2.4.6. Adding a rule</h4>
+<div class="paragraph">
+<p>Rules are a powerful ways to react in real-time to incoming events. For example a rule could update a profile when a certain event comes in, either copying values from the event or performing some kind of computation when the event occurs, including accessing remote systems such as a Salesforce CRM (see the Salesforce connector sample).</p>
+</div>
+<div class="paragraph">
+<p>In this example we will simply setup a basic rule that will react to the <code>view</code> event and set a property in the current profile.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/rules' \
+--header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    "metadata": {
+        "id": "viewEventRule",
+        "name": "View event rule",
+        "description": "Increments a property on a profile to indicate that this rule executed successfully when a view event occurs"
+    },
+    "condition": {
+        "type": "eventTypeCondition",
+        "parameterValues": {
+            "eventTypeId": "view"
+        }
+    },
+    "actions": [
+        {
+            "type": "incrementPropertyAction",
+            "parameterValues": {
+                "propertyName": "pageViewCount"
+            }
+        }
+    ]
+}'</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The above rule will execute when a view event is received (which is automatically sent by the tracker when a page is loaded) and increments a property called <code>pageViewCount</code> on the user&#8217;s profile.</p>
+</div>
+<div class="paragraph">
+<p>You can then reload then page and check with the <code>profile-view PROFILE_UUID</code> SSH command that the profile was updated with the new property and that it is incremented on each page reload.</p>
+</div>
+<div class="paragraph">
+<p>You can also use the <code>rule-list</code> command to display all the rules in the system and the <code>rule-tail</code> to watch in real-time which rules are executed. The <code>rule-view RULE_ID</code> command will let you view the contents of a rule.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_adding_personalization">2.4.7. Adding personalization</h4>
+<div class="paragraph">
+<p>The last step is to use the newly added property to the profile to perform some page personalization. In order to do that we will use the tracker&#8217;s API to register a personalization that will be</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">            variants = {
+                "var1" : {
+                    content : "variant1",
+                },
+                "var2" : {
+                    content : "variant2",
+                }
+            }
+            unomiWebTracker.registerPersonalizationObject({
+                "id": "testPersonalization",
+                "strategy": "matching-first",
+                "strategyOptions": {"fallback": "var2"},
+                "contents": [{
+                    "id": "var1",
+                    "filters": [{
+                        "condition": {
+                            "type": "profilePropertyCondition",
+                            "parameterValues": {
+                                "propertyName" : "properties.pageViewCount",
+                                "comparisonOperator" : "greaterThan",
+                                "propertyValueInteger" : 5
+                            }
+                        }
+                    }]
+                }, {
+                    "id": "var2"
+                }]
+            }, variants, false, function (successfulFilters, selectedFilter) {
+                if (selectedFilter) {
+                    document.getElementById(selectedFilter.content).style.display = '';
+                }
+            });</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_conclusion">2.4.8. Conclusion</h4>
+<div class="paragraph">
+<p>What have we achieved so far ?</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Installed a tracker
+-</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_next_steps">2.4.9. Next steps</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Learn more about the tracker, custom events, API, etc&#8230;&#8203;</p>
+</li>
+<li>
+<p>Learn more about segmentation,</p>
+</li>
+<li>
+<p>Read Unomi&#8217;s user manual to see all that is possible with this technology</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_apache_unomi_recipes_and_requests">3. Apache Unomi Recipes and requests</h2>
+<div class="sectionbody">
+<div class="sect2">
+<h3 id="_recipes">3.1. Recipes</h3>
 <div class="sect3">
-<h4 id="_introduction">3.2.1. Introduction</h4>
+<h4 id="_introduction">3.1.1. Introduction</h4>
 <div class="paragraph">
 <p>In this section of the documentation we provide quick recipes focused on helping you achieve a specific result with
 Apache Unomi.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_enabling_debug_mode">3.2.2. Enabling debug mode</h4>
+<h4 id="_enabling_debug_mode">3.1.2. Enabling debug mode</h4>
 <div class="paragraph">
 <p>Although the examples provided in this documentation are correct (they will work "as-is"),
 you might be tempted to modify them to fit your use case, which might result in errors.</p>
@@ -839,7 +1294,7 @@ therefore to find the source of a schema
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_read_a_profile">3.2.3. How to read a profile</h4>
+<h4 id="_how_to_read_a_profile">3.1.3. How to read a profile</h4>
 <div class="paragraph">
 <p>The simplest way to retrieve profile data for the current profile is to simply send a request to the /cxs/context.json
 endpoint. However you will need to send a body along with that request. Here&#8217;s an example:</p>
@@ -877,7 +1332,7 @@ and security.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_update_a_profile_from_the_public_internet">3.2.4. How to update a profile from the public internet</h4>
+<h4 id="_how_to_update_a_profile_from_the_public_internet">3.1.4. How to update a profile from the public internet</h4>
 <div class="paragraph">
 <p>Before we get into how to update a profile directly from a request coming from the public internet, we&#8217;ll quickly talk
 first about how NOT to do it, because we often see users using the following anti-patterns.</p>
@@ -1159,7 +1614,7 @@ In the example below, an extra property
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_search_for_profile_events">3.2.5. How to search for profile events</h4>
+<h4 id="_how_to_search_for_profile_events">3.1.5. How to search for profile events</h4>
 <div class="paragraph">
 <p>Sometimes you want to retrieve events for a known profile. You will need to provide a query in the body of the request
 that looks something like this (and <a href="https://unomi.apache.org/rest-api-doc/#1768188821">documentation is available in the REST API</a>) :</p>
@@ -1188,7 +1643,7 @@ that looks something like this (and <a h
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_create_a_new_rule">3.2.6. How to create a new rule</h4>
+<h4 id="_how_to_create_a_new_rule">3.1.6. How to create a new rule</h4>
 <div class="paragraph">
 <p>There are basically two ways to create a new rule :</p>
 </div>
@@ -1240,7 +1695,7 @@ contained in the event to the current pr
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_search_for_profiles">3.2.7. How to search for profiles</h4>
+<h4 id="_how_to_search_for_profiles">3.1.7. How to search for profiles</h4>
 <div class="paragraph">
 <p>In order to search for profiles you will have to use the /cxs/profiles/search endpoint that requires a Query JSON
 structure. Here&#8217;s an example of a profile search with a Query object:</p>
@@ -1292,13 +1747,13 @@ on the server and potentially this could
 </div>
 </div>
 <div class="sect3">
-<h4 id="_getting_updating_consents">3.2.8. Getting / updating consents</h4>
+<h4 id="_getting_updating_consents">3.1.8. Getting / updating consents</h4>
 <div class="paragraph">
 <p>You can find information on how to retrieve or create/update consents in the <a href="#_consent_api">Consent API</a> section.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_to_send_a_login_event_to_unomi">3.2.9. How to send a login event to Unomi</h4>
+<h4 id="_how_to_send_a_login_event_to_unomi">3.1.9. How to send a login event to Unomi</h4>
 <div class="paragraph">
 <p>Tracking logins must be done carefully with Unomi. A login event is considered a "privileged" event and therefore for
 not be initiated from the public internet. Ideally user authentication should always be validated by a trusted third-
@@ -1364,9 +1819,9 @@ security issue since it could be a way t
 </div>
 </div>
 <div class="sect2">
-<h3 id="_request_examples">3.3. Request examples</h3>
+<h3 id="_request_examples">3.2. Request examples</h3>
 <div class="sect3">
-<h4 id="_retrieving_your_first_context">3.3.1. Retrieving your first context</h4>
+<h4 id="_retrieving_your_first_context">3.2.1. Retrieving your first context</h4>
 <div class="paragraph">
 <p>You can retrieve a context using curl like this :</p>
 </div>
@@ -1382,7 +1837,7 @@ events using the cxs.collectEvents() fun
 </div>
 </div>
 <div class="sect3">
-<h4 id="_retrieving_a_context_as_a_json_object">3.3.2. Retrieving a context as a JSON object.</h4>
+<h4 id="_retrieving_a_context_as_a_json_object">3.2.2. Retrieving a context as a JSON object.</h4>
 <div class="paragraph">
 <p>If you prefer to retrieve a pure JSON object, you can simply use a request formed like this:</p>
 </div>
@@ -1393,7 +1848,7 @@ events using the cxs.collectEvents() fun
 </div>
 </div>
 <div class="sect3">
-<h4 id="_accessing_profile_properties_in_a_context">3.3.3. Accessing profile properties in a context</h4>
+<h4 id="_accessing_profile_properties_in_a_context">3.2.3. Accessing profile properties in a context</h4>
 <div class="paragraph">
 <p>By default, in order to optimize the amount of data sent over the network, Apache Unomi will not send the content of
 the profile or session properties. If you need this data, you must send a JSON object to configure the resulting output
@@ -1430,7 +1885,7 @@ Java class.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_sending_events_using_the_context_servlet">3.3.4. Sending events using the context servlet</h4>
+<h4 id="_sending_events_using_the_context_servlet">3.2.4. Sending events using the context servlet</h4>
 <div class="paragraph">
 <p>At the same time as you are retrieving the context, you can also directly send events in the ContextRequest object as
 illustrated in the following example:</p>
@@ -1479,7 +1934,7 @@ to send events in a network optimal way
 </div>
 </div>
 <div class="sect3">
-<h4 id="_sending_events_using_the_eventcollector_servlet">3.3.5. Sending events using the eventcollector servlet</h4>
+<h4 id="_sending_events_using_the_eventcollector_servlet">3.2.5. Sending events using the eventcollector servlet</h4>
 <div class="paragraph">
 <p>If you only need to send events without retrieving a context, you should use the eventcollector servlet that is optimized
 respond quickly and minimize network traffic. Here is an example of using this servlet:</p>
@@ -1522,7 +1977,7 @@ to send additional events.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_where_to_go_from_here">3.3.6. Where to go from here</h4>
+<h4 id="_where_to_go_from_here">3.2.6. Where to go from here</h4>
 <div class="ulist">
 <ul>
 <li>
@@ -2564,10 +3019,10 @@ of the ElasticSearch server(s). But if y
 <div class="ulist">
 <ul>
 <li>
-<p>required cluster privileges: <code>manage</code> OR `al`l</p>
+<p>required cluster privileges: <code>manage</code> OR <code>all</code></p>
 </li>
 <li>
-<p>required index privileges on unomi indices: <code>write</code>) AND (<code>manage</code>) AND (<code>read</code> OR <code>all</code></p>
+<p>required index privileges on unomi indices: <code>write, manage, read</code> OR <code>all</code></p>
 </li>
 </ul>
 </div>
@@ -3123,8 +3578,13 @@ By calling <code>POST {{url}}/cxs/jsonSc
 </div>
 </div>
 </div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_graphql_api">6. GraphQL API</h2>
+<div class="sectionbody">
 <div class="sect2">
-<h3 id="_graphql_api">5.4. GraphQL API</h3>
+<h3 id="_introduction_3">6.1. Introduction</h3>
 <div class="paragraph">
 <p>First introduced in Apache Unomi 2.0, a GraphQL API is available as an alternative to REST for interacting with the platform.
 Disabled by default, the GraphQL API is currently considered a beta feature.</p>
@@ -3133,8 +3593,9 @@ Disabled by default, the GraphQL API is
 <p>We look forward for this new GraphQL API to be used, feel free to open discussion on
 <a href="https://the-asf.slack.com/messages/CBP2Z98Q7/">Unomi Slack channel</a> or <a href="https://issues.apache.org/jira/projects/UNOMI/issues">create tickets on Jira</a></p>
 </div>
-<div class="sect3">
-<h4 id="_enabling_the_api">5.4.1. Enabling/ the API</h4>
+</div>
+<div class="sect2">
+<h3 id="_enabling_the_api">6.2. Enabling the API</h3>
 <div class="paragraph">
 <p>The GraphQL API must be enabled using a system property (or environment variable):</p>
 </div>
@@ -3152,16 +3613,16 @@ org.apache.unomi.graphql.feature.activat
 environment variable (if using Docker for example).</p>
 </div>
 </div>
-<div class="sect3">
-<h4 id="_endpoints">5.4.2. Endpoints</h4>
+<div class="sect2">
+<h3 id="_endpoints">6.3. Endpoints</h3>
 <div class="paragraph">
 <p>Two endpoints were introduced for Apache Unomi 2 GraphQL API:
 * <code>/graphql</code> is the primary endpoint for interacting programatically with the API and aims at receiving POST requests.
 * <code>/graphql-ui</code> provides access to the GraphQL Playground UI and aims at being accessed by a Web Browser.</p>
 </div>
 </div>
-<div class="sect3">
-<h4 id="_graphql_schema">5.4.3. GraphQL Schema</h4>
+<div class="sect2">
+<h3 id="_graphql_schema">6.4. GraphQL Schema</h3>
 <div class="paragraph">
 <p>Thanks to GraphQL introspection, there is no dedicated documentation per-se as the Schema itself serves as documentation.</p>
 </div>
@@ -3172,19 +3633,18 @@ you might need to adjust the URL to poin
 </div>
 </div>
 </div>
-</div>
 <div class="sect1">
-<h2 id="_migrations">6. Migrations</h2>
+<h2 id="_migrations">7. Migrations</h2>
 <div class="sectionbody">
 <div class="paragraph">
 <p>This section contains information and steps to migrate between major Unomi versions.</p>
 </div>
 <div class="sect2">
-<h3 id="_from_version_1_6_to_2_0">6.1. From version 1.6 to 2.0</h3>
+<h3 id="_from_version_1_6_to_2_0">7.1. From version 1.6 to 2.0</h3>
 
 </div>
 <div class="sect2">
-<h3 id="_migration_overview">6.2. Migration Overview</h3>
+<h3 id="_migration_overview">7.2. Migration Overview</h3>
 <div class="paragraph">
 <p>Apache Unomi 2.0 is a major release, and as such it does introduce breaking changes. This portion of the document detail the various steps we recommend following to successfully migrate your environment from Apache Unomi 1.6 to Apache Unomi 2.0.</p>
 </div>
@@ -3195,7 +3655,7 @@ you might need to adjust the URL to poin
 </div>
 </div>
 <div class="sect2">
-<h3 id="_updating_applications_consuming_unomi">6.3. Updating applications consuming Unomi</h3>
+<h3 id="_updating_applications_consuming_unomi">7.3. Updating applications consuming Unomi</h3>
 <div class="paragraph">
 <p>Since Apache Unomi is an engine, you&#8217;ve probably built multiple applications consuming its APIs, you might also have built extensions directly running in Unomi.</p>
 </div>
@@ -3204,13 +3664,13 @@ you might need to adjust the URL to poin
 Doing so will display any errors when processing events (such as JSON Schema validations), and will provide useful indications towards solving issues.</p>
 </div>
 <div class="sect3">
-<h4 id="_data_model_changes">6.3.1. Data Model changes</h4>
+<h4 id="_data_model_changes">7.3.1. Data Model changes</h4>
 <div class="paragraph">
 <p>There has been changes to Unomi Data model, please make sure to review those in the &lt;&lt; what_s_new&gt;&gt; section of the user manual.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_create_json_schemas">6.3.2. Create JSON schemas</h4>
+<h4 id="_create_json_schemas">7.3.2. Create JSON schemas</h4>
 <div class="paragraph">
 <p>Once you updated your applications to align with Unomi 2 data model, the next step will be to create the necessary JSON Schemas.</p>
 </div>
@@ -3237,9 +3697,9 @@ you will need to either change to use a
 </div>
 </div>
 <div class="sect2">
-<h3 id="_migrating_your_existing_data">6.4. Migrating your existing data</h3>
+<h3 id="_migrating_your_existing_data">7.4. Migrating your existing data</h3>
 <div class="sect3">
-<h4 id="_elasticsearch_version_and_capacity">6.4.1. Elasticsearch version and capacity</h4>
+<h4 id="_elasticsearch_version_and_capacity">7.4.1. Elasticsearch version and capacity</h4>
 <div class="paragraph">
 <p>While still using Unomi 1.6, the first step will be to upgrade your Elasticsearch to 7.17.5.
 Documentation is available on <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup-upgrade.html">Elasticsearch&#8217;s website</a>.</p>
@@ -3250,7 +3710,7 @@ At a minimum, the required capacity must
 </div>
 </div>
 <div class="sect3">
-<h4 id="_migrate_custom_data">6.4.2. Migrate custom data</h4>
+<h4 id="_migrate_custom_data">7.4.2. Migrate custom data</h4>
 <div class="paragraph">
 <p>Apache Unomi 2.0 knows how to migrate its own data from the new model to the old one, but it does not know how to migrate custom events you might be using in your environment.</p>
 </div>
@@ -3263,11 +3723,22 @@ these scripts are sorted alphabetically
 <p>In most cases, migration steps consist of an Elasticsearch painless script that will handle the data changes.</p>
 </div>
 <div class="paragraph">
+<p>Depending of the volume of data, migration can be lengthy. By paying attention to when re-indexation is happening (triggered in the groovy scripts by <code>MigrationUtils.reIndex()</code>),
+you can find the most appropriate time for your scritps to be executed and avoid re-indexing the same indices multiple times.</p>
+</div>
+<div class="paragraph">
+<p>For example if you wanted to update profiles with custom data (currently migrated by <code>migrate-2.0.0-10-profileReindex.groovy</code>), you could create a script in position "09" that would only contain painless scripts without a reindexing step.
+The script in position "10" will introduce its own painless script, then trigger the re-indexation. This way you don&#8217;t have to re-index the same indices twice.</p>
+</div>
+<div class="paragraph">
+<p>You can find existing painless scripts in <a href="https://github.com/apache/unomi/tree/master/tools/shell-commands/src/main/resources/requestBody/2.0.0">tools/shell-commands/src/main/resources/requestBody/2.0.0</a></p>
+</div>
+<div class="paragraph">
 <p>At runtime, and when starting the migration, Unomi 2.0 will take its own scripts, any additional scripts located in <code>data/migration/scripts</code>, will sort the resulting list alphabetically and execute each migration script sequentially.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_perform_the_migration">6.4.3. Perform the migration</h4>
+<h4 id="_perform_the_migration">7.4.3. Perform the migration</h4>
 <div class="sect4">
 <h5 id="_checklist">Checklist</h5>
 <div class="paragraph">
@@ -3424,9 +3895,17 @@ these scripts are sorted alphabetically
 <p>The migration can also be performed using Docker images, the migration itself can be started by passing a specific value to the <code>KARAF_OPTS</code> environment variable.</p>
 </div>
 <div class="paragraph">
-<p>In the context of this migration guide, we will asssume that:
- - Custom migration scripts are located in <code>/home/unomi/migration/scripts/</code>
- - Painless scripts, or more generally any migration assets are located in <code>/home/unomi/migration/assets/</code>, these scripts will be mounted under <code>/tmp/assets/</code> inside the Docker container.</p>
+<p>In the context of this migration guide, we will asssume that:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Custom migration scripts are located in <code>/home/unomi/migration/scripts/</code></p>
+</li>
+<li>
+<p>Painless scripts, or more generally any migration assets are located in <code>/home/unomi/migration/assets/</code>, these scripts will be mounted under <code>/tmp/assets/</code> inside the Docker container.</p>
+</li>
+</ul>
 </div>
 <div class="listingblock">
 <div class="content">
@@ -3466,15 +3945,15 @@ these scripts are sorted alphabetically
 </div>
 </div>
 <div class="sect2">
-<h3 id="_from_version_1_5_to_1_6">6.5. From version 1.5 to 1.6</h3>
+<h3 id="_from_version_1_5_to_1_6">7.5. From version 1.5 to 1.6</h3>
 <div class="paragraph">
 <p>Migration from Unomi 1.5x to 1.6x does not require any particular steps, simply restart your cluster in the new version.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_from_version_1_4_to_1_5">6.6. From version 1.4 to 1.5</h3>
+<h3 id="_from_version_1_4_to_1_5">7.6. From version 1.4 to 1.5</h3>
 <div class="sect3">
-<h4 id="_data_model_and_elasticsearch_7">6.6.1. Data model and ElasticSearch 7</h4>
+<h4 id="_data_model_and_elasticsearch_7">7.6.1. Data model and ElasticSearch 7</h4>
 <div class="paragraph">
 <p>Since Apache Unomi version 1.5.0 we decided to upgrade the supported ElasticSearch version to the 7.4.2.</p>
 </div>
@@ -3489,7 +3968,7 @@ these scripts are sorted alphabetically
 </div>
 </div>
 <div class="sect3">
-<h4 id="_api_changes">6.6.2. API changes</h4>
+<h4 id="_api_changes">7.6.2. API changes</h4>
 <div class="paragraph">
 <p>To be able to handle the multiple indices the Persistence API implementation
 (<a href="https://github.com/apache/unomi/blob/9f1bab437fd93826dc54d318ed00d3b2e3161437/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java">ElasticSearchPersistenceServiceImpl</a>)
@@ -3529,7 +4008,7 @@ Previously named: <code>geonames</code>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_migration_steps">6.6.3. Migration steps</h4>
+<h4 id="_migration_steps">7.6.3. Migration steps</h4>
 <div class="paragraph">
 <p>In order to migrate the data from ElasticSearch 5 to 7, Unomi provides a migration tool that is directly integrated.</p>
 </div>
@@ -3660,7 +4139,7 @@ the profiles:</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">6.7. Important changes in public servlets since version 1.5.5 and 2.0.0</h3>
+<h3 id="_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">7.7. Important changes in public servlets since version 1.5.5 and 2.0.0</h3>
 <div class="paragraph">
 <p>What used to be dedicated servlets are now part of the REST endpoints.
 Prior to version 1.5.5 the following servlets were used:</p>
@@ -3702,7 +4181,7 @@ to update your client applications.</p>
 </div>
 </div>
 <div class="sect1">
-<h2 id="_queries_and_aggregations">7. Queries and aggregations</h2>
+<h2 id="_queries_and_aggregations">8. Queries and aggregations</h2>
 <div class="sectionbody">
 <div class="paragraph">
 <p>Apache Unomi contains a <code>query</code> endpoint that is quite powerful. It provides ways to perform queries that can quickly
@@ -3712,7 +4191,7 @@ get result counts, apply metrics such as
 <p>In this section we will show examples of requests that may be built using this API.</p>
 </div>
 <div class="sect2">
-<h3 id="_query_counts">7.1. Query counts</h3>
+<h3 id="_query_counts">8.1. Query counts</h3>
 <div class="paragraph">
 <p>Query counts are highly optimized queries that will count the number of objects that match a certain condition without
 retrieving the results. This can be used for example to quickly figure out how many objects will match a given condition
@@ -3767,7 +4246,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_metrics">7.2. Metrics</h3>
+<h3 id="_metrics">8.2. Metrics</h3>
 <div class="paragraph">
 <p>Metric queries make it possible to apply functions to the resulting property. The supported metrics are:</p>
 </div>
@@ -3829,7 +4308,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_aggregations">7.3. Aggregations</h3>
+<h3 id="_aggregations">8.3. Aggregations</h3>
 <div class="paragraph">
 <p>Aggregations are a very powerful way to build queries in Apache Unomi that will collect and aggregate data by filtering
 on certain conditions.</p>
@@ -3841,7 +4320,7 @@ on certain conditions.</p>
 - a condition (used to filter the data set that will be aggregated)</p>
 </div>
 <div class="sect3">
-<h4 id="_aggregation_types">7.3.1. Aggregation types</h4>
+<h4 id="_aggregation_types">8.3.1. Aggregation types</h4>
 <div class="paragraph">
 <p>Aggregations may be of different types. They are listed here below.</p>
 </div>
@@ -4079,14 +4558,14 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect1">
-<h2 id="_profile_import_export">8. Profile import &amp; export</h2>
+<h2 id="_profile_import_export">9. Profile import &amp; export</h2>
 <div class="sectionbody">
 <div class="paragraph">
 <p>The profile import and export feature in Apache Unomi is based on configurations and consumes or produces CSV files that
 contain profiles to be imported and exported.</p>
 </div>
 <div class="sect2">
-<h3 id="_importing_profiles">8.1. Importing profiles</h3>
+<h3 id="_importing_profiles">9.1. Importing profiles</h3>
 <div class="paragraph">
 <p>Only <code>ftp</code>, <code>sftp</code>, <code>ftps</code> and <code>file</code> are supported in the source path. For example:</p>
 </div>
@@ -4146,7 +4625,7 @@ ftps://USER@HOST?password=PASSWORD&amp;f
 </ul>
 </div>
 <div class="sect3">
-<h4 id="_import_api">8.1.1. Import API</h4>
+<h4 id="_import_api">9.1.1. Import API</h4>
 <div class="paragraph">
 <p>Apache Unomi provides REST endpoints to manage import configurations:</p>
 </div>
@@ -4221,7 +4700,7 @@ ftps://USER@HOST?password=PASSWORD&amp;f
 </div>
 </div>
 <div class="sect2">
-<h3 id="_exporting_profiles">8.2. Exporting profiles</h3>
+<h3 id="_exporting_profiles">9.2. Exporting profiles</h3>
 <div class="paragraph">
 <p>Only <code>ftp</code>, <code>sftp</code>, <code>ftps</code> and `file are supported in the source path. For example:</p>
 </div>
@@ -4242,7 +4721,7 @@ per file.</p>
 <p>See <a href="http://camel.apache.org/ftp.html and http://camel.apache.org/file2.html to" class="bare">http://camel.apache.org/ftp.html and http://camel.apache.org/file2.html to</a> build more complex destination path.</p>
 </div>
 <div class="sect3">
-<h4 id="_export_api">8.2.1. Export API</h4>
+<h4 id="_export_api">9.2.1. Export API</h4>
 <div class="paragraph">
 <p>Apache Unomi provides REST endpoints to manage export configurations:</p>
 </div>
@@ -4310,7 +4789,7 @@ per file.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_configuration_in_details">8.3. Configuration in details</h3>
+<h3 id="_configuration_in_details">9.3. Configuration in details</h3>
 <div class="paragraph">
 <p>First configuration you need to change would be the configuration type of your import / export feature (code name
 router) in the <code>etc/unomi.custom.system.properties</code> file (creating it if necessary):</p>
@@ -4404,17 +4883,17 @@ org.apache.unomi.router.config.allowedEn
 </div>
 </div>
 <div class="sect1">
-<h2 id="_consent_management">9. Consent management</h2>
+<h2 id="_consent_management">10. Consent management</h2>
 <div class="sectionbody">
 <div class="sect2">
-<h3 id="_consent_api">9.1. Consent API</h3>
+<h3 id="_consent_api">10.1. Consent API</h3>
 <div class="paragraph">
 <p>Starting with Apache Unomi 1.3, a new API for consent management is now available. This API
 is designed to be able to store/retrieve/update visitor consents in order to comply with new
 privacy regulations such as the <a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">GDPR</a>.</p>
 </div>
 <div class="sect3">
-<h4 id="_profiles_with_consents">9.1.1. Profiles with consents</h4>
+<h4 id="_profiles_with_consents">10.1.1. Profiles with consents</h4>
 <div class="paragraph">
 <p>Visitor profiles now contain a new Consent object that contains the following information:</p>
 </div>
@@ -4489,7 +4968,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_consent_type_definitions">9.1.2. Consent type definitions</h4>
+<h4 id="_consent_type_definitions">10.1.2. Consent type definitions</h4>
 <div class="paragraph">
 <p>Apache Unomi does not manage consent definitions, it leaves that to an external system (for example a CMS) so that it
 can handle user-facing UIs to create, update, internationalize and present consent definitions to end users.</p>
@@ -4500,7 +4979,7 @@ consent type.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_creating_update_a_visitor_consent">9.1.3. Creating / update a visitor consent</h4>
+<h4 id="_creating_update_a_visitor_consent">10.1.3. Creating / update a visitor consent</h4>
 <div class="paragraph">
 <p>A new built-in event type called "modifyConsent" can be sent to Apache Unomi to update a consent for the current
 profile.</p>
@@ -4583,7 +5062,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_how_it_works_internally">9.1.4. How it works (internally)</h4>
+<h4 id="_how_it_works_internally">10.1.4. How it works (internally)</h4>
 <div class="paragraph">
 <p>Upon receiving this event, Apache Unomi will trigger the modifyAnyConsent rule that has the following definition:</p>
 </div>
@@ -4626,14 +5105,14 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect1">
-<h2 id="_privacy_management">10. Privacy management</h2>
+<h2 id="_privacy_management">11. Privacy management</h2>
 <div class="sectionbody">
 <div class="paragraph">
 <p>Apache Unomi provides an endpoint to manage visitor privacy. You will find in this section information about what it
 includes as well as how to use it.</p>
 </div>
 <div class="sect2">
-<h3 id="_setting_up_access_to_the_privacy_endpoint">10.1. Setting up access to the privacy endpoint</h3>
+<h3 id="_setting_up_access_to_the_privacy_endpoint">11.1. Setting up access to the privacy endpoint</h3>
 <div class="paragraph">
 <p>The privacy endpoint is a bit special, because despite being protected by basic authentication as the rest of the REST
 API is is actually designed to be available to end-users.</p>
@@ -4659,7 +5138,7 @@ geographic location)</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_anonymizing_a_profile">10.2. Anonymizing a profile</h3>
+<h3 id="_anonymizing_a_profile">11.2. Anonymizing a profile</h3>
 <div class="paragraph">
 <p>It is possible to anonymize a profile, meaning it will remove all "identifying" property values from the profile.
 Basically all properties with the tag <code>personalIdentifierProperties</code> will be purged from the profile.</p>
@@ -4678,7 +5157,7 @@ and <code>ASCOPE</code> must be replaced
 </div>
 </div>
 <div class="sect2">
-<h3 id="_downloading_profile_data">10.3. Downloading profile data</h3>
+<h3 id="_downloading_profile_data">11.3. Downloading profile data</h3>
 <div class="paragraph">
 <p>It is possible to download the profile data of a user. This will only download the profile for a user using the
 specified ID as a cookie value.</p>
@@ -4699,7 +5178,7 @@ IDs.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_deleting_a_profile">10.4. Deleting a profile</h3>
+<h3 id="_deleting_a_profile">11.4. Deleting a profile</h3>
 <div class="paragraph">
 <p>It is possible to delete a profile, but this works a little differently than you might expect. In all cases the data
 contained in the profile will be completely erased. If the <code>withData</code> optional flag is set to true, all past event and
@@ -4716,7 +5195,7 @@ and the <code>withData</code> specifies
 </div>
 </div>
 <div class="sect2">
-<h3 id="_related">10.5. Related</h3>
+<h3 id="_related">11.5. Related</h3>
 <div class="paragraph">
 <p>You might also be interested in the <a href="#_consent_api">Consent API</a> section that describe how to manage profile consents.</p>
 </div>
@@ -4724,10 +5203,10 @@ and the <code>withData</code> specifies
 </div>
 </div>
 <div class="sect1">
-<h2 id="_cluster_setup">11. Cluster setup</h2>
+<h2 id="_cluster_setup">12. Cluster setup</h2>
 <div class="sectionbody">
 <div class="sect2">
-<h3 id="_cluster_setup_2">11.1. Cluster setup</h3>
+<h3 id="_cluster_setup_2">12.1. Cluster setup</h3>
 <div class="paragraph">
 <p>Apache Karaf relies on Apache Karaf Cellar, which in turn uses Hazelcast to discover and configure its cluster.</p>
 </div>
@@ -4768,10 +5247,10 @@ placeholders in the hazelcast.xml file i
 </div>
 </div>
 <div class="sect1">
-<h2 id="_reference">12. Reference</h2>
+<h2 id="_reference">13. Reference</h2>
 <div class="sectionbody">
 <div class="sect2">
-<h3 id="_useful_apache_unomi_urls">12.1. Useful Apache Unomi URLs</h3>
+<h3 id="_useful_apache_unomi_urls">13.1. Useful Apache Unomi URLs</h3>
 <div class="paragraph">
 <p>In this section we will list some useful URLs that can be used to quickly access parts of Apache Unomi that can help
 you understand or diagnose what is going on in the system.</p>
@@ -4869,12 +5348,12 @@ where PROFILE_ID is a profile identifier
 </table>
 </div>
 <div class="sect2">
-<h3 id="_how_profile_tracking_works">12.2. How profile tracking works</h3>
+<h3 id="_how_profile_tracking_works">13.2. How profile tracking works</h3>
 <div class="paragraph">
 <p>In this section you will learn how Apache Unomi keeps track of visitors.</p>
 </div>
 <div class="sect3">
-<h4 id="_steps">12.2.1. Steps</h4>
+<h4 id="_steps">13.2.1. Steps</h4>
 <div class="olist arabic">
 <ol class="arabic">
 <li>
@@ -4914,7 +5393,7 @@ forcing.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_context_request_flow">12.3. Context Request Flow</h3>
+<h3 id="_context_request_flow">13.3. Context Request Flow</h3>
 <div class="paragraph">
 <p>Here is an overview of how Unomi processes incoming requests to the <code>ContextServlet</code>.</p>
 </div>
@@ -4925,7 +5404,7 @@ forcing.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_data_model_overview">12.4. Data Model Overview</h3>
+<h3 id="_data_model_overview">13.4. Data Model Overview</h3>
 <div class="paragraph">
 <p>Apache Unomi gathers information about users actions, information that is processed and stored by Unomi services.
 The collected information can then be used to personalize content, derive insights on user behavior, categorize the
@@ -4937,7 +5416,7 @@ There are other classes that are less ce
 </div>
 <div class="imageblock">
 <div class="content">
-<img src="images/data-model-overview.png" alt="data model overview">
+<img src="images/data-model.png" alt="data model">
 </div>
 </div>
 <div class="paragraph">
@@ -4945,11 +5424,14 @@ There are other classes that are less ce
 </div>
 </div>
 <div class="sect2">
-<h3 id="_scope">12.5. Scope</h3>
+<h3 id="_scope">13.5. Scope</h3>
 <div class="paragraph">
-<p>Scopes are not actually an object in the system, but simply unique strings that are used to "classify" objects.
+<p>Scopes are objects which simply contains unique strings that are used to "classify" objects.
 For example, when using scopes with a web content management system, a scope could be associated with a site identifier or even a host name.</p>
 </div>
+<div class="paragraph">
+<p>In events, scopes are used to validate event. Events with scope which are unknown by the system will be considered as invalid</p>
+</div>
 <div class="quoteblock">
 <blockquote>
 <div class="paragraph">
@@ -4958,7 +5440,7 @@ For example, when using scopes with a we
 </blockquote>
 </div>
 <div class="sect3">
-<h4 id="_example">12.5.1. Example</h4>
+<h4 id="_example">13.5.1. Example</h4>
 <div class="paragraph">
 <p>In the following example, the scope uses the unique identifier of a web site called “digitall”.</p>
 </div>
@@ -4974,7 +5456,7 @@ For example, when using scopes with a we
 </div>
 </div>
 <div class="sect2">
-<h3 id="_item">12.6. Item</h3>
+<h3 id="_item">13.6. Item</h3>
 <div class="paragraph">
 <p>Unomi structures the information it collects using the concept of <code>Item</code> which provides the base information (an identifier and a type) the context server needs to process and store the data.
 Items are persisted according to their type (structure) and identifier (identity).
@@ -4999,7 +5481,7 @@ Scopes allow clients accessing the conte
 It contains the following fields, that are inherited by other objects that inherit from it.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition">12.6.1. Structure definition</h4>
+<h4 id="_structure_definition">13.6.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: n/a</p>
 </div>
@@ -5037,13 +5519,13 @@ It contains the following fields, that a
 </div>
 </div>
 <div class="sect2">
-<h3 id="_metadata">12.7. Metadata</h3>
+<h3 id="_metadata">13.7. Metadata</h3>
 <div class="paragraph">
 <p>The Metadata object is an object that contains additional information about an object.
 It is usually associated with an Item object (see MetadataItem below).</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_2">12.7.1. Structure definition</h4>
+<h4 id="_structure_definition_2">13.7.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: n/a</p>
 </div>
@@ -5115,7 +5597,7 @@ It is usually associated with an Item ob
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_2">12.7.2. Example</h4>
+<h4 id="_example_2">13.7.2. Example</h4>
 <div class="paragraph">
 <p>This example of a Metadata object structure was taken from a List associated object.
 See the MetadataItem to understand how the two fit together.</p>
@@ -5139,9 +5621,9 @@ See the MetadataItem to understand how t
 </div>
 </div>
 <div class="sect2">

[... 1155 lines stripped ...]