diff --git a/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs b/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs
index a59f80749dfa04a5343156f87799fee5b15a3ddb..fe98f3ae4949fa8510ebfba5e861fc17920eca09 100644
--- a/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs
+++ b/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs
@@ -763,6 +763,12 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis
             return SubscribeToPoseAsync(token, sessionID, body, System.Threading.CancellationToken.None);
         }
 
+        // SylR
+        public virtual System.Threading.Tasks.Task<SubscriptionMultiple> SubscribeToPoseAsync(string token, string sessionID, SubscriptionMultipleRequest body)
+        {
+            return SubscribeToPoseAsync(token, sessionID, body, System.Threading.CancellationToken.None);
+        }
+
         /// <summary>
         /// Subscribe to collect the pose of an AR device, an Anchor or a Trackable
         /// </summary>
@@ -775,6 +781,12 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis
         {
             return System.Threading.Tasks.Task.Run(async () => await SubscribeToPoseAsync(token, sessionID, body, System.Threading.CancellationToken.None)).GetAwaiter().GetResult();
         }
+    
+        // SylR
+        public virtual SubscriptionMultiple SubscribeToPose(string token, string sessionID, SubscriptionMultipleRequest body)
+        {
+            return System.Threading.Tasks.Task.Run(async () => await SubscribeToPoseAsync(token, sessionID, body, System.Threading.CancellationToken.None)).GetAwaiter().GetResult();
+        }
 
         /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
         /// <summary>
@@ -898,6 +910,120 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis
             }
         }
 
+        // SylR
+        public virtual async System.Threading.Tasks.Task<SubscriptionMultiple> SubscribeToPoseAsync(string token, string sessionID, SubscriptionMultipleRequest body, System.Threading.CancellationToken cancellationToken)
+        {
+            if (body == null)
+                throw new System.ArgumentNullException("body");
+
+            var client_ = _httpClient;
+            var disposeClient_ = false;
+            try
+            {
+                using (var request_ = new System.Net.Http.HttpRequestMessage())
+                {
+
+                    if (token != null)
+                        request_.Headers.TryAddWithoutValidation("token", ConvertToString(token, System.Globalization.CultureInfo.InvariantCulture));
+
+                    if (sessionID != null)
+                        request_.Headers.TryAddWithoutValidation("sessionID", ConvertToString(sessionID, System.Globalization.CultureInfo.InvariantCulture));
+                    var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value);
+                    var content_ = new System.Net.Http.StringContent(json_);
+                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+                    request_.Content = content_;
+                    request_.Method = new System.Net.Http.HttpMethod("POST");
+                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+                    var urlBuilder_ = new System.Text.StringBuilder();
+
+                    // Operation Path: "pose/subscriptions"
+                    urlBuilder_.Append("pose/subscriptions");
+
+                    PrepareRequest(client_, request_, urlBuilder_);
+
+                    var url_ = urlBuilder_.ToString();
+                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+                    PrepareRequest(client_, request_, url_);
+
+                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+                    var disposeResponse_ = true;
+                    try
+                    {
+                        var headers_ = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.IEnumerable<string>>();
+                        foreach (var item_ in response_.Headers)
+                            headers_[item_.Key] = item_.Value;
+                        if (response_.Content != null && response_.Content.Headers != null)
+                        {
+                            foreach (var item_ in response_.Content.Headers)
+                                headers_[item_.Key] = item_.Value;
+                        }
+
+                        ProcessResponse(client_, response_);
+
+                        var status_ = (int)response_.StatusCode;
+                        if (status_ == 200)
+                        {
+                            var objectResponse_ = await ReadObjectResponseAsync<SubscriptionMultiple>(response_, headers_, cancellationToken).ConfigureAwait(false);
+                            if (objectResponse_.Object == null)
+                            {
+                                throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+                            }
+                            return objectResponse_.Object;
+                        }
+                        else
+                        if (status_ == 400)
+                        {
+                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+                            var result_ = (string)System.Convert.ChangeType(responseData_, typeof(string));
+                            throw new ApiException<string>("Bad request.", status_, responseData_, headers_, result_, null);
+                        }
+                        else
+                        if (status_ == 403)
+                        {
+                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+                            var result_ = (string)System.Convert.ChangeType(responseData_, typeof(string));
+                            throw new ApiException<string>("Not allowed.", status_, responseData_, headers_, result_, null);
+                        }
+                        else
+                        if (status_ == 404)
+                        {
+                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+                            var result_ = (string)System.Convert.ChangeType(responseData_, typeof(string));
+                            throw new ApiException<string>("Not found.", status_, responseData_, headers_, result_, null);
+                        }
+                        else
+                        if (status_ == 405)
+                        {
+                            var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
+                            var result_ = (string)System.Convert.ChangeType(responseData_, typeof(string));
+                            throw new ApiException<string>("Not supported.", status_, responseData_, headers_, result_, null);
+                        }
+                        else
+                        {
+                            var objectResponse_ = await ReadObjectResponseAsync<Error>(response_, headers_, cancellationToken).ConfigureAwait(false);
+                            if (objectResponse_.Object == null)
+                            {
+                                throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+                            }
+                            throw new ApiException<Error>("Unexpected error.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
+                        }
+                    }
+                    finally
+                    {
+                        if (disposeResponse_)
+                            response_.Dispose();
+                    }
+                }
+            }
+            finally
+            {
+                if (disposeClient_)
+                    client_.Dispose();
+            }
+        }
+
         /// <summary>
         /// Get information about a subscription
         /// </summary>
@@ -1927,8 +2053,8 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis
         /// <summary>
         /// List of modes representing the context of the Relocalization information (AR device to WorldAnchor/Trackable or WorldAnchor/Trackable to AR device)
         /// </summary>
-        [Newtonsoft.Json.JsonProperty("mode", Required = Newtonsoft.Json.Required.Always, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
-        public System.Collections.Generic.ICollection<Mode_WorldAnalysis> Mode { get; set; } = new System.Collections.ObjectModel.Collection<Mode_WorldAnalysis>();
+        [Newtonsoft.Json.JsonProperty("modes", Required = Newtonsoft.Json.Required.Always, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+        public System.Collections.Generic.ICollection<Mode_WorldAnalysis> Modes { get; set; } = new System.Collections.ObjectModel.Collection<Mode_WorldAnalysis>();
 
         /// <summary>
         /// Subscription validity delay in millisecond
diff --git a/Runtime/Scripts/WorldAnalysisInterface.cs b/Runtime/Scripts/WorldAnalysisInterface.cs
index 1efeacdad1832e8406ed9ec7c9d57c21e32dfc3f..416f91798a8f0c67f50950f8cdc6a44911ef9be5 100644
--- a/Runtime/Scripts/WorldAnalysisInterface.cs
+++ b/Runtime/Scripts/WorldAnalysisInterface.cs
@@ -151,7 +151,7 @@ public interface WorldAnalysisInterface
     /// </summary>
     /// <param name="subscriptionUUID">id of the subscription</param>
     /// /// <returns>The unsubscription has been performed or not</returns>
-    public InformationSubscriptionResult UnSubscribeToPose(Guid subscriptionUUID);
+    public InformationSubscriptionResult UnsubscribeFromPose(Guid subscriptionUUID);
 
     #endregion
 
diff --git a/Runtime/Scripts/WorldAnalysisREST.cs b/Runtime/Scripts/WorldAnalysisREST.cs
index 439871247d7de73707a3a813881c61749c5c6526..c4e0d6c92c764bbe54276211683945792bc8f35e 100644
--- a/Runtime/Scripts/WorldAnalysisREST.cs
+++ b/Runtime/Scripts/WorldAnalysisREST.cs
@@ -7,11 +7,14 @@ using ETSI.ARF.WorldAnalysis;
 using static WorldAnalysisInterface;
 using ETSI.ARF.WorldAnalysis.REST;
 
-using WebSocketSharp;
+using UnityEngine.Events;
 
 //Implementation of the WorldAnalysis interface
-public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
+public partial class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
 {
+    [Serializable]
+    public class StringEvent : UnityEvent<string> { }
+
     //
     // Inspector variables
     //
@@ -25,13 +28,15 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
     [Space(8)]
     public bool isDebug = false;
 
+    //[Serializable]
+    //public class StringEvent : UnityEvent<string> { }
+    //public StringEvent webSocketMessage;
+
     //
     // Private members
     //
     private WorldAnalysisClient apiClient;          // For sync calls
     private WorldAnalysisClient apiClientAsync;     // For async calls
-    private WebSocketSharp.WebSocket webSocket;     // For WebSockets
-    private bool websocketConnected = false;
 
     //
     // Management of subscriptions
@@ -91,6 +96,11 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
         }
     }
 
+    private void OnDestroy()
+    {
+        WebSocketClient_Close();
+    }
+
     #endregion
 
     #region Test methods
@@ -117,95 +127,6 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
     }
     #endregion
 
-    #region Communication system
-    private void CreateWebHookServer()
-    {
-        throw new Exception("[REST] CreateWebHookServer(): Not implemented!");
-    }
-
-    private void DestroyWebHookServer()
-    {
-        return;
-    }
-
-    public WebSocket OpenWebSocketClient(string url)
-    {
-        webSocket = new WebSocketSharp.WebSocket(url);
-
-        //
-        // Define standard callbacks
-        //
-        webSocket.OnOpen += (sender, e) =>
-        {
-            Debug.Log("[WS] Connected");
-            websocketConnected = true;
-            webSocket.Send("RegisterClient:UnitySceneManagement");
-        };
-        webSocket.OnClose += (sender, e) =>
-        {
-            Debug.Log("[WS] Disconnected");
-            websocketConnected = false;
-        };
-        webSocket.OnError += (sender, e) => Debug.Log("[WS] Error!");
-        webSocket.OnMessage += (sender, e) => HandleWebSocketClient(e.Data);
-        webSocket.Connect();
-
-        return webSocket;
-    }
-
-    private void OnDestroy()
-    {
-        // State: red
-        CloseWebSocketClient();
-    }
-
-    private void CloseWebSocketClient()
-    {
-        if (websocketConnected)
-        {
-            webSocket.Send("UnregisterClient");
-            webSocket.Close();
-        }
-    }
-
-    bool ok = false;
-    public void HandleWebSocketClient(string data)
-    {
-        Debug.Log("[WS] Receiving: " + data);
-
-        if (data.Contains("You are now registered"))
-        {
-            ok = true;
-            if (isDebug) webSocket.Send("PoseStart:10"); // test
-        }
-        else if (data == "PoseStop")
-        {
-            //SetColor(Color.yellow);
-        }
-        else if (ok)
-        {
-            if (data.Contains("estimationState"))
-            {
-                // Handle pose
-                ETSI.ARF.OpenAPI.WorldAnalysis.Pose p = JsonUtility.FromJson<ETSI.ARF.OpenAPI.WorldAnalysis.Pose>(data);
-                Debug.Log("[WS][Pose] State: " + p.EstimationState.ToString());
-
-                PoseEstimationResult res = p.EstimationState == PoseEstimationState.OK ? PoseEstimationResult.OK : PoseEstimationResult.FAILURE;
-
-                // Search the corresponding callbacks
-                foreach (var item in m_subscriptionsPoses.Values)
-                {
-                    if (p.Uuid == item.uuidTarget)
-                    {
-                        item.callback(res, p);
-                    }
-                }
-            }
-        }
-    }
-
-    #endregion
-
     #region Lifecycle
     /// <summary>
     /// Check the validity of all subscriptions and delete one if needed
@@ -270,8 +191,8 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
         {
             for (int i = 0; i < uuids.Length; i++)
             {
-                PoseEstimationResult poseResul = new PoseEstimationResult();
-                resul[i] = poseResul;
+                PoseEstimationResult poseResult = new PoseEstimationResult();
+                resul[i] = poseResult;
                 poses[i] = posesList[i];
             }
             return resul;
@@ -288,20 +209,29 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
         // Todo: Maintain the callback to the subscription id
         // Get capabilities?
         // Get reloc info?
+        subscriptionUUID = Guid.Empty; // default
 
         SubscriptionSingleRequest body = new SubscriptionSingleRequest();
         body.Target = uuid;
-        body.Mode = mode;
+        body.Mode = mode;        
         body.Validity = validity;
-        body.WebhookUrl = callback == null ? "" : "https:\\..."; // empty -> app will use websockets (client)!
+        body.WebhookUrl = callback != null ? "" : "https:\\..."; // empty -> app will use websockets (client)!
 
         // Get subscription info from the REST server
         SubscriptionSingle response = apiClient.SubscribeToPose(token, sessionID, body);
         subscriptionUUID = response.Uuid;
+        validity = response.Validity;
+
+        //SubscriptionMultipleRequest body_m = new SubscriptionMultipleRequest();
+        //body_m.Targets = new List<object>();
+        //body_m.Mode = new List<Mode_WorldAnalysis>();
+        //body_m.Validity = validity;
+        //body_m.WebhookUrl = callback == null ? "" : "https:\\..."; // empty -> app will use websockets (client)!
+        //SubscriptionMultiple response = apiClient.SubscribeToPose(token, sessionID, body_m);
 
         // We add the subscription
         SubscriptionInfo sub = new SubscriptionInfo();
-        sub.uuid = response.Uuid;
+        sub.uuid = subscriptionUUID;
         sub.timeValidity = Time.time + (validity / 1000.0f);
         sub.pose = new ETSI.ARF.OpenAPI.WorldAnalysis.Pose();
         sub.pose.Mode = mode;
@@ -311,24 +241,27 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
 
         if (!string.IsNullOrEmpty(response.WebhookUrl))
         {
-            CloseWebSocketClient();
+            // Close other communication channel
+            WebSocketClient_Close();
 
-            // todo: create a REST server so that the WA server can send pose update to it
-            // How to auto-generate the C# REST server for pose for Unity?
-            CreateWebHookServer();
+            // Create a REST server so that the WA server can send pose update to it
+            // How to auto-generate the C# REST webhook server for pose for Unity?
+            string webhookUrl = response.WebhookUrl;
+            WebHookServer_Create(webhookUrl);
         }
         else
         {
-            DestroyWebHookServer();
+            // Close other communication channel
+            WebHookServer_Close();
 
-            // todo: Open the websocket?
-            string websocketUrl = response.WebsocketUrl;
-            if (isDebug) websocketUrl = "ws://localhost:61788/ws"; // for tests
+            // Open the websocket
+            string websocketUrl = "ws://" + response.WebsocketUrl + "/ws";
+            //if (isDebug) websocketUrl = "ws://localhost:61788/ws"; // for tests
 
-            if (string.IsNullOrEmpty(websocketUrl))
+            if (!string.IsNullOrEmpty(websocketUrl))
             {
                 // Create the WebSockets client here (NOT in the scene scripts)
-                if (!websocketConnected) OpenWebSocketClient(websocketUrl);
+                if (!websocketConnected) WebSocketClient_Create(websocketUrl);
             }
             else throw new Exception("[REST] No valid WebSockets URL in server reponse.");
         }
@@ -418,15 +351,16 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
             //
             if (oldCB != null && callback == null && !string.IsNullOrEmpty(response.WebhookUrl))
             {
-                CloseWebSocketClient();
+                WebSocketClient_Close();
 
-                // todo: create a REST server so that the WA server can send pose update to it
+                // Create a REST server so that the WA server can send pose update to it
                 // How to auto-generate the C# REST server for pose for Unity?
-                CreateWebHookServer();
+                string webhookUrl = response.WebhookUrl;
+                WebHookServer_Create(webhookUrl);
             }
             else if (oldCB == null && callback != null && string.IsNullOrEmpty(response.WebhookUrl))
             {
-                DestroyWebHookServer();
+                WebHookServer_Close();
 
                 // todo: Open the websocket?
                 string websocketUrl = response.WebsocketUrl;
@@ -435,7 +369,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
                 if (string.IsNullOrEmpty(websocketUrl))
                 {
                     // Create the WebSockets client here (NOT in the scene scripts)
-                    if (!websocketConnected) OpenWebSocketClient(websocketUrl);
+                    if (!websocketConnected) WebSocketClient_Create(websocketUrl);
                 }
                 else throw new Exception("[REST] No valid WebSockets URL in server reponse.");
             }
@@ -445,7 +379,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
         return InformationSubscriptionResult.UNKNOWN_ID;
     }
 
-    public InformationSubscriptionResult UnSubscribeToPose(Guid subscriptionUUID)
+    public InformationSubscriptionResult UnsubscribeFromPose(Guid subscriptionUUID)
     {
         if (m_subscriptionsPoses.ContainsKey(subscriptionUUID))
         {
@@ -455,7 +389,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface
             if (m_subscriptionsPoses.Count == 0)
             {
                 // Close the connection via websockets
-                CloseWebSocketClient();
+                WebSocketClient_Close();
             }
             return InformationSubscriptionResult.OK;
         }