diff --git a/Jenkinsfile b/Jenkinsfile
index 3e5e2be1a85cfc3c0ad0d70c46fff8dd2ffd967a..f9348236bff042cb87c1ab42ca913266e5057bd5 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -163,7 +163,7 @@ try {
     build job: 'des-mbi-bundle-centos7', wait: false
   }
 } catch(e) {
-  if (env.BRANCH_NAME == '2.8.x' && !(${e} =~ /^.+FlowInterruptedException$/)) {
+  if (env.BRANCH_NAME == '2.8.x' && !(${e} =~ /^.+FlowInterruptedException\$/)) {
     slackSend channel: "#monitoring-metrology",
         color: "#F30031",
         message: "*FAILURE*: `CENTREON WEB` <${env.BUILD_URL}|build #${env.BUILD_NUMBER}> on branch ${env.BRANCH_NAME}\n" +
diff --git a/behat.yml b/behat.yml
index 28d1509a20b887f94534b6fcc2ed333be2ec202e..590842dc7b540ef55b4dab6c7264028673eb4377 100644
--- a/behat.yml
+++ b/behat.yml
@@ -105,6 +105,10 @@ default:
       paths: [ %paths.base%/features/DowntimeDST.feature ]
       contexts: [ DowntimeDSTContext ]
 
+    downtime_recurrent:
+      paths: [ %paths.base%/features/DowntimeRecurrent.feature ]
+      contexts: [ DowntimeRecurrentContext ]
+
     command_arguments:
       paths: [ %paths.base%/features/CommandArguments.feature ]
       contexts: [ CommandArgumentsContext ]
diff --git a/doc/en/_static/images/developer/lua/add_parameter.png b/doc/en/_static/images/developer/lua/add_parameter.png
new file mode 100644
index 0000000000000000000000000000000000000000..453b84cb0f21ceb7b0cd55a76e95b9fd34c81785
Binary files /dev/null and b/doc/en/_static/images/developer/lua/add_parameter.png differ
diff --git a/doc/en/_static/images/developer/lua/add_stream_connector.png b/doc/en/_static/images/developer/lua/add_stream_connector.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e5b27c08a7e98de5807f5b30fafeb7be18daac6
Binary files /dev/null and b/doc/en/_static/images/developer/lua/add_stream_connector.png differ
diff --git a/doc/en/_static/images/developer/lua/archi_broker_lua_script.png b/doc/en/_static/images/developer/lua/archi_broker_lua_script.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffaa5b94b156bf5995967dd3ac30b69d0555f712
Binary files /dev/null and b/doc/en/_static/images/developer/lua/archi_broker_lua_script.png differ
diff --git a/doc/en/_static/images/developer/lua/archi_broker_regular.png b/doc/en/_static/images/developer/lua/archi_broker_regular.png
new file mode 100644
index 0000000000000000000000000000000000000000..470a08ec12665be407fecb6c10883f45be5e06a9
Binary files /dev/null and b/doc/en/_static/images/developer/lua/archi_broker_regular.png differ
diff --git a/doc/en/_static/images/developer/lua/archi_broker_stream.png b/doc/en/_static/images/developer/lua/archi_broker_stream.png
new file mode 100644
index 0000000000000000000000000000000000000000..364e73e60eaac84e40b24ed7d8db221707d980e6
Binary files /dev/null and b/doc/en/_static/images/developer/lua/archi_broker_stream.png differ
diff --git a/doc/en/_static/images/developer/lua/broker_influxdb_output.png b/doc/en/_static/images/developer/lua/broker_influxdb_output.png
new file mode 100644
index 0000000000000000000000000000000000000000..857d23dc7b210591013f583e1c9cb6286e3ed255
Binary files /dev/null and b/doc/en/_static/images/developer/lua/broker_influxdb_output.png differ
diff --git a/doc/en/_static/images/developer/lua/describe_output.png b/doc/en/_static/images/developer/lua/describe_output.png
new file mode 100644
index 0000000000000000000000000000000000000000..16270525de72786ac68207b511755fa8b6bef71b
Binary files /dev/null and b/doc/en/_static/images/developer/lua/describe_output.png differ
diff --git a/doc/en/_static/images/developer/lua/visualize_data_grafana.png b/doc/en/_static/images/developer/lua/visualize_data_grafana.png
new file mode 100644
index 0000000000000000000000000000000000000000..e09321dcd3d5f8170868ecaf21e642cc70892eea
Binary files /dev/null and b/doc/en/_static/images/developer/lua/visualize_data_grafana.png differ
diff --git a/doc/en/api/api_rest/index.rst b/doc/en/api/api_rest/index.rst
index ceb9c619035730e53ed03c25587bc812a7ae2983..844efd45db15b6d667b736e093bdaeb25ea4798c 100644
--- a/doc/en/api/api_rest/index.rst
+++ b/doc/en/api/api_rest/index.rst
@@ -17,8 +17,18 @@ Permissions
 -----------
 
 To perform API calls using a specific Centreon user, you need permissions to do so.
-You have to edit user settings on the menu **Configuration > Users > Contacts/Users**,
-edit user and on second tab check box **Reach API**.
+
+There are two types of permission:
+
+You can give access to the configuration for a specific Centreon user. To do so you have
+to edit user settings on the menu **Configuration > Users > Contacts/Users**,
+edit user and on second tab check box **Reach API Configuration**.
+
+You can give access to the realtime for a specific Centreon user. To do so you have
+to edit user settings on the menu **Configuration > Users > Contacts/Users**,
+edit user and on second tab check box **Reach API Realtime**.
+
+If you want both then check **both** checkboxes
 
 
 Authentication
diff --git a/doc/en/developer/index.rst b/doc/en/developer/index.rst
index 00fa4f69c44e0bd99c0e9097e94c8256ed745762..6fb96d1b6b44cf405bcf97346ba18c458bec0af3 100644
--- a/doc/en/developer/index.rst
+++ b/doc/en/developer/index.rst
@@ -7,4 +7,5 @@ Developer
 
    writemodule
    writewidget
+   writestreamconnector
    translatecentreon
diff --git a/doc/en/developer/writestreamconnector.rst b/doc/en/developer/writestreamconnector.rst
new file mode 100644
index 0000000000000000000000000000000000000000..01d2210956d9f478e5656e65323b0b12d2550634
--- /dev/null
+++ b/doc/en/developer/writestreamconnector.rst
@@ -0,0 +1,901 @@
+===============================
+How to write a Stream Connector
+===============================
+
+********
+Overview
+********
+
+Centreon Stream Connector is a feature introduced in Centreon 3.4.6. It allows
+one to export Centreon data (events and metrics) to an external storage or
+application such as ElasticSearch, Splunk, InfluxDB, files, etc.
+
+In a Centreon platform, the component that carries information between the
+remote pollers and the Centreon central server is called Centreon Broker. This
+broker stores received data into the Centreon local storage: MariaDB and
+RRDtool.
+
+The following diagram explains the transfer of collected data and insertion into
+storages:
+
+.. image:: /_static/images/developer/lua/archi_broker_regular.png
+   :align: center
+   :scale: 65%
+
+The Stream Connector functionality is a new Centreon Broker output getting data
+from Centreon Broker Master (also known as Centreon Broker SQL) to aggregate and
+forward it to external storage:
+
+.. image:: /_static/images/developer/lua/archi_broker_stream.png
+   :align: center
+   :scale: 65%
+
+This output loads a Lua script called a Stream Connector, which job is to
+handle, aggregate and enrich the data before forwarding it to the defined
+protocol:
+
+.. image:: /_static/images/developer/lua/archi_broker_lua_script.png
+   :align: center
+   :scale: 65%
+
+Because it is an output of Centreon Broker, the principle of creating retention
+files upon interrupting external storage access is retained. In the same way,
+it is possible to filter input on the categories of flow to handle.
+
+************
+Requirements
+************
+
+To use the Centreon Stream connector functionality you need to update your Centreon
+platform to Centreon 3.4.6:
+
+* Centreon Web >= 2.8.18
+* Centreon Broker >= 3.0.13
+* Lua >= 5.1.x
+
+*************************
+Creating a new Lua script
+*************************
+
+The complete technical documentation is available `here <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html>`_.
+In this how-to, we will write two scripts:
+
+* The first one, easy, that explains the basics of Stream Connectors. Its goal
+  is to export data to a log file.
+* The second one is more exigent for the reader ; it exports performance data
+  to the TSDB InfluxDB but is easily adaptable to export to another TSDB.
+
+Programming language
+====================
+
+Centreon chose the Lua programming language to let you handle, aggregate and
+transfer data. Lua is a programming language that is easy to use. You can find
+more information with the `Lua official documentation <https://www.lua.org/docs.html>`_
+
+Storage of Lua scripts
+======================
+Broker's Lua scripts can be stored in any directory readable by the
+**centreon-broker** user.
+
+We recommend to store them in **/usr/share/centreon-broker/lua**.
+
+.. note::
+   In a near future, this directory will be in the *default path* of the Lua
+   scripts launched by broker. It will then be easier to use user defined
+   Lua libraries because you will just have to add your libraries there like
+   stream connectors.
+
+Write all information into a file
+=================================
+
+Store raw data
+**************
+
+Let's start with the first script. Our goal is to store all events
+given by Broker in a log file. We will call our stream connector
+**bbdo2file.lua**.
+
+As we said previously, we will store this file into the
+**/usr/share/centreon-broker/lua** directory on the Centreon central server.
+
+If the directory does not exist, as root, we can create it with the following
+command:
+
+.. code-block:: bash
+
+  mkdir -p /usr/share/centreon-broker/lua
+
+Centreon Broker provides several log functions to write logs, warnings or errors
+into a file. We will use one of these functions *info()* to write Broker events.
+`See technical documentation for more information
+<https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-broker-log-object>`_.
+
+The function *info()* makes part of the *broker_log* object. To call it, the
+syntax is the following:
+
+.. code-block:: lua
+
+  broker_log:info(level, text)
+
+* *level* is an integer from 1 (most important) to 3 (least important).
+* *text* is the text to write as log.
+
+.. note::
+  Did you notice the separator between **broker_log** and **info**, yes it is a
+  colon! Objects functions, also called *methods* are called like this in Lua.
+
+Let's start our script. The more important function in a stream connector is
+the **write()** function. Each time an event is received from a poller through
+Broker, this function is called with the event as an argument.
+
+.. note::
+  You will never have to call the **write()** function by yourself, it is always
+  Broker's work to do so. And it would be a fault to make such a call. In other
+  words, there should not be any call to the **write()** function in your script.
+
+`See technical documentation for more information
+<https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-write-function>`_.
+
+Here is the **bbdo2file.lua** first version:
+
+.. code-block:: lua
+
+  function init(conf)
+    broker_log:set_parameters(3, "/var/log/centreon-broker/bbdo2file.log")
+  end
+
+  function write(d)
+    for k,v in pairs(d) do
+      broker_log:info(3, k .. " => " .. tostring(v))
+    end
+    return true
+  end
+
+.. note::
+   Information about the initialization of the Broker's log function
+   and its parameters are given here `see technical documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-broker-log-object>`_.
+
+Let's explain what we are doing in this script.
+
+We must provide an **init()** function, it is described in the `technical documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-init-function>`_.
+
+This function is called during the stream connector initialization.
+Here, we use it to initialize the **broker_log** object. To achieve this,
+we call the **broker_log::set_parameters()** method that needs two parameters :
+
+* A max level (from 1 to 3). If you give 2 here, only logs of levels 1 and 2
+  will be returned.
+* A file to write the logs in. This file must be in a writable directory for
+  the **centreon-broker** user.
+
+The second function is the **write()** function. We already said its argument
+is a Broker event. This type of object is a collection of keys/values. For example:
+
+.. code-block:: json
+
+  {
+    "check_hosts_freshness": false,
+    "active_host_checks": true,
+    "category": 1,
+    "event_handlers": true,
+    "instance_id": 1,
+    "last_command_check": 1522836592,
+    "type": 65552,
+    "global_service_event_handler": "",
+    "obsess_over_services": false,
+    "passive_service_checks": true,
+    "last_alive": 1522836593,
+    "active_service_checks": true,
+    "check_services_freshness": true,
+    "flap_detection": false,
+    "global_host_event_handler": "",
+    "notifications": true,
+    "obsess_over_hosts": false,
+    "passive_host_checks": true,
+    "element": 16
+  }
+
+In all events, you will find *category*, *element* and *type*.
+
+* Information about the *category* can be found `here in the bbdo documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/dev/bbdo.html#event-categories>`_
+* The *element* is the *sub-category* (also called *type* in the bbdo
+  documentation).
+* The *type* is a number built from the *category* and the *element* (binary
+  concatenation).
+
+In this example, the *category* is 1 and the *element* is 16. So, by reading
+the documentation, we can say this event is a NEB event with sub-category
+*instance-status*.
+
+To finish with the **write()** function, we make a loop on the **d** event
+parameters. For each step, *k* is a key and *v* is the corresponding value.
+And we send to the log file a string `k .. " => " .. tostring(v)` that means
+the *concatenation* of *k*, *=>* and *v* converted into a string. You will see
+an example of the result below.
+
+Another possibility would be to use the **broker.json_encode(d)** function that
+converts any Lua object to a *json* string representation of it. So, we could
+write the function like this:
+
+.. code-block:: lua
+
+  function write(d)
+    broker_log:info(3, broker.json_encode(d))
+    return true
+  end
+
+.. note::
+
+  You can notice that **broker.json_encode(d)** is made of **broker** and
+  **json_encode(d)** separated by a *dot* and not a *colon*. This is because
+  **broker** is not a Lua object. In fact, you can see it as a functions set
+  provided by *Centreon Broker*.
+
+Once your file **/usr/share/centreon-broker/lua/bbdo2file.lua** is ready, verify
+it is readable by the **centreon-broker** user (or the **centreon-engine**
+user who is the owner of the **centreon-broker** group), if it is not the case,
+as root you can enter::
+
+  # chown centreon-engine:centreon-engine /usr/share/centreon-broker/lua/bbdo2file.lua
+
+Then configure the new output into Centreon Web interface in
+**Configuration > Pollers > Broker configuration > Central Broker**. In **Output**
+tab select **Generic – Stream connector** and click **Add**:
+
+.. image:: /_static/images/developer/lua/add_stream_connector.png
+   :align: center
+
+Define the name of this output and the path to the Lua connector:
+
+.. image:: /_static/images/developer/lua/describe_output.png
+   :align: center
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+Once the Centreon Broker will be restarted on your Centreon central server, data
+will appear in your **/var/log/centreon-broker/bbdo2file.log** log file::
+
+  mer. 28 mars 2018 14:27:35 CEST: INFO: flap_detection => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: enabled => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: host_id => 102
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_time_ok => 1522240053
+  mer. 28 mars 2018 14:27:35 CEST: INFO: state => 0
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_update => 1522240054
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_check => 1522240053
+  mer. 28 mars 2018 14:27:35 CEST: INFO: execution_time => 0.005025
+  mer. 28 mars 2018 14:27:35 CEST: INFO: acknowledged => false
+  mer. 28 mars 2018 14:27:35 CEST: INFO: service_id => 778
+  mer. 28 mars 2018 14:27:35 CEST: INFO: active_checks => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: notify => false
+  mer. 28 mars 2018 14:27:35 CEST: INFO: max_check_attempts => 3
+  mer. 28 mars 2018 14:27:35 CEST: INFO: obsess_over_service => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_type => 0
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_hard_state_change => 1522165654
+  mer. 28 mars 2018 14:27:35 CEST: INFO: category => 1
+  mer. 28 mars 2018 14:27:35 CEST: INFO: perfdata => used=41986296644o;48103633715;54116587930;0;60129542144 size=60129542144o
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_interval => 5
+  mer. 28 mars 2018 14:27:35 CEST: INFO: output => Disk /var - used : 39.10 Go - size : 56.00 Go - percent : 69 %
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_command => check-bench-disk
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_period => 24x7
+  mer. 28 mars 2018 14:27:35 CEST: INFO: type => 65560
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_hard_state => 0
+
+.. note::
+   This log file will grow quickly, do not forget to add a log rotate.
+
+Use parameters
+**************
+
+The Centreon Broker log functions should be used for log only. To write into a
+file, we must use the Lua dedicated function. Moreover, it is possible to use
+parameters to define the name of the log file.
+
+So it is time to improve our Stream Connector:
+
+.. code-block:: lua
+
+  function init(conf)
+    logFile = conf['logFile']
+    broker_log:set_parameters(3, "/var/log/centreon-broker/debug.log")
+  end
+
+  function write(d)
+    for k,v in pairs(d) do
+      writeIntoFile(k .. " => " .. tostring(v) .. "\n")
+    end
+    return true
+  end
+
+  function writeIntoFile(output)
+    local file,err = io.open(logFile, 'a')
+    if file == nil then
+      broker_log:info(3, "Couldn't open file: " .. err)
+    else
+      file:write(output)
+      file:close()
+    end
+  end
+
+Did you notice that expression `local file,err = io.open(logFile, 'a')`?
+
+Lua is able to store several variables at the same time. Also, Lua functions can
+return several variables!
+
+For example, if you want to swap variables *a* and *b*, you can enter:
+
+.. code-block:: lua
+
+  a, b = b, a
+
+Another example that illustrates several values returned:
+
+.. code-block:: lua
+
+  function fib(a, b)
+    return b, a + b
+  end
+
+So, this call to **io.open** returns two variables, a first variable
+**file** that is a *file descriptor* used to access the file and a second
+variable not always defined that contains error if one occurs or **nil**
+(not defined) otherwise.
+
+The **init()** function allows to get parameters and define these from Centreon
+web interface. See technical documentation for more information. Here, we add
+the possibility to choose the destination file name. The **conf** table has
+a key *logFile* defined in the web interface. The corresponding value is
+the file name used to store events.
+
+Edit your Broker output to declare this parameter:
+
+.. image:: /_static/images/developer/lua/add_parameter.png
+   :align: center
+
+It is important that the name of the parameter in the web interface matches the
+key name in the **conf** table. Here, it is *logFile*.
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+Data are stored into **/var/log/centreon-broker/bbdo2file.log** log file as
+this::
+
+  name => error
+  category => 3
+  interval => 300
+  rrd_len => 3456000
+  value => 0
+  value_type => 0
+  type => 196612
+  ctime => 1522315660
+  index_id => 4880
+  element => 4
+  state => 0
+  category => 3
+  interval => 300
+  rrd_len => 3456000
+  is_for_rebuild => false
+  service_id => 1056
+  type => 196609
+  ctime => 1522315660
+  host_id => 145
+  element => 1
+  is_for_rebuild => false
+  metric_id => 11920
+
+Manipulate data
+***************
+
+Here, we continue to improve our stream connector by choosing what events to
+export and also by improving outputs.
+
+We will select only the NEB category and the events regarding hosts and
+services status.
+
+We know that NEB is the category 1, also service status is the sub-category 24,
+whereas host status is the sub-category 14.
+
+So, only events with the following criteria:
+
+* category = 1
+* element = 14 or element = 24
+
+are interesting for us.
+
+Moreover, we would prefer to have a host name instead of a host id and a service
+description instead of a service id.
+
+At last, we would be interested to get status information and outputs.
+
+NEB Events with elements 14 and 24 give almost all we want except host names and
+service descriptions.
+
+To get those two information, we will have to use the **broker_cache** object.
+This one is filled when pollers are restarted or reloaded. So, do not forget
+to restart your pollers if you want something in your **broker_cache** object!
+
+If the cache is well filled, it is easy to get a host name from the host id::
+
+  broker_cache:get_hostname(host_id)
+
+And it is also easy to get the service description from the host id and service
+id::
+
+  broker_cache:get_service_description(host_id, service_id)
+
+To install the filter on events, there is a useful function called **filter()**
+that takes two parameters into account: *category*, *element*.
+
+This function, if defined, is called just before **write()**. If it returns
+**true**, the **write()** function will be called, otherwise, the event will
+be thrown away.
+
+Let's complete our Lua script:
+
+.. code-block:: lua
+
+  function init(conf)
+    logFile = conf['logFile']
+    broker_log:set_parameters(3, "/var/log/centreon-broker/debug.log")
+  end
+
+  function write(d)
+    local output = ""
+
+    local host_name = broker_cache:get_hostname(d.host_id)
+    if not host_name then
+      broker_log:info(3, "Unable to get name of host, please restart centengine")
+      host_name = d.host_id
+    end
+
+    if d.element == 14 then
+      output = "HOST:" .. host_name .. ";" .. d.host_id .. ";" .. d.state .. ";" .. d.output
+      writeIntoFile(output)
+      broker_log:info(output)
+    elseif d.element == 24 then
+      local service_description = broker_cache:get_service_description(d.host_id, d.service_id)
+      if not service_description then
+        broker_log:info(3, "Unable to get description of service, please restart centengine")
+        service_description = d.service_id
+      end
+      output = "SERVICE:" .. host_name .. ";" .. d.host_id .. ";" .. service_description .. ";" .. d.service_id .. ";" .. d.state .. ";" .. d.output
+      writeIntoFile(output)
+      broker_log:info(output)
+    end
+    return true
+  end
+
+  function filter(category, element)
+    -- Get only host status and services status from NEB category
+    if category == 1 and (element == 14 or element == 24) then
+      return true
+    end
+      return false
+  end
+
+  local function writeIntoFile(output)
+    local file,err = io.open(logFile, 'a')
+    if file == nil then
+      broker_log:info(3, "Couldn't open file: " .. err)
+    else
+      file:write(output)
+      file:close()
+    end
+  end
+
+Just several remarks on this new script before showing what we get.
+
+In the **init()** function, we access the *logFile* key in the *conf* table
+by using `conf['logFile']`. Whereas, in the **write()** function, we access
+the *element* key in the *d* table by using `d.element`...
+
+In fact, the two syntaxes are allowed : `d.element` is the same value than
+`d['element']`.
+
+Another remark, in the **write()** function we can see something like::
+
+  if not host_name then
+
+And in the **writeIntoFile()** function, we can see that::
+
+  if file == nil then
+
+Do they mean the same thing? Where is the difference?
+
+You must know that in Lua, a variable is considered to be **true** if it is
+defined and not **false**:
+
+so, the following code
+
+.. code:: lua
+
+  if toto then
+    print("Good")
+  else
+    print("Bad")
+  end
+
+will write *Good* if *toto* is defined and not **false**. More precisely, it will
+write *Good* in the following cases:
+
+* toto=12
+* toto=true
+* toto="A string"
+* toto=0 (surprising!)
+
+It will write *Bad* in these cases:
+
+* toto=nil (by default a variable is nil, which means not defined)
+* toto=false
+
+The **/var/log/centreon-broker/bbdo2file.log** file will now contain::
+
+  HOST:srv-DC-djakarta;215;0;OK - srv-DC-djakarta: rta 0.061ms, lost 0%
+  SERVICE:mail-titan-gateway;92;disk-/usr;623;0;Disk /usr - used : 42.98 Go - size : 142.00 Go - percent : 30 %
+  SERVICE:mail-sun-master;87;memory-stats;535;0;Memory usage (Total 13.0GB): 0.12GB [buffer:0.00GB] [cache:0.01GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.07GB] [inactive:0.00GB] [apps:0.02GB] [unused:12.88GB]
+  SERVICE:mail-saturn-frontend;86;traffic-eth1;512;0;Traffic In : 4.73 Mb/s (4.73 %), Out : 4.79 Mb/s (4.79 %) - Total RX Bits In : 396.01 Gb, Out : 393.88 Gb
+  SERVICE:mail-saturn-frontend;86;memory-stats;515;0;Memory usage (Total 16.0GB): 8.89GB [buffer:0.43GB] [cache:0.95GB] [pages_tables:0.27GB] [mapped:0.15GB] [active:3.92GB] [inactive:0.29GB] [apps:2.88GB] [unused:7.11GB]
+  SERVICE:mail-neptune-frontend;80;traffic-eth1;392;0;Traffic In : 4.82 Mb/s (4.82 %), Out : 6.48 Mb/s (6.48 %) - Total RX Bits In : 398.40 Gb, Out : 396.44 Gb
+  HOST:srv-DC-casablanca;207;0;OK - srv-DC-casablanca: rta 2.042ms, lost 0%
+  SERVICE:mail-neptune-frontend;80;memory-stats;395;0;Memory usage (Total 9.0GB): 0.54GB [buffer:0.03GB] [cache:0.00GB] [pages_tables:0.01GB] [mapped:0.00GB] [active:0.48GB] [inactive:0.00GB] [apps:0.01GB] [unused:8.46GB]
+  SERVICE:mail-mercury-frontend;82;traffic-eth1;432;0;Traffic In : 8.28 Mb/s (8.28 %), Out : 1.23 Mb/s (1.23 %) - Total RX Bits In : 397.71 Gb, Out : 400.34 Gb
+  SERVICE:mail-mercury-frontend;82;memory-stats;435;0;Memory usage (Total 12.0GB): 1.58GB [buffer:0.00GB] [cache:0.63GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.75GB] [inactive:0.00GB] [apps:0.19GB] [unused:10.42GB]
+  SERVICE:mail-mars-frontend;84;traffic-eth1;472;0;Traffic In : 7.24 Mb/s (7.24 %), Out : 3.36 Mb/s (3.36 %) - Total RX Bits In : 399.93 Gb, Out : 395.67 Gb
+  SERVICE:mail-mars-frontend;84;memory-stats;475;0;Memory usage (Total 3.0GB): 1.19GB [buffer:0.01GB] [cache:0.59GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.15GB] [inactive:0.04GB] [apps:0.39GB] [unused:1.81GB]
+  SERVICE:mail-jupiter-frontend;85;traffic-eth1;492;0;Traffic In : 1.41 Mb/s (1.41 %), Out : 9.08 Mb/s (9.08 %) - Total RX Bits In : 388.86 Gb, Out : 394.85 Gb
+  SERVICE:mail-jupiter-frontend;85;memory-stats;495;0;Memory usage (Total 12.0GB): 0.57GB [buffer:0.04GB] [cache:0.23GB] [pages_tables:0.02GB] [mapped:0.02GB] [active:0.07GB] [inactive:0.03GB] [apps:0.16GB] [unused:11.43GB]
+  SERVICE:mail-io-backend;88;traffic-eth1;547;0;Traffic In : 1.51 Mb/s (1.51 %), Out : 7.12 Mb/s (7.12 %) - Total RX Bits In : 389.61 Gb, Out : 390.54 Gb
+  SERVICE:mail-io-backend;88;diskio-system;551;0;Device /dev/sda: avg read 4.78 (MB/s) and write 9.08 (MB/s)
+
+
+***********************************
+Export performance data to InfluxDB
+***********************************
+
+Now, you have already seen many things about stream connectors. It is time to
+create something more useful!
+
+`InfluxDB <https://www.influxdata.com/>`_ is a Time Series database. We will use
+this storage to insert performance data collected by the Centreon platform. For
+this example, we will use the predefined `InfluxDB Docker <https://hub.docker.com/_/influxdb/>`_.
+
+To send data to InfluxDB, we need parameters to access to InfluxDB storage:
+
+* **http_server_address**: IP address of the storage
+* **http_server_port**: 8086 by default
+* **http_server_protocol**: http or https
+* **influx_database**: name of database
+* **influx_user**: user to access to database if defined
+* **influx_password**: password of user to access to database if defined
+
+In order to not saturate the storage, we will add all events in a queue and
+once its max size is reached, we will send data by bulk.
+
+We need to define the size of the queue and the maximum
+delay before sending events:
+
+* max_buffer_size
+* max_buffer_age
+
+To create this queue, we introduce a code a little more complicated. We
+construct an object **event_queue**. It is composed of parameters such as
+*events*, *influx_database* and methods like *new()*, *add()*.
+
+To understand how to create such an object in Lua, we recommend the Lua
+documentation `here for classes <https://www.lua.org/pil/16.1.html>`_
+and `there for metatables <https://www.lua.org/pil/13.html>`_.
+
+To send data to a server, we provide a **broker_tcp_socket** object.
+
+Its API is very simple (too simple?). This *socket*
+is a TCP socket, it does not support encryption and it can be tricky to send
+data in http. Here is an example:
+
+.. code-block:: lua
+
+  -- Here, we create our socket
+  local socket = broker_tcp_socket.new()
+
+  -- We establish the connection with the server
+  socket:connect(address, port)
+
+  -- Now, we can send data
+  socket:write("This is a text to send")
+
+  -- If, we want an answer, we also have a function to read
+  local content = socket:read()
+
+  -- When exchanges are finished, we can close the socket
+  socket:close()
+
+For our purpose, we do not use **broker_tcp_socket** because of its limitations.
+We want to be able to send data to an https server.
+
+A prerequisite is to install the `lua-socket library <http://w3.impa.br/~diego/software/luasocket/>`_. This library provides several functionalities, we
+need two of them:
+
+* http socket
+* ltn12
+
+To access them, Lua provides the **require** function.
+
+Let's introduce the beginning of our new Stream Connector.
+
+The queue parameters
+====================
+
+.. code-block:: lua
+
+  -- We declare the objects to import here
+  local http = require("socket.http")
+  local ltn12 = require("ltn12")
+
+  -- Here are predefined queue parameters
+  local event_queue = {
+    __internal_ts_last_flush    = nil,
+    http_server_address         = "",
+    http_server_port            = 8086,
+    http_server_protocol        = "http",
+    events                      = {},
+    influx_database             = "mydb",
+    influx_user                 = "",
+    influx_password             = "",
+    max_buffer_size             = 5000,
+    max_buffer_age              = 5
+  }
+
+
+In this table, we give default values to parameters that can possibly
+be changed during the **init()** call. This table will be used to store important
+data for the script and is also our queue object.
+
+A method to create the queue
+============================
+
+To declare this table as a Lua object, we need a constructor. So, here it is:
+
+.. code-block:: lua
+
+  -- Constructor of the event_queue
+  function event_queue:new(o, conf)
+    o = o or {}
+    setmetatable(o, self)
+    self.__index = self
+    for i,v in pairs(conf) do
+      if self[i] and i ~= "events" and string.sub(i, 1, 11) ~= "__internal_" then
+        broker_log:info(1, "event_queue:new: getting parameter " .. i .. " => " .. v)
+        self[i] = v
+      else
+        broker_log:warning(1, "event_queue:new: ignoring parameter " .. i .. " => " .. v)
+      end
+    end
+    self.__internal_ts_last_flush = os.time()
+    broker_log:info(2, "event_queue:new: setting the internal timestamp to " .. self.__internal_ts_last_flush)
+    return o
+  end
+
+.. note::
+   In this function, we use a Lua sugar "o = o or {}" that means *o* stays the
+   same if it is **true**, otherwise it is affected with an empty table `{}`.
+
+   Another point to notice is the **~=** operator that means **different from**.
+
+   And to finish on this function, the variable **self** is implicitly defined
+   when we declare an object's method. Its meaning is the same as **this** in
+   Java or in C++. It represents the object we are working on.
+
+A method to add event in queue
+==============================
+
+We have a queue object. It would be great to use it like this:
+
+.. code-block:: lua
+
+  -- We construct it
+  local queue = event_queue:new(nil, conf)
+
+  -- We add an event to it
+  queue:add(event)
+
+  -- When the queue is full, we would like to do something like this
+  queue:flush()
+
+
+Let's do it! Below, we present an **add()** method that retrieves a host name
+and service description from the cache, builds a string from the event and
+pushes it on its stack.
+
+.. code-block:: lua
+
+  function event_queue:add(e)
+    local metric = e.name
+    -- time is a reserved word in influxDB so I rename it
+    if metric == "time" then
+      metric = "_" .. metric
+    end
+
+    -- retrieve objects names instead of IDs
+    local host_name = broker_cache:get_hostname(e.host_id)
+    local service_description = broker_cache:get_service_description(e.host_id, e.service_id)
+
+    -- what if we could not get them from cache
+    if not host_name then
+      broker_log:warning(1, "event_queue:add: host_name for id " .. e.host_id .. " not found. Restarting centengine should fix this.")
+      host_name = e.host_id
+    end
+    if not service_description then
+      broker_log:warning(1, "event_queue:add: service_description for id " .. e.host_id .. "." .. e.service_id .. " not found. Restarting centengine should fix this.")
+      service_description = e.service_id
+    else
+      service_description = service_description:gsub(" ", "_")
+    end
+
+    -- we finally append the event to the events table
+    metric = metric:gsub(" ", "_")
+    broker_log:info(3, 'event_queue:add: adding  ' .. service_description .. ",host=" .. host_name .. " " .. metric .. "=" .. e.value .. " " .. e.ctime .. '000000000" to event list.')
+    self.events[#self.events + 1] = service_description .. ",host=" .. host_name .. " " .. metric .. "=" .. e.value .. " " .. e.ctime .. "000000000\n"
+
+    -- then we check whether it is time to send the events to the receiver and flush
+    if #self.events >= self.max_buffer_size then
+      broker_log:info(2, "event_queue:add: flushing because buffer size reached " .. self.max_buffer_size .. " elements.")
+      self:flush()
+      return true
+    elseif os.time() - self.__internal_ts_last_flush >= self.max_buffer_age then
+      broker_log:info(2, "event_queue:add: flushing " .. #self.events .. " elements because buffer age reached " .. (os.time() - self.__internal_ts_last_flush) .. "s and max age is " .. self.max_buffer_age .. "s.")
+      self:flush()
+      return true
+    else
+      return false
+    end
+  end
+
+A method to flush the queue
+===========================
+
+Once the events added in the queue and the maximum size of the queue or the
+timeout is reached, events will be sent to the InfluxDB storage.
+
+This function builds data from the queue and sends them to the storage. If an
+error occurs, it dumps a log error.
+
+It is here that we use the **http** and **ltn12** objects loaded at the
+beginning of the script.
+
+.. code-block:: lua
+
+  function event_queue:flush()
+    broker_log:info(2, "event_queue:flush: Concatenating all the events as one string")
+    --  we concatenate all the events
+    local http_post_data = ""
+    local http_result_body = {}
+    for i, raw_event in ipairs(self.events) do
+      http_post_data = http_post_data .. raw_event
+    end
+    broker_log:info(2, 'event_queue:flush: HTTP POST request "' .. self.http_server_protocol .. "://" .. self.http_server_address .. ":" .. self.http_server_port .. "/write?db=" .. self.influx_database .. '"')
+    broker_log:info(3, "event_queue:flush: HTTP POST data are: '" .. http_post_data .. "'")
+
+    -- build url
+    local influxdb_url = self.http_server_protocol .. "://" .. self.http_server_address .. ":" .. self.http_server_port .. "/write?db=" .. self.influx_database
+    -- add authentication if needed
+    if string.len(self.influx_user) >= 1 and string.len(self.influx_password) >= 1 then
+      influxdb_url = influxdb_url .. "&u=" .. self.influx_user .. "&p="..self.influx_password
+    end
+
+    local hr_result, hr_code, hr_header, hr_s = http.request{
+      url = influxdb_url,
+      method = "POST",
+      -- sink is where the request result's body will go
+      sink = ltn12.sink.table(http_result_body),
+      -- request body needs to be formatted as a LTN12 source
+      source = ltn12.source.string(http_post_data),
+      headers = {
+        -- mandatory for POST request with body
+        ["content-length"] = string.len(http_post_data)
+      }
+    }
+    -- Handling the return code
+    if hr_code == 204 then
+      broker_log:info(2, "event_queue:flush: HTTP POST request successful: return code is " .. hr_code)
+    else
+      broker_log:error(1, "event_queue:flush: HTTP POST request FAILED: return code is " .. hr_code)
+      for i, v in ipairs(http_result_body) do
+        broker_log:error(1, "event_queue:flush: HTTP POST request FAILED: message line " .. i .. ' is "' .. v .. '"')
+      end
+    end
+
+    -- now that the data has been sent, we empty the events array
+    self.events = {}
+    -- and update the timestamp
+    self.__internal_ts_last_flush = os.time()
+  end
+
+The init() function to get parameters and create the queue
+==========================================================
+
+In this case, the **init()** function creates the queue with parameters
+defined by users in the web interface or uses default parameters already
+defined in the queue. This alternative is managed by the queue constructor.
+
+.. code-block:: lua
+
+  function init(conf)
+    broker_log:set_parameters(1, "/var/log/centreon-broker/stream-connector-influxdb.log")
+    broker_log:info(2, "init: Beginning init() function")
+    queue = event_queue:new(nil, conf)
+    broker_log:info(2, "init: Ending init() function, Event queue created")
+  end
+
+.. note::
+
+  **queue** is not defined as local, this is important so that it is accessible
+  from all the functions.
+
+The write() function to insert events in queue
+==============================================
+
+The **write()** function is only used to insert filtered events into the queue:
+
+.. code-block:: lua
+
+  function write(e)
+    broker_log:info(3, "write: Beginning write() function")
+    queue:add(e)
+    broker_log:info(3, "write: Ending write() function\n")
+    return true
+  end
+
+The filter() function to select only performance data events
+============================================================
+
+To select only performance data, we need to select *category* 3 (“Storage”)
+and *element* 1 for *metric*:
+
+.. code-block:: lua
+
+  function filter(category, element)
+    if category == 3 and element == 1 then
+      return true
+    end
+    return false
+  end
+
+Complete script
+===============
+
+The complete script can be downloaded `here <https://github.com/centreon/centreon-stream-connector-scripts/tree/master/influxdb>`_.
+
+Configure Centreon Broker
+=========================
+
+Configure the new output into Centreon Web interface in
+**Configuration > Pollers > Broker configuration > Central Broker**.
+In **Output** tab select **Generic – Stream connector** and click **Add**:
+
+.. image:: /_static/images/developer/lua/add_stream_connector.png
+   :align: center
+
+Define the name of this output and the path to the Lua connector:
+
+.. image:: /_static/images/developer/lua/broker_influxdb_output.png
+   :align: center
+   :scale: 65%
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+.. note::
+   Don’t forget to restart “centengine” too to create the Centreon Broker cache.
+
+If you install the `Grafana <https://grafana.com/>`_ dashboard, you can visualize the stored data:
+
+.. image:: /_static/images/developer/lua/visualize_data_grafana.png
+   :align: center
+   :scale: 65%
+
+Discover other Centreon Stream Connectors
+=========================================
+
+Centreon provides a Github repository to host Lua scripts developed by Centreon
+and the community. Please go to the `dedicated Github <http://github.com/centreon/centreon-stream-connector-scripts>`_.
+
+Need help to develop your Stream connector? You want to share your experience with
+the community? Join the `Centreon community Slack channel <https://centreon.github.io/>`_.
+
diff --git a/doc/en/release_notes/centreon-2.8/centreon-2.8.20.rst b/doc/en/release_notes/centreon-2.8/centreon-2.8.20.rst
index c95b30b0b272acfe8475c0c9301c097fa9f03026..b45a4a2fe55a259f0ceaa035ef907c62dcaf8b95 100644
--- a/doc/en/release_notes/centreon-2.8/centreon-2.8.20.rst
+++ b/doc/en/release_notes/centreon-2.8/centreon-2.8.20.rst
@@ -5,6 +5,28 @@ Centreon Web 2.8.20
 Enhancements
 ============
 
+* [API] Add default poller - PR #6098
+* [API] Link host with default poller if unknown poller - PR #6099
+* [ACL] Improve performance - #6056 PR #6107
+* [Documentation] Improve Centreon CLAPI usage - PR #6090 #6091
+* [Documentation] Improve documentation to add a new poller - #6075 PR  #6086
+* [Documentation] Add notice for 64 bits support only - PR #6101
+* [Monitoring] Display links in output and comments  - #5943 PR #6113
+
 Bug Fixes
 =========
 
+* [ACL] Allow nested groups filter in ldap configuration - #6127 PR #6128
+* [API] Export specific service, add host before service in CLAPI - PR #6100
+* [API] CLAPI add resource export filter - PR #6125
+* [API] CLAPI Export contact with contact group - PR #6131
+* [API] CLAPI Export service categories - PR #6134
+* [Configuration] SNMP trap poller generation uses ACL - #6043 PR #6069
+* [Custom Views] Fix share custom view - PR #6109
+* [Poller Stats] Poller Statistics Graphs are displayed in first column only - #6003 PR #6122
+
+Others
+======
+
+* Update copyright date on the login page - PR #6076
+* Remove multiple debug in Centreon - PR #6138
\ No newline at end of file
diff --git a/doc/en/release_notes/centreon-2.8/centreon-2.8.21.rst b/doc/en/release_notes/centreon-2.8/centreon-2.8.21.rst
index a74c0badd68c52365df1eaeafacba1f4e9262211..cc9ffa5012ae1c2a7ee71e299b291875b97ec8d8 100644
--- a/doc/en/release_notes/centreon-2.8/centreon-2.8.21.rst
+++ b/doc/en/release_notes/centreon-2.8/centreon-2.8.21.rst
@@ -5,5 +5,17 @@ Centreon Web 2.8.21
 Enhancements
 ============
 
+* [Documentation] Add chapter about how to write a stream connector - PR #6189
+* [API] Separate REST API configuration and REST API realtime access - PR #6188
+
 Bug Fixes
 =========
+
+* [ACL] Manage filters (poller, host, service) on servicegroup - PR #6163
+* [Configuration] Fix output stream connector name for fresh install - PR #6159 #6182
+* [Configuration] No "Conf changed" flag set to "yes" when deploying services to selected hosts - #6160 PR #6191
+
+Other
+=====
+
+* Fix php warning in realtime host API - PR #6174
\ No newline at end of file
diff --git a/doc/en/release_notes/centreon-2.8/centreon-2.8.22.rst b/doc/en/release_notes/centreon-2.8/centreon-2.8.22.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2cf9f9b79db2e7df6b1ef29d5496040ca2dfecde
--- /dev/null
+++ b/doc/en/release_notes/centreon-2.8/centreon-2.8.22.rst
@@ -0,0 +1,14 @@
+###################
+Centreon Web 2.8.22
+###################
+
+Enhancements
+============
+
+Bug Fixes
+=========
+
+* [CLAPI] Fix host services deployment - PR #6212
+
+Other
+=====
diff --git a/doc/en/release_notes/centreon-2.8/centreon-2.8.23.rst b/doc/en/release_notes/centreon-2.8/centreon-2.8.23.rst
new file mode 100644
index 0000000000000000000000000000000000000000..603bb166a422992225583595a3c305ce05eefa19
--- /dev/null
+++ b/doc/en/release_notes/centreon-2.8/centreon-2.8.23.rst
@@ -0,0 +1,32 @@
+###################
+Centreon Web 2.8.23
+###################
+
+Enhancements
+============
+
+* [API] Add default poller - PR #6098
+* [API] Link host with default poller if unknown poller - PR #6099
+* [ACL] Improve performance - #6056 PR #6107
+* [Documentation] Improve Centreon CLAPI usage - PR #6090 #6091
+* [Documentation] Improve documentation to add a new poller - #6075 PR  #6086
+* [Documentation] Add notice for 64 bits support only - PR #6101
+* [Monitoring] Display links in output and comments  - #5943 PR #6113
+
+Bug Fixes
+=========
+
+* [ACL] Allow nested groups filter in ldap configuration - #6127 PR #6128
+* [API] Export specific service, add host before service in CLAPI - PR #6100
+* [API] CLAPI add resource export filter - PR #6125
+* [API] CLAPI Export contact with contact group - PR #6131
+* [API] CLAPI Export service categories - PR #6134
+* [Configuration] SNMP trap poller generation uses ACL - #6043 PR #6069
+* [Custom Views] Fix share custom view - PR #6109
+* [Poller Stats] Poller Statistics Graphs are displayed in first column only - #6003 PR #6122
+
+Others
+======
+
+* Update copyright date on the login page - PR #6076
+* Remove multiple debug in Centreon - PR #6138
diff --git a/doc/en/release_notes/centreon-2.8/index.rst b/doc/en/release_notes/centreon-2.8/index.rst
index 845a9edebbf7f1848f0c03682b431022ff5054c9..1a40f83ac3110f7a40f706bb6b03d0647992f5e9 100644
--- a/doc/en/release_notes/centreon-2.8/index.rst
+++ b/doc/en/release_notes/centreon-2.8/index.rst
@@ -28,3 +28,5 @@ Please find here the release notes dedicated to the last 2.8.x version of Centre
     centreon-2.8.19
     centreon-2.8.20
     centreon-2.8.21
+    centreon-2.8.22
+    centreon-2.8.23
diff --git a/doc/fr/_static/images/developper/lua/add_parameter.png b/doc/fr/_static/images/developper/lua/add_parameter.png
new file mode 100644
index 0000000000000000000000000000000000000000..453b84cb0f21ceb7b0cd55a76e95b9fd34c81785
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/add_parameter.png differ
diff --git a/doc/fr/_static/images/developper/lua/add_stream_connector.png b/doc/fr/_static/images/developper/lua/add_stream_connector.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e5b27c08a7e98de5807f5b30fafeb7be18daac6
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/add_stream_connector.png differ
diff --git a/doc/fr/_static/images/developper/lua/archi_broker_lua_script.png b/doc/fr/_static/images/developper/lua/archi_broker_lua_script.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffaa5b94b156bf5995967dd3ac30b69d0555f712
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/archi_broker_lua_script.png differ
diff --git a/doc/fr/_static/images/developper/lua/archi_broker_regular.png b/doc/fr/_static/images/developper/lua/archi_broker_regular.png
new file mode 100644
index 0000000000000000000000000000000000000000..470a08ec12665be407fecb6c10883f45be5e06a9
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/archi_broker_regular.png differ
diff --git a/doc/fr/_static/images/developper/lua/archi_broker_stream.png b/doc/fr/_static/images/developper/lua/archi_broker_stream.png
new file mode 100644
index 0000000000000000000000000000000000000000..364e73e60eaac84e40b24ed7d8db221707d980e6
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/archi_broker_stream.png differ
diff --git a/doc/fr/_static/images/developper/lua/broker_influxdb_output.png b/doc/fr/_static/images/developper/lua/broker_influxdb_output.png
new file mode 100644
index 0000000000000000000000000000000000000000..857d23dc7b210591013f583e1c9cb6286e3ed255
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/broker_influxdb_output.png differ
diff --git a/doc/fr/_static/images/developper/lua/describe_output.png b/doc/fr/_static/images/developper/lua/describe_output.png
new file mode 100644
index 0000000000000000000000000000000000000000..16270525de72786ac68207b511755fa8b6bef71b
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/describe_output.png differ
diff --git a/doc/fr/_static/images/developper/lua/visualize_data_grafana.png b/doc/fr/_static/images/developper/lua/visualize_data_grafana.png
new file mode 100644
index 0000000000000000000000000000000000000000..e09321dcd3d5f8170868ecaf21e642cc70892eea
Binary files /dev/null and b/doc/fr/_static/images/developper/lua/visualize_data_grafana.png differ
diff --git a/doc/fr/api/api_rest/index.rst b/doc/fr/api/api_rest/index.rst
index 3ee977556796ff183d3abdfcc58173088c7806d9..88cf723750017f90daac93fef07e3c44ab1a12cd 100644
--- a/doc/fr/api/api_rest/index.rst
+++ b/doc/fr/api/api_rest/index.rst
@@ -17,9 +17,18 @@ Permissions
 -----------
 
 To perform API calls using a specific Centreon user, you need permissions to do so.
-You have to edit user settings on the menu **Configuration > Users > Contacts/Users**,
-edit user and on second tab check box **Reach API**.
 
+There are two types of permission:
+
+You can give access to the configuration for a specific Centreon user. To do so you have
+to edit user settings on the menu **Configuration > Users > Contacts/Users**,
+edit user and on second tab check box **Reach API Configuration**.
+
+You can give access to the realtime for a specific Centreon user. To do so you have
+to edit user settings on the menu **Configuration > Users > Contacts/Users**,
+edit user and on second tab check box **Reach API Realtime**.
+
+If you want both then check **both** checkboxes
 
 Authentication
 ----------------
diff --git a/doc/fr/configuration_guide/deploy.rst b/doc/fr/configuration_guide/deploy.rst
index 2f4ed375a8ffc41119f7012765ce8d8bd8044f9d..4772e5b02ee8befc74616c8dc3cea1bb960fb37f 100644
--- a/doc/fr/configuration_guide/deploy.rst
+++ b/doc/fr/configuration_guide/deploy.rst
@@ -16,7 +16,7 @@ Première étape
 
 #. Rendez-vous dans le menu **Configuration** ==> **Collecteurs**
 #. Choisissez les collecteurs sur lesquels exporter la configuration
-#. Cliquez sur **Appliquez la configurartion**
+#. Cliquez sur **Appliquez la configuration**
 
 .. image:: /images/guide_utilisateur/configuration/poller_menu_generate.png
     :align: center
diff --git a/doc/fr/developper/index.rst b/doc/fr/developper/index.rst
index 039539bf6be2038a061caa3baaa16f72117af73a..61ea642d1a134b1426e7d4971de4bbe099b5a026 100644
--- a/doc/fr/developper/index.rst
+++ b/doc/fr/developper/index.rst
@@ -9,4 +9,5 @@ Ce chapitre est une reprise sans traduction de la documentation anglaise.
 
    writemodule
    writewidget
+   writestreamconnector
    translatecentreon
diff --git a/doc/fr/developper/writestreamconnector.rst b/doc/fr/developper/writestreamconnector.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cf94eb6cf83eed5946005553482c41c143a8ab16
--- /dev/null
+++ b/doc/fr/developper/writestreamconnector.rst
@@ -0,0 +1,901 @@
+===============================
+How to write a Stream Connector
+===============================
+
+********
+Overview
+********
+
+Centreon Stream Connector is a feature introduced in Centreon 3.4.6. It allows
+one to export Centreon data (events and metrics) to an external storage or
+application such as ElasticSearch, Splunk, InfluxDB, files, etc.
+
+In a Centreon platform, the component that carries information between the
+remote pollers and the Centreon central server is called Centreon Broker. This
+broker stores received data into the Centreon local storage: MariaDB and
+RRDtool.
+
+The following diagram explains the transfer of collected data and insertion into
+storages:
+
+.. image:: /_static/images/developper/lua/archi_broker_regular.png
+   :align: center
+   :scale: 65%
+
+The Stream Connector functionality is a new Centreon Broker output getting data
+from Centreon Broker Master (also known as Centreon Broker SQL) to aggregate and
+forward it to external storage:
+
+.. image:: /_static/images/developper/lua/archi_broker_stream.png
+   :align: center
+   :scale: 65%
+
+This output loads a Lua script called a Stream Connector, which job is to
+handle, aggregate and enrich the data before forwarding it to the defined
+protocol:
+
+.. image:: /_static/images/developper/lua/archi_broker_lua_script.png
+   :align: center
+   :scale: 65%
+
+Because it is an output of Centreon Broker, the principle of creating retention
+files upon interrupting external storage access is retained. In the same way,
+it is possible to filter input on the categories of flow to handle.
+
+************
+Requirements
+************
+
+To use the Centreon Stream connector functionality you need to update your Centreon
+platform to Centreon 3.4.6:
+
+* Centreon Web >= 2.8.18
+* Centreon Broker >= 3.0.13
+* Lua >= 5.1.x
+
+*************************
+Creating a new Lua script
+*************************
+
+The complete technical documentation is available `here <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html>`_.
+In this how-to, we will write two scripts:
+
+* The first one, easy, that explains the basics of Stream Connectors. Its goal
+  is to export data to a log file.
+* The second one is more exigent for the reader ; it exports performance data
+  to the TSDB InfluxDB but is easily adaptable to export to another TSDB.
+
+Programming language
+====================
+
+Centreon chose the Lua programming language to let you handle, aggregate and
+transfer data. Lua is a programming language that is easy to use. You can find
+more information with the `Lua official documentation <https://www.lua.org/docs.html>`_
+
+Storage of Lua scripts
+======================
+Broker's Lua scripts can be stored in any directory readable by the
+**centreon-broker** user.
+
+We recommend to store them in **/usr/share/centreon-broker/lua**.
+
+.. note::
+   In a near future, this directory will be in the *default path* of the Lua
+   scripts launched by broker. It will then be easier to use user defined
+   Lua libraries because you will just have to add your libraries there like
+   stream connectors.
+
+Write all information into a file
+=================================
+
+Store raw data
+**************
+
+Let's start with the first script. Our goal is to store all events
+given by Broker in a log file. We will call our stream connector
+**bbdo2file.lua**.
+
+As we said previously, we will store this file into the
+**/usr/share/centreon-broker/lua** directory on the Centreon central server.
+
+If the directory does not exist, as root, we can create it with the following
+command:
+
+.. code-block:: bash
+
+  mkdir -p /usr/share/centreon-broker/lua
+
+Centreon Broker provides several log functions to write logs, warnings or errors
+into a file. We will use one of these functions *info()* to write Broker events.
+`See technical documentation for more information
+<https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-broker-log-object>`_.
+
+The function *info()* makes part of the *broker_log* object. To call it, the
+syntax is the following:
+
+.. code-block:: lua
+
+  broker_log:info(level, text)
+
+* *level* is an integer from 1 (most important) to 3 (least important).
+* *text* is the text to write as log.
+
+.. note::
+  Did you notice the separator between **broker_log** and **info**, yes it is a
+  colon! Objects functions, also called *methods* are called like this in Lua.
+
+Let's start our script. The more important function in a stream connector is
+the **write()** function. Each time an event is received from a poller through
+Broker, this function is called with the event as an argument.
+
+.. note::
+  You will never have to call the **write()** function by yourself, it is always
+  Broker's work to do so. And it would be a fault to make such a call. In other
+  words, there should not be any call to the **write()** function in your script.
+
+`See technical documentation for more information
+<https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-write-function>`_.
+
+Here is the **bbdo2file.lua** first version:
+
+.. code-block:: lua
+
+  function init(conf)
+    broker_log:set_parameters(3, "/var/log/centreon-broker/bbdo2file.log")
+  end
+
+  function write(d)
+    for k,v in pairs(d) do
+      broker_log:info(3, k .. " => " .. tostring(v))
+    end
+    return true
+  end
+
+.. note::
+   Information about the initialization of the Broker's log function
+   and its parameters are given here `see technical documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-broker-log-object>`_.
+
+Let's explain what we are doing in this script.
+
+We must provide an **init()** function, it is described in the `technical documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/exploit/stream_connectors.html#the-init-function>`_.
+
+This function is called during the stream connector initialization.
+Here, we use it to initialize the **broker_log** object. To achieve this,
+we call the **broker_log::set_parameters()** method that needs two parameters :
+
+* A max level (from 1 to 3). If you give 2 here, only logs of levels 1 and 2
+  will be returned.
+* A file to write the logs in. This file must be in a writable directory for
+  the **centreon-broker** user.
+
+The second function is the **write()** function. We already said its argument
+is a Broker event. This type of object is a collection of keys/values. For example:
+
+.. code-block:: json
+
+  {
+    "check_hosts_freshness": false,
+    "active_host_checks": true,
+    "category": 1,
+    "event_handlers": true,
+    "instance_id": 1,
+    "last_command_check": 1522836592,
+    "type": 65552,
+    "global_service_event_handler": "",
+    "obsess_over_services": false,
+    "passive_service_checks": true,
+    "last_alive": 1522836593,
+    "active_service_checks": true,
+    "check_services_freshness": true,
+    "flap_detection": false,
+    "global_host_event_handler": "",
+    "notifications": true,
+    "obsess_over_hosts": false,
+    "passive_host_checks": true,
+    "element": 16
+  }
+
+In all events, you will find *category*, *element* and *type*.
+
+* Information about the *category* can be found `here in the bbdo documentation <https://documentation.centreon.com/docs/centreon-broker/en/latest/dev/bbdo.html#event-categories>`_
+* The *element* is the *sub-category* (also called *type* in the bbdo
+  documentation).
+* The *type* is a number built from the *category* and the *element* (binary
+  concatenation).
+
+In this example, the *category* is 1 and the *element* is 16. So, by reading
+the documentation, we can say this event is a NEB event with sub-category
+*instance-status*.
+
+To finish with the **write()** function, we make a loop on the **d** event
+parameters. For each step, *k* is a key and *v* is the corresponding value.
+And we send to the log file a string `k .. " => " .. tostring(v)` that means
+the *concatenation* of *k*, *=>* and *v* converted into a string. You will see
+an example of the result below.
+
+Another possibility would be to use the **broker.json_encode(d)** function that
+converts any Lua object to a *json* string representation of it. So, we could
+write the function like this:
+
+.. code-block:: lua
+
+  function write(d)
+    broker_log:info(3, broker.json_encode(d))
+    return true
+  end
+
+.. note::
+
+  You can notice that **broker.json_encode(d)** is made of **broker** and
+  **json_encode(d)** separated by a *dot* and not a *colon*. This is because
+  **broker** is not a Lua object. In fact, you can see it as a functions set
+  provided by *Centreon Broker*.
+
+Once your file **/usr/share/centreon-broker/lua/bbdo2file.lua** is ready, verify
+it is readable by the **centreon-broker** user (or the **centreon-engine**
+user who is the owner of the **centreon-broker** group), if it is not the case,
+as root you can enter::
+
+  # chown centreon-engine:centreon-engine /usr/share/centreon-broker/lua/bbdo2file.lua
+
+Then configure the new output into Centreon Web interface in
+**Configuration > Pollers > Broker configuration > Central Broker**. In **Output**
+tab select **Generic – Stream connector** and click **Add**:
+
+.. image:: /_static/images/developper/lua/add_stream_connector.png
+   :align: center
+
+Define the name of this output and the path to the Lua connector:
+
+.. image:: /_static/images/developper/lua/describe_output.png
+   :align: center
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+Once the Centreon Broker will be restarted on your Centreon central server, data
+will appear in your **/var/log/centreon-broker/bbdo2file.log** log file::
+
+  mer. 28 mars 2018 14:27:35 CEST: INFO: flap_detection => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: enabled => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: host_id => 102
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_time_ok => 1522240053
+  mer. 28 mars 2018 14:27:35 CEST: INFO: state => 0
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_update => 1522240054
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_check => 1522240053
+  mer. 28 mars 2018 14:27:35 CEST: INFO: execution_time => 0.005025
+  mer. 28 mars 2018 14:27:35 CEST: INFO: acknowledged => false
+  mer. 28 mars 2018 14:27:35 CEST: INFO: service_id => 778
+  mer. 28 mars 2018 14:27:35 CEST: INFO: active_checks => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: notify => false
+  mer. 28 mars 2018 14:27:35 CEST: INFO: max_check_attempts => 3
+  mer. 28 mars 2018 14:27:35 CEST: INFO: obsess_over_service => true
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_type => 0
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_hard_state_change => 1522165654
+  mer. 28 mars 2018 14:27:35 CEST: INFO: category => 1
+  mer. 28 mars 2018 14:27:35 CEST: INFO: perfdata => used=41986296644o;48103633715;54116587930;0;60129542144 size=60129542144o
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_interval => 5
+  mer. 28 mars 2018 14:27:35 CEST: INFO: output => Disk /var - used : 39.10 Go - size : 56.00 Go - percent : 69 %
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_command => check-bench-disk
+  mer. 28 mars 2018 14:27:35 CEST: INFO: check_period => 24x7
+  mer. 28 mars 2018 14:27:35 CEST: INFO: type => 65560
+  mer. 28 mars 2018 14:27:35 CEST: INFO: last_hard_state => 0
+
+.. note::
+   This log file will grow quickly, do not forget to add a log rotate.
+
+Use parameters
+**************
+
+The Centreon Broker log functions should be used for log only. To write into a
+file, we must use the Lua dedicated function. Moreover, it is possible to use
+parameters to define the name of the log file.
+
+So it is time to improve our Stream Connector:
+
+.. code-block:: lua
+
+  function init(conf)
+    logFile = conf['logFile']
+    broker_log:set_parameters(3, "/var/log/centreon-broker/debug.log")
+  end
+
+  function write(d)
+    for k,v in pairs(d) do
+      writeIntoFile(k .. " => " .. tostring(v) .. "\n")
+    end
+    return true
+  end
+
+  function writeIntoFile(output)
+    local file,err = io.open(logFile, 'a')
+    if file == nil then
+      broker_log:info(3, "Couldn't open file: " .. err)
+    else
+      file:write(output)
+      file:close()
+    end
+  end
+
+Did you notice that expression `local file,err = io.open(logFile, 'a')`?
+
+Lua is able to store several variables at the same time. Also, Lua functions can
+return several variables!
+
+For example, if you want to swap variables *a* and *b*, you can enter:
+
+.. code-block:: lua
+
+  a, b = b, a
+
+Another example that illustrates several values returned:
+
+.. code-block:: lua
+
+  function fib(a, b)
+    return b, a + b
+  end
+
+So, this call to **io.open** returns two variables, a first variable
+**file** that is a *file descriptor* used to access the file and a second
+variable not always defined that contains error if one occurs or **nil**
+(not defined) otherwise.
+
+The **init()** function allows to get parameters and define these from Centreon
+web interface. See technical documentation for more information. Here, we add
+the possibility to choose the destination file name. The **conf** table has
+a key *logFile* defined in the web interface. The corresponding value is
+the file name used to store events.
+
+Edit your Broker output to declare this parameter:
+
+.. image:: /_static/images/developper/lua/add_parameter.png
+   :align: center
+
+It is important that the name of the parameter in the web interface matches the
+key name in the **conf** table. Here, it is *logFile*.
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+Data are stored into **/var/log/centreon-broker/bbdo2file.log** log file as
+this::
+
+  name => error
+  category => 3
+  interval => 300
+  rrd_len => 3456000
+  value => 0
+  value_type => 0
+  type => 196612
+  ctime => 1522315660
+  index_id => 4880
+  element => 4
+  state => 0
+  category => 3
+  interval => 300
+  rrd_len => 3456000
+  is_for_rebuild => false
+  service_id => 1056
+  type => 196609
+  ctime => 1522315660
+  host_id => 145
+  element => 1
+  is_for_rebuild => false
+  metric_id => 11920
+
+Manipulate data
+***************
+
+Here, we continue to improve our stream connector by choosing what events to
+export and also by improving outputs.
+
+We will select only the NEB category and the events regarding hosts and
+services status.
+
+We know that NEB is the category 1, also service status is the sub-category 24,
+whereas host status is the sub-category 14.
+
+So, only events with the following criteria:
+
+* category = 1
+* element = 14 or element = 24
+
+are interesting for us.
+
+Moreover, we would prefer to have a host name instead of a host id and a service
+description instead of a service id.
+
+At last, we would be interested to get status information and outputs.
+
+NEB Events with elements 14 and 24 give almost all we want except host names and
+service descriptions.
+
+To get those two information, we will have to use the **broker_cache** object.
+This one is filled when pollers are restarted or reloaded. So, do not forget
+to restart your pollers if you want something in your **broker_cache** object!
+
+If the cache is well filled, it is easy to get a host name from the host id::
+
+  broker_cache:get_hostname(host_id)
+
+And it is also easy to get the service description from the host id and service
+id::
+
+  broker_cache:get_service_description(host_id, service_id)
+
+To install the filter on events, there is a useful function called **filter()**
+that takes two parameters into account: *category*, *element*.
+
+This function, if defined, is called just before **write()**. If it returns
+**true**, the **write()** function will be called, otherwise, the event will
+be thrown away.
+
+Let's complete our Lua script:
+
+.. code-block:: lua
+
+  function init(conf)
+    logFile = conf['logFile']
+    broker_log:set_parameters(3, "/var/log/centreon-broker/debug.log")
+  end
+
+  function write(d)
+    local output = ""
+
+    local host_name = broker_cache:get_hostname(d.host_id)
+    if not host_name then
+      broker_log:info(3, "Unable to get name of host, please restart centengine")
+      host_name = d.host_id
+    end
+
+    if d.element == 14 then
+      output = "HOST:" .. host_name .. ";" .. d.host_id .. ";" .. d.state .. ";" .. d.output
+      writeIntoFile(output)
+      broker_log:info(output)
+    elseif d.element == 24 then
+      local service_description = broker_cache:get_service_description(d.host_id, d.service_id)
+      if not service_description then
+        broker_log:info(3, "Unable to get description of service, please restart centengine")
+        service_description = d.service_id
+      end
+      output = "SERVICE:" .. host_name .. ";" .. d.host_id .. ";" .. service_description .. ";" .. d.service_id .. ";" .. d.state .. ";" .. d.output
+      writeIntoFile(output)
+      broker_log:info(output)
+    end
+    return true
+  end
+
+  function filter(category, element)
+    -- Get only host status and services status from NEB category
+    if category == 1 and (element == 14 or element == 24) then
+      return true
+    end
+      return false
+  end
+
+  local function writeIntoFile(output)
+    local file,err = io.open(logFile, 'a')
+    if file == nil then
+      broker_log:info(3, "Couldn't open file: " .. err)
+    else
+      file:write(output)
+      file:close()
+    end
+  end
+
+Just several remarks on this new script before showing what we get.
+
+In the **init()** function, we access the *logFile* key in the *conf* table
+by using `conf['logFile']`. Whereas, in the **write()** function, we access
+the *element* key in the *d* table by using `d.element`...
+
+In fact, the two syntaxes are allowed : `d.element` is the same value than
+`d['element']`.
+
+Another remark, in the **write()** function we can see something like::
+
+  if not host_name then
+
+And in the **writeIntoFile()** function, we can see that::
+
+  if file == nil then
+
+Do they mean the same thing? Where is the difference?
+
+You must know that in Lua, a variable is considered to be **true** if it is
+defined and not **false**:
+
+so, the following code
+
+.. code:: lua
+
+  if toto then
+    print("Good")
+  else
+    print("Bad")
+  end
+
+will write *Good* if *toto* is defined and not **false**. More precisely, it will
+write *Good* in the following cases:
+
+* toto=12
+* toto=true
+* toto="A string"
+* toto=0 (surprising!)
+
+It will write *Bad* in these cases:
+
+* toto=nil (by default a variable is nil, which means not defined)
+* toto=false
+
+The **/var/log/centreon-broker/bbdo2file.log** file will now contain::
+
+  HOST:srv-DC-djakarta;215;0;OK - srv-DC-djakarta: rta 0.061ms, lost 0%
+  SERVICE:mail-titan-gateway;92;disk-/usr;623;0;Disk /usr - used : 42.98 Go - size : 142.00 Go - percent : 30 %
+  SERVICE:mail-sun-master;87;memory-stats;535;0;Memory usage (Total 13.0GB): 0.12GB [buffer:0.00GB] [cache:0.01GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.07GB] [inactive:0.00GB] [apps:0.02GB] [unused:12.88GB]
+  SERVICE:mail-saturn-frontend;86;traffic-eth1;512;0;Traffic In : 4.73 Mb/s (4.73 %), Out : 4.79 Mb/s (4.79 %) - Total RX Bits In : 396.01 Gb, Out : 393.88 Gb
+  SERVICE:mail-saturn-frontend;86;memory-stats;515;0;Memory usage (Total 16.0GB): 8.89GB [buffer:0.43GB] [cache:0.95GB] [pages_tables:0.27GB] [mapped:0.15GB] [active:3.92GB] [inactive:0.29GB] [apps:2.88GB] [unused:7.11GB]
+  SERVICE:mail-neptune-frontend;80;traffic-eth1;392;0;Traffic In : 4.82 Mb/s (4.82 %), Out : 6.48 Mb/s (6.48 %) - Total RX Bits In : 398.40 Gb, Out : 396.44 Gb
+  HOST:srv-DC-casablanca;207;0;OK - srv-DC-casablanca: rta 2.042ms, lost 0%
+  SERVICE:mail-neptune-frontend;80;memory-stats;395;0;Memory usage (Total 9.0GB): 0.54GB [buffer:0.03GB] [cache:0.00GB] [pages_tables:0.01GB] [mapped:0.00GB] [active:0.48GB] [inactive:0.00GB] [apps:0.01GB] [unused:8.46GB]
+  SERVICE:mail-mercury-frontend;82;traffic-eth1;432;0;Traffic In : 8.28 Mb/s (8.28 %), Out : 1.23 Mb/s (1.23 %) - Total RX Bits In : 397.71 Gb, Out : 400.34 Gb
+  SERVICE:mail-mercury-frontend;82;memory-stats;435;0;Memory usage (Total 12.0GB): 1.58GB [buffer:0.00GB] [cache:0.63GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.75GB] [inactive:0.00GB] [apps:0.19GB] [unused:10.42GB]
+  SERVICE:mail-mars-frontend;84;traffic-eth1;472;0;Traffic In : 7.24 Mb/s (7.24 %), Out : 3.36 Mb/s (3.36 %) - Total RX Bits In : 399.93 Gb, Out : 395.67 Gb
+  SERVICE:mail-mars-frontend;84;memory-stats;475;0;Memory usage (Total 3.0GB): 1.19GB [buffer:0.01GB] [cache:0.59GB] [pages_tables:0.00GB] [mapped:0.00GB] [active:0.15GB] [inactive:0.04GB] [apps:0.39GB] [unused:1.81GB]
+  SERVICE:mail-jupiter-frontend;85;traffic-eth1;492;0;Traffic In : 1.41 Mb/s (1.41 %), Out : 9.08 Mb/s (9.08 %) - Total RX Bits In : 388.86 Gb, Out : 394.85 Gb
+  SERVICE:mail-jupiter-frontend;85;memory-stats;495;0;Memory usage (Total 12.0GB): 0.57GB [buffer:0.04GB] [cache:0.23GB] [pages_tables:0.02GB] [mapped:0.02GB] [active:0.07GB] [inactive:0.03GB] [apps:0.16GB] [unused:11.43GB]
+  SERVICE:mail-io-backend;88;traffic-eth1;547;0;Traffic In : 1.51 Mb/s (1.51 %), Out : 7.12 Mb/s (7.12 %) - Total RX Bits In : 389.61 Gb, Out : 390.54 Gb
+  SERVICE:mail-io-backend;88;diskio-system;551;0;Device /dev/sda: avg read 4.78 (MB/s) and write 9.08 (MB/s)
+
+
+***********************************
+Export performance data to InfluxDB
+***********************************
+
+Now, you have already seen many things about stream connectors. It is time to
+create something more useful!
+
+`InfluxDB <https://www.influxdata.com/>`_ is a Time Series database. We will use
+this storage to insert performance data collected by the Centreon platform. For
+this example, we will use the predefined `InfluxDB Docker <https://hub.docker.com/_/influxdb/>`_.
+
+To send data to InfluxDB, we need parameters to access to InfluxDB storage:
+
+* **http_server_address**: IP address of the storage
+* **http_server_port**: 8086 by default
+* **http_server_protocol**: http or https
+* **influx_database**: name of database
+* **influx_user**: user to access to database if defined
+* **influx_password**: password of user to access to database if defined
+
+In order to not saturate the storage, we will add all events in a queue and
+once its max size is reached, we will send data by bulk.
+
+We need to define the size of the queue and the maximum
+delay before sending events:
+
+* max_buffer_size
+* max_buffer_age
+
+To create this queue, we introduce a code a little more complicated. We
+construct an object **event_queue**. It is composed of parameters such as
+*events*, *influx_database* and methods like *new()*, *add()*.
+
+To understand how to create such an object in Lua, we recommend the Lua
+documentation `here for classes <https://www.lua.org/pil/16.1.html>`_
+and `there for metatables <https://www.lua.org/pil/13.html>`_.
+
+To send data to a server, we provide a **broker_tcp_socket** object.
+
+Its API is very simple (too simple?). This *socket*
+is a TCP socket, it does not support encryption and it can be tricky to send
+data in http. Here is an example:
+
+.. code-block:: lua
+
+  -- Here, we create our socket
+  local socket = broker_tcp_socket.new()
+
+  -- We establish the connection with the server
+  socket:connect(address, port)
+
+  -- Now, we can send data
+  socket:write("This is a text to send")
+
+  -- If, we want an answer, we also have a function to read
+  local content = socket:read()
+
+  -- When exchanges are finished, we can close the socket
+  socket:close()
+
+For our purpose, we do not use **broker_tcp_socket** because of its limitations.
+We want to be able to send data to an https server.
+
+A prerequisite is to install the `lua-socket library <http://w3.impa.br/~diego/software/luasocket/>`_. This library provides several functionalities, we
+need two of them:
+
+* http socket
+* ltn12
+
+To access them, Lua provides the **require** function.
+
+Let's introduce the beginning of our new Stream Connector.
+
+The queue parameters
+====================
+
+.. code-block:: lua
+
+  -- We declare the objects to import here
+  local http = require("socket.http")
+  local ltn12 = require("ltn12")
+
+  -- Here are predefined queue parameters
+  local event_queue = {
+    __internal_ts_last_flush    = nil,
+    http_server_address         = "",
+    http_server_port            = 8086,
+    http_server_protocol        = "http",
+    events                      = {},
+    influx_database             = "mydb",
+    influx_user                 = "",
+    influx_password             = "",
+    max_buffer_size             = 5000,
+    max_buffer_age              = 5
+  }
+
+
+In this table, we give default values to parameters that can possibly
+be changed during the **init()** call. This table will be used to store important
+data for the script and is also our queue object.
+
+A method to create the queue
+============================
+
+To declare this table as a Lua object, we need a constructor. So, here it is:
+
+.. code-block:: lua
+
+  -- Constructor of the event_queue
+  function event_queue:new(o, conf)
+    o = o or {}
+    setmetatable(o, self)
+    self.__index = self
+    for i,v in pairs(conf) do
+      if self[i] and i ~= "events" and string.sub(i, 1, 11) ~= "__internal_" then
+        broker_log:info(1, "event_queue:new: getting parameter " .. i .. " => " .. v)
+        self[i] = v
+      else
+        broker_log:warning(1, "event_queue:new: ignoring parameter " .. i .. " => " .. v)
+      end
+    end
+    self.__internal_ts_last_flush = os.time()
+    broker_log:info(2, "event_queue:new: setting the internal timestamp to " .. self.__internal_ts_last_flush)
+    return o
+  end
+
+.. note::
+   In this function, we use a Lua sugar "o = o or {}" that means *o* stays the
+   same if it is **true**, otherwise it is affected with an empty table `{}`.
+
+   Another point to notice is the **~=** operator that means **different from**.
+
+   And to finish on this function, the variable **self** is implicitly defined
+   when we declare an object's method. Its meaning is the same as **this** in
+   Java or in C++. It represents the object we are working on.
+
+A method to add event in queue
+==============================
+
+We have a queue object. It would be great to use it like this:
+
+.. code-block:: lua
+
+  -- We construct it
+  local queue = event_queue:new(nil, conf)
+
+  -- We add an event to it
+  queue:add(event)
+
+  -- When the queue is full, we would like to do something like this
+  queue:flush()
+
+
+Let's do it! Below, we present an **add()** method that retrieves a host name
+and service description from the cache, builds a string from the event and
+pushes it on its stack.
+
+.. code-block:: lua
+
+  function event_queue:add(e)
+    local metric = e.name
+    -- time is a reserved word in influxDB so I rename it
+    if metric == "time" then
+      metric = "_" .. metric
+    end
+
+    -- retrieve objects names instead of IDs
+    local host_name = broker_cache:get_hostname(e.host_id)
+    local service_description = broker_cache:get_service_description(e.host_id, e.service_id)
+
+    -- what if we could not get them from cache
+    if not host_name then
+      broker_log:warning(1, "event_queue:add: host_name for id " .. e.host_id .. " not found. Restarting centengine should fix this.")
+      host_name = e.host_id
+    end
+    if not service_description then
+      broker_log:warning(1, "event_queue:add: service_description for id " .. e.host_id .. "." .. e.service_id .. " not found. Restarting centengine should fix this.")
+      service_description = e.service_id
+    else
+      service_description = service_description:gsub(" ", "_")
+    end
+
+    -- we finally append the event to the events table
+    metric = metric:gsub(" ", "_")
+    broker_log:info(3, 'event_queue:add: adding  ' .. service_description .. ",host=" .. host_name .. " " .. metric .. "=" .. e.value .. " " .. e.ctime .. '000000000" to event list.')
+    self.events[#self.events + 1] = service_description .. ",host=" .. host_name .. " " .. metric .. "=" .. e.value .. " " .. e.ctime .. "000000000\n"
+
+    -- then we check whether it is time to send the events to the receiver and flush
+    if #self.events >= self.max_buffer_size then
+      broker_log:info(2, "event_queue:add: flushing because buffer size reached " .. self.max_buffer_size .. " elements.")
+      self:flush()
+      return true
+    elseif os.time() - self.__internal_ts_last_flush >= self.max_buffer_age then
+      broker_log:info(2, "event_queue:add: flushing " .. #self.events .. " elements because buffer age reached " .. (os.time() - self.__internal_ts_last_flush) .. "s and max age is " .. self.max_buffer_age .. "s.")
+      self:flush()
+      return true
+    else
+      return false
+    end
+  end
+
+A method to flush the queue
+===========================
+
+Once the events added in the queue and the maximum size of the queue or the
+timeout is reached, events will be sent to the InfluxDB storage.
+
+This function builds data from the queue and sends them to the storage. If an
+error occurs, it dumps a log error.
+
+It is here that we use the **http** and **ltn12** objects loaded at the
+beginning of the script.
+
+.. code-block:: lua
+
+  function event_queue:flush()
+    broker_log:info(2, "event_queue:flush: Concatenating all the events as one string")
+    --  we concatenate all the events
+    local http_post_data = ""
+    local http_result_body = {}
+    for i, raw_event in ipairs(self.events) do
+      http_post_data = http_post_data .. raw_event
+    end
+    broker_log:info(2, 'event_queue:flush: HTTP POST request "' .. self.http_server_protocol .. "://" .. self.http_server_address .. ":" .. self.http_server_port .. "/write?db=" .. self.influx_database .. '"')
+    broker_log:info(3, "event_queue:flush: HTTP POST data are: '" .. http_post_data .. "'")
+
+    -- build url
+    local influxdb_url = self.http_server_protocol .. "://" .. self.http_server_address .. ":" .. self.http_server_port .. "/write?db=" .. self.influx_database
+    -- add authentication if needed
+    if string.len(self.influx_user) >= 1 and string.len(self.influx_password) >= 1 then
+      influxdb_url = influxdb_url .. "&u=" .. self.influx_user .. "&p="..self.influx_password
+    end
+
+    local hr_result, hr_code, hr_header, hr_s = http.request{
+      url = influxdb_url,
+      method = "POST",
+      -- sink is where the request result's body will go
+      sink = ltn12.sink.table(http_result_body),
+      -- request body needs to be formatted as a LTN12 source
+      source = ltn12.source.string(http_post_data),
+      headers = {
+        -- mandatory for POST request with body
+        ["content-length"] = string.len(http_post_data)
+      }
+    }
+    -- Handling the return code
+    if hr_code == 204 then
+      broker_log:info(2, "event_queue:flush: HTTP POST request successful: return code is " .. hr_code)
+    else
+      broker_log:error(1, "event_queue:flush: HTTP POST request FAILED: return code is " .. hr_code)
+      for i, v in ipairs(http_result_body) do
+        broker_log:error(1, "event_queue:flush: HTTP POST request FAILED: message line " .. i .. ' is "' .. v .. '"')
+      end
+    end
+
+    -- now that the data has been sent, we empty the events array
+    self.events = {}
+    -- and update the timestamp
+    self.__internal_ts_last_flush = os.time()
+  end
+
+The init() function to get parameters and create the queue
+==========================================================
+
+In this case, the **init()** function creates the queue with parameters
+defined by users in the web interface or uses default parameters already
+defined in the queue. This alternative is managed by the queue constructor.
+
+.. code-block:: lua
+
+  function init(conf)
+    broker_log:set_parameters(1, "/var/log/centreon-broker/stream-connector-influxdb.log")
+    broker_log:info(2, "init: Beginning init() function")
+    queue = event_queue:new(nil, conf)
+    broker_log:info(2, "init: Ending init() function, Event queue created")
+  end
+
+.. note::
+
+  **queue** is not defined as local, this is important so that it is accessible
+  from all the functions.
+
+The write() function to insert events in queue
+==============================================
+
+The **write()** function is only used to insert filtered events into the queue:
+
+.. code-block:: lua
+
+  function write(e)
+    broker_log:info(3, "write: Beginning write() function")
+    queue:add(e)
+    broker_log:info(3, "write: Ending write() function\n")
+    return true
+  end
+
+The filter() function to select only performance data events
+============================================================
+
+To select only performance data, we need to select *category* 3 (“Storage”)
+and *element* 1 for *metric*:
+
+.. code-block:: lua
+
+  function filter(category, element)
+    if category == 3 and element == 1 then
+      return true
+    end
+    return false
+  end
+
+Complete script
+===============
+
+The complete script can be downloaded `here <https://github.com/centreon/centreon-stream-connector-scripts/tree/master/influxdb>`_.
+
+Configure Centreon Broker
+=========================
+
+Configure the new output into Centreon Web interface in
+**Configuration > Pollers > Broker configuration > Central Broker**.
+In **Output** tab select **Generic – Stream connector** and click **Add**:
+
+.. image:: /_static/images/developper/lua/add_stream_connector.png
+   :align: center
+
+Define the name of this output and the path to the Lua connector:
+
+.. image:: /_static/images/developper/lua/broker_influxdb_output.png
+   :align: center
+   :scale: 65%
+
+Then click **Save** and go to generate the configuration and restart **cbd**.
+
+.. note::
+   Don’t forget to restart “centengine” too to create the Centreon Broker cache.
+
+If you install the `Grafana <https://grafana.com/>`_ dashboard, you can visualize the stored data:
+
+.. image:: /_static/images/developper/lua/visualize_data_grafana.png
+   :align: center
+   :scale: 65%
+
+Discover other Centreon Stream Connectors
+=========================================
+
+Centreon provides a Github repository to host Lua scripts developed by Centreon
+and the community. Please go to the `dedicated Github <http://github.com/centreon/centreon-stream-connector-scripts>`_.
+
+Need help to develop your Stream connector? You want to share your experience with
+the community? Join the `Centreon community Slack channel <https://centreon.github.io/>`_.
+
diff --git a/doc/fr/release_notes/centreon-2.8/centreon-2.8.20.rst b/doc/fr/release_notes/centreon-2.8/centreon-2.8.20.rst
index 4cd104f88077c2f831a2abbbd076c915728038f2..b45a4a2fe55a259f0ceaa035ef907c62dcaf8b95 100644
--- a/doc/fr/release_notes/centreon-2.8/centreon-2.8.20.rst
+++ b/doc/fr/release_notes/centreon-2.8/centreon-2.8.20.rst
@@ -5,5 +5,28 @@ Centreon Web 2.8.20
 Enhancements
 ============
 
+* [API] Add default poller - PR #6098
+* [API] Link host with default poller if unknown poller - PR #6099
+* [ACL] Improve performance - #6056 PR #6107
+* [Documentation] Improve Centreon CLAPI usage - PR #6090 #6091
+* [Documentation] Improve documentation to add a new poller - #6075 PR  #6086
+* [Documentation] Add notice for 64 bits support only - PR #6101
+* [Monitoring] Display links in output and comments  - #5943 PR #6113
+
 Bug Fixes
 =========
+
+* [ACL] Allow nested groups filter in ldap configuration - #6127 PR #6128
+* [API] Export specific service, add host before service in CLAPI - PR #6100
+* [API] CLAPI add resource export filter - PR #6125
+* [API] CLAPI Export contact with contact group - PR #6131
+* [API] CLAPI Export service categories - PR #6134
+* [Configuration] SNMP trap poller generation uses ACL - #6043 PR #6069
+* [Custom Views] Fix share custom view - PR #6109
+* [Poller Stats] Poller Statistics Graphs are displayed in first column only - #6003 PR #6122
+
+Others
+======
+
+* Update copyright date on the login page - PR #6076
+* Remove multiple debug in Centreon - PR #6138
\ No newline at end of file
diff --git a/doc/fr/release_notes/centreon-2.8/centreon-2.8.21.rst b/doc/fr/release_notes/centreon-2.8/centreon-2.8.21.rst
index a74c0badd68c52365df1eaeafacba1f4e9262211..cc9ffa5012ae1c2a7ee71e299b291875b97ec8d8 100644
--- a/doc/fr/release_notes/centreon-2.8/centreon-2.8.21.rst
+++ b/doc/fr/release_notes/centreon-2.8/centreon-2.8.21.rst
@@ -5,5 +5,17 @@ Centreon Web 2.8.21
 Enhancements
 ============
 
+* [Documentation] Add chapter about how to write a stream connector - PR #6189
+* [API] Separate REST API configuration and REST API realtime access - PR #6188
+
 Bug Fixes
 =========
+
+* [ACL] Manage filters (poller, host, service) on servicegroup - PR #6163
+* [Configuration] Fix output stream connector name for fresh install - PR #6159 #6182
+* [Configuration] No "Conf changed" flag set to "yes" when deploying services to selected hosts - #6160 PR #6191
+
+Other
+=====
+
+* Fix php warning in realtime host API - PR #6174
\ No newline at end of file
diff --git a/doc/fr/release_notes/centreon-2.8/centreon-2.8.22.rst b/doc/fr/release_notes/centreon-2.8/centreon-2.8.22.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2cf9f9b79db2e7df6b1ef29d5496040ca2dfecde
--- /dev/null
+++ b/doc/fr/release_notes/centreon-2.8/centreon-2.8.22.rst
@@ -0,0 +1,14 @@
+###################
+Centreon Web 2.8.22
+###################
+
+Enhancements
+============
+
+Bug Fixes
+=========
+
+* [CLAPI] Fix host services deployment - PR #6212
+
+Other
+=====
diff --git a/doc/fr/release_notes/centreon-2.8/centreon-2.8.23.rst b/doc/fr/release_notes/centreon-2.8/centreon-2.8.23.rst
new file mode 100644
index 0000000000000000000000000000000000000000..603bb166a422992225583595a3c305ce05eefa19
--- /dev/null
+++ b/doc/fr/release_notes/centreon-2.8/centreon-2.8.23.rst
@@ -0,0 +1,32 @@
+###################
+Centreon Web 2.8.23
+###################
+
+Enhancements
+============
+
+* [API] Add default poller - PR #6098
+* [API] Link host with default poller if unknown poller - PR #6099
+* [ACL] Improve performance - #6056 PR #6107
+* [Documentation] Improve Centreon CLAPI usage - PR #6090 #6091
+* [Documentation] Improve documentation to add a new poller - #6075 PR  #6086
+* [Documentation] Add notice for 64 bits support only - PR #6101
+* [Monitoring] Display links in output and comments  - #5943 PR #6113
+
+Bug Fixes
+=========
+
+* [ACL] Allow nested groups filter in ldap configuration - #6127 PR #6128
+* [API] Export specific service, add host before service in CLAPI - PR #6100
+* [API] CLAPI add resource export filter - PR #6125
+* [API] CLAPI Export contact with contact group - PR #6131
+* [API] CLAPI Export service categories - PR #6134
+* [Configuration] SNMP trap poller generation uses ACL - #6043 PR #6069
+* [Custom Views] Fix share custom view - PR #6109
+* [Poller Stats] Poller Statistics Graphs are displayed in first column only - #6003 PR #6122
+
+Others
+======
+
+* Update copyright date on the login page - PR #6076
+* Remove multiple debug in Centreon - PR #6138
diff --git a/doc/fr/release_notes/centreon-2.8/index.rst b/doc/fr/release_notes/centreon-2.8/index.rst
index 845a9edebbf7f1848f0c03682b431022ff5054c9..1a40f83ac3110f7a40f706bb6b03d0647992f5e9 100644
--- a/doc/fr/release_notes/centreon-2.8/index.rst
+++ b/doc/fr/release_notes/centreon-2.8/index.rst
@@ -28,3 +28,5 @@ Please find here the release notes dedicated to the last 2.8.x version of Centre
     centreon-2.8.19
     centreon-2.8.20
     centreon-2.8.21
+    centreon-2.8.22
+    centreon-2.8.23
diff --git a/features/DowntimeRecurrent.feature b/features/DowntimeRecurrent.feature
new file mode 100644
index 0000000000000000000000000000000000000000..6fdc7440bea305bb78263bdef1fc3cfadadc38a9
--- /dev/null
+++ b/features/DowntimeRecurrent.feature
@@ -0,0 +1,14 @@
+Feature: Testing a recurrent Downtime
+  As a Centreon user
+  I want to be certain that the recurrent downtimes work correctly
+  To release quality products
+
+  Background:
+    Given I am logged in a Centreon server
+
+  @critical
+  Scenario: Testing a recurrent Downtime on a HostGroup without any ServiceGroup created (Bugfix)
+    Given a hostGroup is configured
+    And a recurrent downtime on a hostGroup
+    When this one gives a downtime
+    Then the recurrent downtime started
diff --git a/features/bootstrap/DowntimeRecurrentContext.php b/features/bootstrap/DowntimeRecurrentContext.php
new file mode 100644
index 0000000000000000000000000000000000000000..3957c0584296102e1af08c1d00611dcbcf58a582
--- /dev/null
+++ b/features/bootstrap/DowntimeRecurrentContext.php
@@ -0,0 +1,127 @@
+<?php
+
+use Centreon\Test\Behat\CentreonContext;
+use Centreon\Test\Behat\Configuration\ServiceConfigurationPage;
+use Centreon\Test\Behat\Configuration\DowntimeConfigurationListingPage;
+use Centreon\Test\Behat\Configuration\HostConfigurationPage;
+use Centreon\Test\Behat\Configuration\HostGroupConfigurationPage;
+use Centreon\Test\Behat\Configuration\RecurrentDowntimeConfigurationPage;
+
+/**
+ * Defines application features from the specific context.
+ */
+class DowntimeRecurrentContext extends CentreonContext
+{
+    protected $currentPage;
+    protected $startDate;
+    protected $endDate;
+
+    protected $host = array(
+        'name' => 'host',
+        'alias' => 'host',
+        'address' => 'host2@localhost',
+        'check_command' => 'check_centreon_dummy',
+        'location' => 'Europe/Paris'
+    );
+
+    protected $hostGroup = array(
+        'name' => 'hostGroupName',
+        'alias' => 'hostGroupAlias',
+        'hosts' => 'host',
+        'enabled' => 1
+    );
+
+    protected $service = array(
+        'hosts' => 'host',
+        'description' => 'service',
+        'templates' => 'generic-service',
+        'check_command' => 'check_centreon_dummy',
+        'check_period' => '24x7',
+        'max_check_attempts' => 1,
+        'normal_check_interval' => 1,
+        'retry_check_interval' => 1,
+        'active_checks_enabled' => 1,
+        'passive_checks_enabled' => 0,
+        'notifications_enabled' => 1,
+        'notify_on_recovery' => 1,
+        'notify_on_critical' => 1,
+        'recovery_notification_delay' => 1,
+        'cs' => 'admin_admin'
+    );
+
+    /**
+     * @Given a hostGroup is configured
+     */
+    public function aHostGroupIsConfigured()
+    {
+        $this->currentPage = new HostConfigurationPage($this);
+        $this->currentPage->setproperties($this->host);
+        $this->currentPage->save();
+        $this->currentPage = new HostGroupConfigurationPage($this);
+        $this->currentPage->setProperties($this->hostGroup);
+        $this->currentPage->save();
+        $this->currentPage = new ServiceConfigurationPage($this);
+        $this->currentPage->setProperties($this->service);
+        $this->currentPage->save();
+        $this->reloadAllPollers();
+    }
+
+    /**
+     * @Given a recurrent downtime on a hostGroup
+     */
+    public function aRecurrentDowntime()
+    {
+        $this->startDate = new DateTime('now');
+
+        $this->endDate = new DateTime('now');
+        $this->endDate->add(new DateInterval('PT360M'));
+
+        $this->currentPage = new RecurrentDowntimeConfigurationPage($this);
+        $this->currentPage->setProperties(array(
+            'name' => 'test_DT',
+            'alias' => 'recurrent_DT',
+            'days' => array(7, 1, 2, 3, 4, 5, 6),
+            'start' => $this->startDate->format('H:i'),
+            'end' => $this->endDate->format('H:i'),
+            'hostgroup_relation' => $this->hostGroup['name']
+        ));
+
+        $this->currentPage->save();
+    }
+
+    /**
+     * @When this one gives a downtime
+     */
+    public function thisOneGivesADowntime()
+    {
+        /* faking cron's launchtime. 2 min sooner */
+        $this->container->execute(
+            "faketime -f '-120s' php /usr/share/centreon/cron/downtimeManager.php",
+            'web'
+        );
+    }
+
+    /**
+     * @Then the recurrent downtime started
+     */
+    public function aRecurrentDowntimeIsStarted()
+    {
+        /* checking for results */
+        $this->spin(
+            function ($context) {
+                $found = false;
+                $this->currentPage = new DowntimeConfigurationListingPage($context);
+                $this->currentPage->displayDowntimeCycle();
+                foreach ($this->currentPage->getEntries() as $entry) {
+                    if ($entry['host'] == $context->host['name'] &&
+                        $entry['service'] == $context->service['description'] &&
+                        $entry['started'] == true
+                    ) {
+                        $found = true;
+                    }
+                }
+                return $found;
+            }
+        );
+    }
+}
diff --git a/tests/clapi_export/clapi-configuration.txt b/tests/clapi_export/clapi-configuration.txt
index f3a59e1d9fe1b79639c680e07b7e897175cb23da..8058ddca8cae078a8d947945d0bdf2841c184e98 100644
--- a/tests/clapi_export/clapi-configuration.txt
+++ b/tests/clapi_export/clapi-configuration.txt
@@ -708,6 +708,7 @@ CONTACTTPL;setparam;contact_template;servicenotifopt;n
 CONTACTTPL;setparam;contact_template;contact_js_effects;0
 CONTACTTPL;setparam;contact_template;timezone;
 CONTACTTPL;setparam;contact_template;reach_api;0
+CONTACTTPL;setparam;contact_template;reach_api_rt;0
 CONTACTTPL;setparam;contact_template;contact_enable_notifications;2
 CONTACTTPL;setparam;contact_template;contact_type_msg;txt
 CONTACTTPL;setparam;contact_template;contact_activate;1
@@ -717,6 +718,7 @@ CONTACTTPL;setparam;test_contact-template;servicenotifopt;n
 CONTACTTPL;setparam;test_contact-template;contact_js_effects;0
 CONTACTTPL;setparam;test_contact-template;timezone;
 CONTACTTPL;setparam;test_contact-template;reach_api;0
+CONTACTTPL;setparam;test_contact-template;reach_api_rt;0
 CONTACTTPL;setparam;test_contact-template;contact_enable_notifications;0
 CONTACTTPL;setparam;test_contact-template;contact_type_msg;txt
 CONTACTTPL;setparam;test_contact-template;contact_activate;1
@@ -780,6 +782,7 @@ CONTACT;setparam;admin;servicenotifopt;n
 CONTACT;setparam;admin;contact_js_effects;0
 CONTACT;setparam;admin;timezone;
 CONTACT;setparam;admin;reach_api;0
+CONTACT;setparam;admin;reach_api_rt;0
 CONTACT;setparam;admin;contact_enable_notifications;1
 CONTACT;setparam;admin;contact_type_msg;txt
 CONTACT;setparam;admin;contact_activate;1
@@ -793,6 +796,7 @@ CONTACT;setparam;guest;servicenotifopt;n
 CONTACT;setparam;guest;contact_js_effects;0
 CONTACT;setparam;guest;timezone;
 CONTACT;setparam;guest;reach_api;0
+CONTACT;setparam;guest;reach_api_rt;0
 CONTACT;setparam;guest;contact_enable_notifications;2
 CONTACT;setparam;guest;contact_type_msg;txt
 CONTACT;setparam;guest;contact_activate;0
@@ -806,6 +810,7 @@ CONTACT;setparam;user;servicenotifopt;n
 CONTACT;setparam;user;contact_js_effects;0
 CONTACT;setparam;user;timezone;
 CONTACT;setparam;user;reach_api;0
+CONTACT;setparam;user;reach_api_rt;0
 CONTACT;setparam;user;contact_enable_notifications;2
 CONTACT;setparam;user;contact_type_msg;txt
 CONTACT;setparam;user;contact_activate;0
@@ -817,6 +822,7 @@ CONTACT;setparam;test_contact;servicenotifopt;n
 CONTACT;setparam;test_contact;contact_js_effects;0
 CONTACT;setparam;test_contact;timezone;
 CONTACT;setparam;test_contact;reach_api;0
+CONTACT;setparam;test_contact;reach_api_rt;0
 CONTACT;setparam;test_contact;contact_enable_notifications;0
 CONTACT;setparam;test_contact;contact_type_msg;txt
 CONTACT;setparam;test_contact;contact_activate;1
@@ -826,6 +832,7 @@ CONTACT;setparam;jeanpierre;servicenotifopt;n
 CONTACT;setparam;jeanpierre;contact_js_effects;0
 CONTACT;setparam;jeanpierre;timezone;
 CONTACT;setparam;jeanpierre;reach_api;0
+CONTACT;setparam;jeanpierre;reach_api_rt;0
 CONTACT;setparam;jeanpierre;contact_enable_notifications;2
 CONTACT;setparam;jeanpierre;contact_type_msg;txt
 CONTACT;setparam;jeanpierre;contact_activate;1
diff --git a/www/Themes/Centreon-2/jquery-ui/jquery-ui-centreon.css b/www/Themes/Centreon-2/jquery-ui/jquery-ui-centreon.css
index cb996859e1f945f46703eb1d9f7dcb0daea6f75b..0de9bccc3571f4da8946e8d713c87fc758c5b4a7 100644
--- a/www/Themes/Centreon-2/jquery-ui/jquery-ui-centreon.css
+++ b/www/Themes/Centreon-2/jquery-ui/jquery-ui-centreon.css
@@ -12,7 +12,7 @@
 .ui-sortable-placeholder { visibility: hidden; }
 
 .ui-button, .ui-button:hover, .ui-button:focus {
-    padding: .2em 1em .2em .2em;
+    padding: .4em 1em;
     color: #ffffff;
     font-weight: bold;
     font-family: segoe ui, Arial, sans-serif;
@@ -57,6 +57,4 @@ iframe {
 .ui-tabs .ui-tabs-nav li a { float: left; padding: .4em 1em 0.4em .4em; text-decoration: none; background: #009fdf;}
 .ui-tabs .ui-tabs-nav li.ui-state-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text;  background: none; }
 
-
-.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .2em 1em .2em 2.1em; }
 #globalView {padding-bottom:10px;}
diff --git a/www/Themes/Centreon-2/style.css b/www/Themes/Centreon-2/style.css
index a666cc1c13b643b5dda58ca50411a8bc5fb8bb39..9be9fc4a3f245cff8d61baa81fa2c6a10803c1df 100644
--- a/www/Themes/Centreon-2/style.css
+++ b/www/Themes/Centreon-2/style.css
@@ -1756,6 +1756,10 @@ span.state_badge {
     background: transparent !important;
 }
 
+#colorbox {
+    outline: none;
+}
+
 #cboxContent {
     border-radius: 4px;
     border: 1px solid #a7a8ac;
@@ -1772,6 +1776,7 @@ span.state_badge {
     width: 18px !important;
     right: -10px !important;
     border-radius: 10px;
+    border-width: 0px;
 }
 
 /* ColorBox CSS */
diff --git a/www/api/class/centreon_administration_widget.class.php b/www/api/class/centreon_administration_widget.class.php
index 5a11d198dd9f1b89a76f3f76e562b45d970a1e66..4f6ba0a7c4ce6572e2f1945084e91990081a424c 100644
--- a/www/api/class/centreon_administration_widget.class.php
+++ b/www/api/class/centreon_administration_widget.class.php
@@ -74,4 +74,21 @@ class CentreonAdministrationWidget extends CentreonWebService
         $widgetObj = new CentreonWidget($centreon, $this->pearDB);
         return $widgetObj->getWidgetModels($q, $range);
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiConfiguration();
+    }
 }
diff --git a/www/api/class/centreon_clapi.class.php b/www/api/class/centreon_clapi.class.php
index 932b1c08b6e9f55cb8637a05d1466a87c498f6d9..53075b85e7d94df8658a86fc112afe2e28afe778 100644
--- a/www/api/class/centreon_clapi.class.php
+++ b/www/api/class/centreon_clapi.class.php
@@ -189,4 +189,21 @@ class CentreonClapi extends CentreonWebService
         }
         return $return;
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiConfiguration();
+    }
 }
diff --git a/www/api/class/centreon_configuration_objects.class.php b/www/api/class/centreon_configuration_objects.class.php
index 55ef93672431546fb0ffca3bc152744398cba883..6d3e4685fdbf563464cbe97ef1b6d99e30d1a252 100644
--- a/www/api/class/centreon_configuration_objects.class.php
+++ b/www/api/class/centreon_configuration_objects.class.php
@@ -270,4 +270,21 @@ class CentreonConfigurationObjects extends CentreonWebService
         }
         return $tmpValues;
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiConfiguration();
+    }
 }
diff --git a/www/api/class/centreon_home_customview.class.php b/www/api/class/centreon_home_customview.class.php
index 84b7fa4a5cb73b57b10e1100627b00ee64509dc0..3aa5d7b4611c6b8a57daaad0ae6bd12fda0fa540 100644
--- a/www/api/class/centreon_home_customview.class.php
+++ b/www/api/class/centreon_home_customview.class.php
@@ -163,4 +163,17 @@ class CentreonHomeCustomview extends CentreonWebService
             'tabs' => $tabs
         );
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        return true;
+    }
 }
diff --git a/www/api/class/centreon_keepalive.class.php b/www/api/class/centreon_keepalive.class.php
index e055763456be612007242fa8759eef929de8bd17..bc1b9d15d808bd2e7f47b620de7a820e1dfbec99 100644
--- a/www/api/class/centreon_keepalive.class.php
+++ b/www/api/class/centreon_keepalive.class.php
@@ -50,7 +50,7 @@ class CentreonKeepalive extends CentreonWebService
     {
         parent::__construct();
     }
-    
+
     /**
      * Keep alive
      */
@@ -59,4 +59,17 @@ class CentreonKeepalive extends CentreonWebService
         $session = new CentreonSession();
         $session->updateSession($this->pearDB);
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        return true;
+    }
 }
diff --git a/www/api/class/centreon_metric.class.php b/www/api/class/centreon_metric.class.php
index 1ae1cc4b73f95eabe4ad825f55acec3a9b1d1a6e..5ca9701cd89ffb15bf4a645e9e2e1643ec348fb1 100644
--- a/www/api/class/centreon_metric.class.php
+++ b/www/api/class/centreon_metric.class.php
@@ -675,4 +675,17 @@ class CentreonMetric extends CentreonWebService
         }
         return $periods;
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        return true;
+    }
 }
diff --git a/www/api/class/centreon_proxy.class.php b/www/api/class/centreon_proxy.class.php
index a2a5ffef4aeb5fd53a896d283b688593a76c1783..13980cfbad9c6da31e383baf1deebb7ff6bfa67a 100644
--- a/www/api/class/centreon_proxy.class.php
+++ b/www/api/class/centreon_proxy.class.php
@@ -26,4 +26,17 @@ class CentreonProxy extends CentreonWebService
             'message' => $message
         );
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        return true;
+    }
 }
diff --git a/www/api/class/centreon_realtime_base.class.php b/www/api/class/centreon_realtime_base.class.php
index 30637ed1583f82abe11300be1190cbb21faff995..f2a589789fd4579df1151f445821080e164db01b 100644
--- a/www/api/class/centreon_realtime_base.class.php
+++ b/www/api/class/centreon_realtime_base.class.php
@@ -247,4 +247,21 @@ class CentreonRealtimeBase extends CentreonWebService
         }
         return $tmpValues;
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiRealtime();
+    }
 }
diff --git a/www/api/class/centreon_results_acceptor.class.php b/www/api/class/centreon_results_acceptor.class.php
index 999fadcf66b858e983210bafb9aca6df19af3457..d80a32ba82fd84d4bc5b928511d651a960329ad0 100644
--- a/www/api/class/centreon_results_acceptor.class.php
+++ b/www/api/class/centreon_results_acceptor.class.php
@@ -66,7 +66,7 @@ class CentreonResultsAcceptor extends CentreonConfigurationObjects
     }
 
     /*
-     * Get poller Listing 
+     * Get poller Listing
      */
     private function getPollers()
     {
@@ -236,4 +236,21 @@ class CentreonResultsAcceptor extends CentreonConfigurationObjects
             throw new RestBadRequestException('Bad arguments - Cannot find command list');
         }
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiConfiguration();
+    }
 }
diff --git a/www/api/class/centreon_wiki.class.php b/www/api/class/centreon_wiki.class.php
index e669a6fa2032bdb5d4f142f1dd48231e1e10ca4e..675118177dab0e4d343ebf6fd4a6145826ee3c8a 100644
--- a/www/api/class/centreon_wiki.class.php
+++ b/www/api/class/centreon_wiki.class.php
@@ -78,4 +78,21 @@ class CentreonWiki extends CentreonWebService
             'result' => $result
         );
     }
+
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal)
+    {
+        if (parent::authorize($action, $user, $isInternal)) {
+            return true;
+        }
+
+        return $user->hasAccessRestApiConfiguration();
+    }
 }
diff --git a/www/api/class/webService.class.php b/www/api/class/webService.class.php
index a6244a46c2a84d23496de232d7088e8aa798739a..169385ce837abcfe0920772f6f01e9aea43750bc 100644
--- a/www/api/class/webService.class.php
+++ b/www/api/class/webService.class.php
@@ -121,6 +121,23 @@ class CentreonWebService
         }
     }
 
+    /**
+     * Authorize to access to the action
+     *
+     * @param string $action The action name
+     * @param array $user The current user
+     * @param boolean $isInternal If the api is call in internal
+     * @return boolean If the user has access to the action
+     */
+    public function authorize($action, $user, $isInternal = false)
+    {
+        if ($isInternal || $user->admin) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Get webservice
      *
@@ -220,8 +237,11 @@ class CentreonWebService
      * Route the webservice to the good method
      * @global string _CENTREON_PATH_
      * @global type $pearDB3
+     *
+     * @param CentreonUser $user The current user
+     * @param boolean $isInternal If the Rest API call is internal
      */
-    public static function router()
+    public static function router($user, $isInternal = false)
     {
         global $pearDB;
 
@@ -260,6 +280,10 @@ class CentreonWebService
             static::sendJson("Method not found", 404);
         }
 
+        if (false === $wsObj->authorize($action, $user, $isInternal)) {
+            static::sendJson('Forbidden', 403);
+        }
+
         /* Execute the action */
         try {
             static::updateTokenTtl();
diff --git a/www/api/index.php b/www/api/index.php
index 1249620ab7e5c11e9bd140bf2c774c8bf169e70b..101b470335c30d26d7677cca260d4722e1cc6de1 100644
--- a/www/api/index.php
+++ b/www/api/index.php
@@ -50,11 +50,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' &&
     if (false === isset($_POST['username']) || false === isset($_POST['password'])) {
         CentreonWebService::sendJson("Bad parameters", 400);
     }
-    
+
     /* @todo Check if user already have valid token */
     require_once _CENTREON_PATH_ . "/www/class/centreonLog.class.php";
     require_once _CENTREON_PATH_ . "/www/class/centreonAuth.class.php";
-    
+
     /* Authenticate the user */
     $log = new CentreonUserLog(0, $pearDB);
     $auth = new CentreonAuth($_POST['username'], $_POST['password'], 0, $pearDB, $log, 1, "", "API");
@@ -62,10 +62,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' &&
         CentreonWebService::sendJson("Bad credentials", 403);
         exit();
     }
-    
+
     /* Check if user exists in contact table */
     $reachAPI = 0;
-    $res = $pearDB->prepare("SELECT contact_id, reach_api, contact_admin FROM contact WHERE contact_activate = '1' AND contact_register = '1' AND contact_alias = ?");
+    $res = $pearDB->prepare("SELECT contact_id, reach_api, reach_api_rt, contact_admin
+        FROM contact
+        WHERE contact_activate = '1' AND contact_register = '1' AND contact_alias = ?");
     $res = $pearDB->execute($res, array($_POST['username']));
     while ($data = $res->fetchRow()) {
       if (isset($data['contact_admin']) && $data['contact_admin'] == 1) {
@@ -73,6 +75,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' &&
         } else {
             if (isset($data['reach_api']) && $data['reach_api'] == 1) {
                $reachAPI = 1;
+            } else if (isset($data['reach_api_rt']) && $data['reach_api_rt'] == 1) {
+                $reachAPI = 1;
             }
         }
     }
@@ -111,4 +115,4 @@ if (is_null($userInfos)) {
 $centreon = new Centreon($userInfos);
 $oreon = $centreon;
 
-CentreonWebService::router();
+CentreonWebService::router($centreon->user);
diff --git a/www/api/internal.php b/www/api/internal.php
index 6f39d44a060dcad1d7087092419185ef24034a1c..ea803510138100fb923c7717ace93bbcd8296ed9 100644
--- a/www/api/internal.php
+++ b/www/api/internal.php
@@ -64,4 +64,4 @@ if (false === isset($centreon) || false === is_object($centreon)) {
     CentreonWebService::sendJson("Unauthorized", 401);
 }
 
-CentreonWebService::router();
+CentreonWebService::router($centreon->user, true);
diff --git a/www/class/centreon-clapi/centreonContact.class.php b/www/class/centreon-clapi/centreonContact.class.php
index 9adf7eed8b7545f6b0c8708125fa391eafe27021..4e2b75f4d6d63688a2ee15d86f2fe47a8bb4e233 100644
--- a/www/class/centreon-clapi/centreonContact.class.php
+++ b/www/class/centreon-clapi/centreonContact.class.php
@@ -367,7 +367,7 @@ class CentreonContact extends CentreonObject
                         }
                     }
                 }
-                if ($params[1] != 'reach_api' && $params[1] != 'default_page' && $params[1] != 'ar_id') {
+                if ($params[1] != 'reach_api' && $params[1] != 'reach_api_rt' && $params[1] != 'default_page' && $params[1] != 'ar_id') {
                     $params[1] = "contact_" . $params[1];
                 }
             }
diff --git a/www/class/centreon-clapi/centreonHost.class.php b/www/class/centreon-clapi/centreonHost.class.php
index bc4d71b56b001e5b8a9a5d6e593cdef4be61631b..df33a299beb1c564ee85979723882a2831fac286 100644
--- a/www/class/centreon-clapi/centreonHost.class.php
+++ b/www/class/centreon-clapi/centreonHost.class.php
@@ -898,11 +898,20 @@ class CentreonHost extends CentreonObject
                 );
                 $result = $res->fetchAll();
                 if (!count($result)) {
-                    $svcId = $svcObj->insert(array('service_description' => $params['service_alias'],
+                    $serviceDesc = array('service_description' => $params['service_alias'],
                         'service_activate' => '1',
                         'service_register' => '1',
-                        'service_template_model_stm_id' => $serviceTemplateId));
+                        'service_template_model_stm_id' => $serviceTemplateId);
+                    $svcId = $svcObj->insert($serviceDesc);
                     $hostSvcRel->insert($hostId, $svcId);
+                    $serviceDesc['service_hPars'] = $hostId;
+                    $this->addAuditLog(
+                        'a',
+                        $svcId,
+                        $params['service_alias'],
+                        $serviceDesc,
+                        'SERVICE'
+                    );
                     $svcExtended->insert(array($svcExtended->getUniqueLabelField() => $svcId));
                 }
                 unset($res);
diff --git a/www/class/centreon-clapi/centreonObject.class.php b/www/class/centreon-clapi/centreonObject.class.php
index d6d5673a856fa6c697b153e6f6917108420a342d..34f6e05a892488e9e29c1ba2102bf8dca9166ba6 100644
--- a/www/class/centreon-clapi/centreonObject.class.php
+++ b/www/class/centreon-clapi/centreonObject.class.php
@@ -424,10 +424,11 @@ abstract class CentreonObject
      * @param int $objId
      * @param string $objName
      * @param array $objValues
+     * @param string|null $objectType - The object type to log if is null use the object type of the class
      */
-    public function addAuditLog($actionType, $objId, $objName, $objValues = array())
+    public function addAuditLog($actionType, $objId, $objName, $objValues = array(), $objectType = null)
     {
-        $objType = strtoupper($this->action);
+        $objType = is_null($objectType) ? strtoupper($this->action) : $objectType;
         $objectTypes = array(
             'HTPL' => 'host',
             'STPL' => 'service',
diff --git a/www/class/centreonDowntime.class.php b/www/class/centreonDowntime.class.php
index 7059f9c1d6293f156a4f2369b3a073fd435599fc..887d9dea43c08203d2a65e6044ad8bf9039b0c06 100644
--- a/www/class/centreonDowntime.class.php
+++ b/www/class/centreonDowntime.class.php
@@ -360,7 +360,7 @@ class CentreonDowntime
             . 'dtp.dtp_month_cycle, dtp.dtp_day_of_month, dtp.dtp_fixed, dtp.dtp_duration, '
             . 'h.host_id, h.host_name, NULL as service_id, NULL as service_description '
             . 'FROM downtime_period dtp, downtime dt, '
-            . 'downtime_hostgroup_relation dhr, servicegroup sg, '
+            . 'downtime_hostgroup_relation dhr, '
             . 'host h, hostgroup_relation hgr '
             . 'WHERE dtp.dt_id = dhr.dt_id '
             . 'AND dtp.dt_id = dt.dt_id '
diff --git a/www/class/centreonHost.class.php b/www/class/centreonHost.class.php
index d32d9347d8ee322900f4da2c1781e3105e39003e..7711b5b066b96ba6aea2306df41ef17693e35627 100755
--- a/www/class/centreonHost.class.php
+++ b/www/class/centreonHost.class.php
@@ -36,6 +36,7 @@
 require_once _CENTREON_PATH_ . 'www/class/centreonInstance.class.php';
 require_once _CENTREON_PATH_ . 'www/class/centreonService.class.php';
 require_once _CENTREON_PATH_ . 'www/class/centreonCommand.class.php';
+require_once _CENTREON_PATH_ . 'www/class/centreonLogAction.class.php';
 
 /*
  *  Class that contains various methods for managing hosts
@@ -1743,6 +1744,8 @@ class CentreonHost
      */
     public function deployServices($hostId, $hostTemplateId = null)
     {
+        global $centreon;
+
         if (!isset($hostTemplateId)) {
             $id = $hostId;
         } else {
@@ -1778,15 +1781,17 @@ class CentreonHost
                 $res = $this->db->execute($stmt, $queryValues);
 
                 if (!$res->numRows()) {
-                    $svcId = $this->serviceObj->insert(
-                        array(
-                            'service_description' => $service['service_alias'],
-                            'service_activate' => array('service_activate' => '1'),
-                            'service_register' => '1',
-                            'service_template_model_stm_id' => $serviceTemplateId
-                        )
+                    $serviceDesc = array(
+                        'service_description' => $service['service_alias'],
+                        'service_activate' => array('service_activate' => '1'),
+                        'service_register' => '1',
+                        'service_template_model_stm_id' => $serviceTemplateId,
+                        'service_hPars' => $hostId
                     );
 
+                    $svcId = $this->serviceObj->insert($serviceDesc);
+                    $fields = CentreonLogAction::prepareChanges($serviceDesc);
+                    $centreon->CentreonLogAction->insertLog("service", $svcId, CentreonDB::escape($service['service_alias']), "a", $fields);
                     $this->insertRelHostService($hostId, $svcId);
                 }
                 unset($res);
diff --git a/www/class/centreonPurgeEngine.class.php b/www/class/centreonPurgeEngine.class.php
index 6f02b21cc0692ade8041a9532812abd17b92ba93..77fcca65bb5f7d2b79eccb6c17393b7eb63f5f60 100644
--- a/www/class/centreonPurgeEngine.class.php
+++ b/www/class/centreonPurgeEngine.class.php
@@ -165,7 +165,7 @@ class CentreonPurgeEngine
         $request .= "AND TABLE_SCHEMA='" . dbcstg . "' ";
         $request .= "AND CONVERT(PARTITION_DESCRIPTION, SIGNED INTEGER) IS NOT NULL ";
         $request .= "AND CONVERT(PARTITION_DESCRIPTION, SIGNED INTEGER) < " . $this->tablesToPurge[$table]['retention'] . " ";
-        $request .= "AND CONVERT(PARTITION_DESCRIPTION, SIGNED INTEGER) NOT LIKE 'pmax' ";
+        $request .= "AND PARTITION_NAME NOT LIKE 'pmax' ";
         
         $DBRESULT = $this->dbCentstorage->query($request);
         if (PEAR::isError($DBRESULT)) {
diff --git a/www/class/centreonUser.class.php b/www/class/centreonUser.class.php
index c9af2e59f368a589508daae317dc90754b40b21a..8578b57cd2d1dd39491cc874dc07e24dbfc51297 100644
--- a/www/class/centreonUser.class.php
+++ b/www/class/centreonUser.class.php
@@ -59,7 +59,10 @@ class CentreonUser
 	var $userCrypted;
     protected $token;
     public $default_page;
-        
+
+    protected $restApi;
+    protected $restApiRt;
+
 	# User LCA
 	# Array with elements ID for loop test
 	var $lcaTopo;
@@ -68,7 +71,7 @@ class CentreonUser
 	var $lcaTStr;
 
     /**
-     * 
+     *
      * @global type $pearDB
      * @param type $user
      */
@@ -101,10 +104,16 @@ class CentreonUser
          */
         $this->log = new CentreonUserLog($this->user_id, $pearDB);
         $this->userCrypted = md5($this->alias);
+
+        /**
+         * Init rest api auth
+         */
+        $this->restApi = isset($user['reach_api']) && $user['reach_api'] == 1;
+        $this->restApiRt = isset($user['reach_api_rt']) && $user['reach_api_rt'] == 1;
     }
 
     /**
-     * 
+     *
      * @global type $pearDB
      * @param type $div_name
      * @return int
@@ -124,7 +133,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $pearDB
      * @return int
      */
@@ -140,10 +149,10 @@ class CentreonUser
         $DBRESULT->free();
         return $lcaTopo;
     }
-    
+
     /**
      * Check if user is admin or had ACL
-     * 
+     *
      * @param type $sid
      * @param type $pearDB
      */
@@ -175,7 +184,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_name()
@@ -184,7 +193,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_email()
@@ -193,7 +202,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_alias()
@@ -202,7 +211,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_version()
@@ -211,7 +220,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_lang()
@@ -220,7 +229,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_passwd()
@@ -229,7 +238,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function get_admin()
@@ -238,7 +247,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function is_admin()
@@ -247,7 +256,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @global type $pearDB
      * @return type
      */
@@ -264,11 +273,11 @@ class CentreonUser
 
         return $this->js_effects;
     }
-  
+
   // Set
 
     /**
-     * 
+     *
      * @param type $id
      */
     function set_id($id)
@@ -277,7 +286,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $name
      */
     function set_name($name)
@@ -286,7 +295,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $email
      */
     function set_email($email)
@@ -295,7 +304,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $lang
      */
     function set_lang($lang)
@@ -304,7 +313,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $alias
      */
     function set_alias($alias)
@@ -313,7 +322,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $version
      */
     function set_version($version)
@@ -322,7 +331,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @param type $js_effects
      */
     function set_js_effects($js_effects)
@@ -331,7 +340,7 @@ class CentreonUser
     }
 
     /**
-     * 
+     *
      * @return type
      */
     function getMyGMT()
@@ -437,7 +446,7 @@ class CentreonUser
             . 'WHERE cp_contact_id = ? '
             . 'AND  cp_key IN( ';
         $queryValues[] = $this->user_id;
-        
+
         $queryKey ='';
         foreach ($keys as $key) {
             $queryKey .=' ?,';
@@ -445,14 +454,14 @@ class CentreonUser
         }
         $queryKey = rtrim($queryKey, ',');
         $deleteQuery .= $queryKey. ' )';
-        
+
         $stmt = $db->prepare($deleteQuery);
         $res = $db->execute($stmt, $queryValues);
-        
+
         if (PEAR::isError($res)) {
             throw new Exception('Bad Request');
         }
-       
+
         $insertQuery = 'INSERT INTO contact_param (cp_key, cp_value, cp_contact_id) VALUES (?, ?, ?)';
         $stmt = $db->prepare($insertQuery);
         foreach ($parameters as $key => $value) {
@@ -460,20 +469,20 @@ class CentreonUser
             $db->execute($stmt, $sqlParams);
         }
     }
-  
+
   /**
    * Get token
-   * 
+   *
    * @return string
    */
     public function getToken()
     {
         return $this->token;
     }
-  
+
   /**
    * Set token
-   * 
+   *
    * @param string $token
    * @return void
    */
@@ -481,4 +490,20 @@ class CentreonUser
     {
         $this->token = $token;
     }
+
+    /**
+     * If the user has access to Rest API Configuration
+     */
+    public function hasAccessRestApiConfiguration()
+    {
+        return $this->restApi;
+    }
+
+    /**
+     * If the user has access to Rest API Realtime
+     */
+    public function hasAccessRestApiRealtime()
+    {
+        return $this->restApiRt;
+    }
 }
diff --git a/www/include/common/javascript/jquery/plugins/pagination/jquery.pagination.js b/www/include/common/javascript/jquery/plugins/pagination/jquery.pagination.js
index a20d0ed5d312d439f4a656a99d120e9ba461e34e..9ab06ea5db3e642bce47d6b4dfe028e869b0c4be 100644
--- a/www/include/common/javascript/jquery/plugins/pagination/jquery.pagination.js
+++ b/www/include/common/javascript/jquery/plugins/pagination/jquery.pagination.js
@@ -242,6 +242,8 @@
         if (opts.load_first_page) {
             opts.callback(current_page, containers);
         }
+
+        return this;
     }; // End of jQuery.fn.pagination block
 
 })(jQuery);
\ No newline at end of file
diff --git a/www/include/common/javascript/jquery/plugins/toggleClick/jquery.toggleClick.js b/www/include/common/javascript/jquery/plugins/toggleClick/jquery.toggleClick.js
new file mode 100644
index 0000000000000000000000000000000000000000..57bccd8f1d84f0076b21c9e87000df9c140010ec
--- /dev/null
+++ b/www/include/common/javascript/jquery/plugins/toggleClick/jquery.toggleClick.js
@@ -0,0 +1,13 @@
+(function($) {
+    $.fn.toggleClick = function(){
+
+        var functions = arguments ;
+
+        return this.click(function(){
+                var iteration = $(this).data('iteration') || 0;
+                functions[iteration].apply(this, arguments);
+                iteration = (iteration + 1) % functions.length ;
+                $(this).data('iteration', iteration);
+        });
+    };
+})(jQuery);
\ No newline at end of file
diff --git a/www/include/configuration/configObject/contact/DB-Func.php b/www/include/configuration/configObject/contact/DB-Func.php
index 9d059544b3128e41fcdcf43d2f628e042453f8a8..29caaf98c9b95ae629ab3e3266abeb5e0f3bedc6 100644
--- a/www/include/configuration/configObject/contact/DB-Func.php
+++ b/www/include/configuration/configObject/contact/DB-Func.php
@@ -56,7 +56,7 @@ function testContactExistence($name = null)
 
     $DBRESULT = $pearDB->query("SELECT contact_name, contact_id FROM contact WHERE contact_name = '" . htmlentities($centreon->checkIllegalChar($name), ENT_QUOTES, "UTF-8") . "'");
     $contact = $DBRESULT->fetchRow();
-   
+
     if ($DBRESULT->numRows() >= 1 && $contact["contact_id"] == $id) {
         return true;
     } elseif ($DBRESULT->numRows() >= 1 && $contact["contact_id"] != $id) {
@@ -81,7 +81,7 @@ function testAliasExistence($alias = null)
 
     $DBRESULT = $pearDB->query("SELECT contact_alias, contact_id FROM contact WHERE contact_alias = '" . htmlentities($alias, ENT_QUOTES, "UTF-8") . "'");
     $contact = $DBRESULT->fetchRow();
-    
+
     if ($DBRESULT->numRows() >= 1 && $contact["contact_id"] == $id) {
         return true;
     } elseif ($DBRESULT->numRows() >= 1 && $contact["contact_id"] != $id) {
@@ -123,10 +123,10 @@ function keepOneContactAtLeast($ct_id = null)
     /*
      * Get activated contacts
      */
-    $DBRESULT = $pearDB->query("SELECT COUNT(*) AS nbr_valid 
-            FROM contact 
-            WHERE contact_activate = '1' 
-            AND contact_oreon = '1' 
+    $DBRESULT = $pearDB->query("SELECT COUNT(*) AS nbr_valid
+            FROM contact
+            WHERE contact_activate = '1'
+            AND contact_oreon = '1'
             AND contact_id <> '" . $pearDB->escape($contact_id) . "'");
     $contacts = $DBRESULT->fetchRow();
 
@@ -157,7 +157,7 @@ function enableContactInDB($contact_id = null, $contact_arr = array())
 
     foreach ($contact_arr as $key => $value) {
         $DBRESULT = $pearDB->query("UPDATE contact SET contact_activate = '1' WHERE contact_id = '" . intval($key). "'");
-        
+
         $DBRESULT2 = $pearDB->query("SELECT contact_name FROM `contact` WHERE `contact_id` = '" . intval($key) . "' LIMIT 1");
         $row = $DBRESULT2->fetchRow();
 
@@ -185,10 +185,10 @@ function disableContactInDB($contact_id = null, $contact_arr = array())
     foreach ($contact_arr as $key => $value) {
         if (keepOneContactAtLeast($key)) {
             $pearDB->query("UPDATE contact SET contact_activate = '0' WHERE contact_id = '" . intval($key) . "'");
-            
+
             $DBRESULT2 = $pearDB->query("SELECT contact_name FROM `contact` WHERE `contact_id` = '" . intval($key) . "' LIMIT 1");
             $row = $DBRESULT2->fetchRow();
-            
+
             $centreon->CentreonLogAction->insertLog("contact", $key, $row['contact_name'], "disable");
         }
     }
@@ -311,11 +311,11 @@ function multipleContactInDB($contacts = array(), $nbrDup = array())
 function updateContactInDB($contact_id = null, $from_MC = false)
 {
     global $form;
-    
+
     if (!$contact_id) {
         return;
     }
-    
+
     $ret = $form->getSubmitValues();
     # Global function to use
     if ($from_MC) {
@@ -395,7 +395,8 @@ function insertContact($ret = array())
             "`contact_id` , `timeperiod_tp_id` , `timeperiod_tp_id2` , `contact_name` , " .
             "`contact_alias` , `contact_autologin_key` , `contact_passwd` , `contact_lang` , `contact_template_id`, " .
             "`contact_host_notification_options` , `contact_service_notification_options` , " .
-            "`contact_email` , `contact_pager` , `contact_comment` , `contact_oreon`, `reach_api`, `contact_register`, `contact_enable_notifications` , " .
+            "`contact_email` , `contact_pager` , `contact_comment` , `contact_oreon`, `reach_api`, `reach_api_rt`, " .
+            "`contact_register`, `contact_enable_notifications` , " .
             "`contact_admin` , `contact_type_msg`, `contact_activate`, `contact_auth_type`, " .
             "`contact_ldap_dn`, `contact_location`, `contact_address1`, `contact_address2`, " .
             "`contact_address3`, `contact_address4`, `contact_address5`, `contact_address6`)" .
@@ -439,6 +440,9 @@ function insertContact($ret = array())
         isset($ret["contact_oreon"]["contact_oreon"]) && $ret["contact_oreon"]["contact_oreon"] != null ? $rq .= "'" . $ret["contact_oreon"]["contact_oreon"] . "', " : $rq .= " '1', ";
     }
     isset($ret["reach_api"]["reach_api"]) && $ret["reach_api"]["reach_api"] != null ? $rq .= $ret["reach_api"]["reach_api"] . ", " : $rq .= " 0, ";
+    isset($ret["reach_api_rt"]["reach_api_rt"]) && $ret["reach_api_rt"]["reach_api_rt"] != null
+        ? $rq .= $ret["reach_api_rt"]["reach_api_rt"] . ", "
+        : $rq .= " 0, ";
     isset($ret["contact_register"]) && $ret["contact_register"] != null ? $rq .= "'" . $ret["contact_register"] . "', " : $rq .= " '1', ";
     isset($ret["contact_enable_notifications"]["contact_enable_notifications"]) && $ret["contact_enable_notifications"]["contact_enable_notifications"] != null ? $rq .= "'" . $ret["contact_enable_notifications"]["contact_enable_notifications"] . "', " : $rq .= "NULL, ";
     isset($ret["contact_admin"]["contact_admin"]) && $ret["contact_admin"]["contact_admin"] != null ? $rq .= "'" . $ret["contact_admin"]["contact_admin"] . "', " : $rq .= "'0', ";
@@ -468,7 +472,7 @@ function insertContact($ret = array())
             $ret["contact_passwd"] = $ret["contact_passwd2"] = $utilsObject->encodePass($ret["contact_passwd"], 'md5');
         }
     }
-    
+
     /* Prepare value for changelog */
     $fields = CentreonLogAction::prepareChanges($ret);
     $centreon->CentreonLogAction->insertLog("contact", $contact_id["MAX(contact_id)"], $ret["contact_name"], "a", $fields);
@@ -495,7 +499,7 @@ function updateContact($contact_id = null, $from_MC = false)
     $rq .= "timeperiod_tp_id2 = ";
     isset($ret["timeperiod_tp_id2"]) && $ret["timeperiod_tp_id2"] != null ? $rq .= "'" . $ret["timeperiod_tp_id2"] . "', " : $rq .= "NULL, ";
     # If we are doing a MC, we don't have to set name and alias field
-    
+
     if (!$from_MC) {
         $rq .= "contact_name = ";
         isset($ret["contact_name"]) && $ret["contact_name"] != null ? $rq .= "'" . $ret["contact_name"] . "', " : $rq .= "NULL, ";
@@ -531,6 +535,10 @@ function updateContact($contact_id = null, $from_MC = false)
     isset($ret["contact_oreon"]["contact_oreon"]) && $ret["contact_oreon"]["contact_oreon"] != null ? $rq .= "'" . $ret["contact_oreon"]["contact_oreon"] . "', " : $rq .= "NULL, ";
     $rq .= "reach_api = ";
     isset($ret["reach_api"]["reach_api"]) && $ret["reach_api"]["reach_api"] != null ? $rq .= "'" . $ret["reach_api"]["reach_api"] . "', " : $rq .= "NULL, ";
+    $rq .= "reach_api_rt = ";
+    isset($ret["reach_api_rt"]["reach_api_rt"]) && $ret["reach_api_rt"]["reach_api_rt"] != null
+        ? $rq .= "'" . $ret["reach_api_rt"]["reach_api_rt"] . "', "
+        : $rq .= "NULL, ";
     $rq .= "contact_enable_notifications = ";
     isset($ret["contact_enable_notifications"]["contact_enable_notifications"]) && $ret["contact_enable_notifications"]["contact_enable_notifications"] != null ? $rq .= "'" . $ret["contact_enable_notifications"]["contact_enable_notifications"] . "', " : $rq .= "NULL, ";
     $rq .= "contact_admin = ";
@@ -566,7 +574,7 @@ function updateContact($contact_id = null, $from_MC = false)
     if (isset($ret["contact_lang"]) && $ret["contact_lang"] != null && $contact_id == $centreon->user->get_id()) {
         $centreon->user->set_lang($ret["contact_lang"]);
     }
-    
+
     if (isset($ret["contact_passwd"])) {
         if ($encryptType == 1) {
             $ret["contact_passwd"] = $ret["contact_passwd2"] = $utilsObject->encodePass($ret["contact_passwd"], 'md5');
@@ -585,13 +593,13 @@ function updateContact($contact_id = null, $from_MC = false)
 function updateContact_MC($contact_id = null)
 {
     global $form, $pearDB, $centreon, $encryptType;
-    
+
     if (!$contact_id) {
         return;
     }
 
     $utilsObject = new CentreonUtils();
-    
+
     $ret = array();
     $ret = $form->getSubmitValues();
     $rq = "UPDATE contact SET ";
@@ -684,7 +692,7 @@ function updateContact_MC($contact_id = null)
 
         $DBRESULT2 = $pearDB->query("SELECT contact_name FROM `contact` WHERE contact_id='" . intval($contact_id) . "' LIMIT 1");
         $row = $DBRESULT2->fetchRow();
-        
+
         /* Prepare value for changelog */
         $fields = CentreonLogAction::prepareChanges($ret);
         $centreon->CentreonLogAction->insertLog("contact", $contact_id, $row["contact_name"], "mc", $fields);
@@ -694,7 +702,7 @@ function updateContact_MC($contact_id = null)
 function updateContactHostCommands($contact_id = null, $ret = array())
 {
     global $form, $pearDB;
-    
+
     if (!$contact_id) {
         return;
     }
@@ -869,7 +877,7 @@ function insertLdapContactInDB($tmpContacts = array())
         }
         $tmpContacts["contact_name"][$select_key] = str_replace(array(" ", ","), array("_", "_"), $tmpContacts["contact_name"][$select_key]);
         $arId = $tmpContacts["ar_id"][$select_key];
-        
+
         if (isset($tmpContacts["contact_name"][$select_key]) && testContactExistence($tmpContacts["contact_name"][$select_key])) {
             $tmpConf["contact_name"] = $tmpContacts["contact_name"][$select_key];
             $tmpConf["contact_alias"] = $tmpContacts["contact_alias"][$select_key];
diff --git a/www/include/configuration/configObject/contact/formContact.ihtml b/www/include/configuration/configObject/contact/formContact.ihtml
index 9fc82171495f3e5005f7aafb9dad24a400a222d6..6291be53ddcd6f73e81a536290a28d8a8b9cd04e 100644
--- a/www/include/configuration/configObject/contact/formContact.ihtml
+++ b/www/include/configuration/configObject/contact/formContact.ihtml
@@ -33,7 +33,7 @@
         <tr class="list_two"><td class="FormRowField"><img class="helpTooltip" name="email"> {$form.contact_email.label}</td><td class="FormRowValue">{$form.contact_email.html}</td></tr>
         <tr class="list_one"><td class="FormRowField"><img class="helpTooltip" name="pager"> {$form.contact_pager.label}</td><td class="FormRowValue">{$form.contact_pager.html}</td></tr>
         <tr class="list_two"><td class="FormRowField"><img class="helpTooltip" name="pager"> {$form.contact_template_id.label}</td><td class="FormRowValue">{$form.contact_template_id.html}</td></tr>
-        
+
         <tr class="list_lvl_1">
             <td class="ListColLvl1_name" colspan="2">
                 <h4>{$form.header.groupLinks}</h4>
@@ -118,6 +118,13 @@
         {if $displayAdminFlag == 1}
         <tr class="list_two"><td class="FormRowField"><img class="helpTooltip" name="admin"> {$form.contact_admin.label}</td><td class="FormRowValue">{$form.contact_admin.html}</td></tr>
         <tr class="list_one"><td class="FormRowField"><img class="helpTooltip" name="reach_api"> {$form.reach_api.label}</td><td class="FormRowValue">{$form.reach_api.html}</td></tr>
+        <tr class="list_two">
+            <td class="FormRowField">
+                <img class="helpTooltip" name="reach_api_rt">
+                {$form.reach_api_rt.label}
+            </td>
+            <td class="FormRowValue">{$form.reach_api_rt.html}</td>
+        </tr>
         {/if}
         <tr class="list_lvl_1">
             <td class="ListColLvl1_name" colspan="2">
@@ -125,7 +132,7 @@
             </td>
         </tr>
         {if $o == "mc"}
-            <tr class="list_two"><td class="FormRowField"><img class="helpTooltip" name="mc_update"> {$form.mc_mod_acl.label}</td><td class="FormRowValue">{$form.mc_mod_acl.html}</td></tr>
+            <tr class="list_one"><td class="FormRowField"><img class="helpTooltip" name="mc_update"> {$form.mc_mod_acl.label}</td><td class="FormRowValue">{$form.mc_mod_acl.html}</td></tr>
         {/if}
         <tr class="list_one"><td class="FormRowField"><img class="helpTooltip" name="aclgroups"> {$form.contact_acl_groups.label}</td><td class="FormRowValue">{$form.contact_acl_groups.html}</td></tr>
         {if $o == "a" || $o == "c"}
@@ -175,4 +182,4 @@
     </div>
     {$form.hidden}
 </form>
-{$helptext}
\ No newline at end of file
+{$helptext}
diff --git a/www/include/configuration/configObject/contact/formContact.php b/www/include/configuration/configObject/contact/formContact.php
index 3a609b0082eb1623ea1d550fd05caca02994dbb4..3081b7b5c794d7e25c382cd82f591043645a844d 100644
--- a/www/include/configuration/configObject/contact/formContact.php
+++ b/www/include/configuration/configObject/contact/formContact.php
@@ -205,8 +205,8 @@ $aclCond = "";
 if (!$centreon->user->admin) {
     $aclCond = " WHERE acl_group_id IN (" . $acl->getAccessGroupsString() . ") ";
 }
-$sql = "SELECT acl_group_id, acl_group_name 
-    FROM acl_groups 
+$sql = "SELECT acl_group_id, acl_group_name
+    FROM acl_groups
     {$aclCond}
     ORDER BY acl_group_name";
 $DBRESULT = $pearDB->query($sql);
@@ -357,7 +357,12 @@ if ($centreon->user->admin) {
     $tab = array();
     $tab[] = HTML_QuickForm::createElement('radio', 'reach_api', null, _("Yes"), '1');
     $tab[] = HTML_QuickForm::createElement('radio', 'reach_api', null, _("No"), '0');
-    $form->addGroup($tab, 'reach_api', _("Reach API"), '&nbsp;');
+    $form->addGroup($tab, 'reach_api', _("Reach API Configuration"), '&nbsp;');
+
+    $tab = array();
+    $tab[] = HTML_QuickForm::createElement('radio', 'reach_api_rt', null, _("Yes"), '1');
+    $tab[] = HTML_QuickForm::createElement('radio', 'reach_api_rt', null, _("No"), '0');
+    $form->addGroup($tab, 'reach_api_rt', _("Reach API Realtime"), '&nbsp;');
 }
 
 /**
@@ -408,7 +413,12 @@ if ($centreon->optGen['ldap_auth_enable'] == 1) {
     }
 }
 if ($o != "mc") {
-    $form->setDefaults(array('contact_oreon' => '1', "contact_admin" => '0', "reach_api" => '0'));
+    $form->setDefaults(array(
+        'contact_oreon' => '1',
+        'contact_admin' => '0',
+        'reach_api' => '0',
+        'reach_api_rt' => '0'
+    ));
 }
 $form->addElement('select', 'contact_auth_type', _("Authentication Source"), $auth_type);
 
@@ -706,4 +716,4 @@ function uncheckAllS(object)
         document.getElementById('sNone').checked = false;
     }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/www/include/configuration/configObject/contact/help.php b/www/include/configuration/configObject/contact/help.php
index 2898d5ffaa1fe89d5d4a9067284f15ce31057df5..cc45a099629acf8ec914b11f4befa2cc05d814f5 100644
--- a/www/include/configuration/configObject/contact/help.php
+++ b/www/include/configuration/configObject/contact/help.php
@@ -36,7 +36,8 @@ $help["admin"] = dgettext("help", "Specify if the user has administrative permis
 $help["autologin_key"] = dgettext("help", "Token used for autologin. Refer to the Centreon documentation to know more about its usage.");
 $help["auth_type"] = dgettext("help", "Specify the source for user credentials. Choose between Centreon and LDAP, whereas LDAP is only available when configured in Administration Options.");
 $help["location"] = dgettext("help", "Select the timezone, in which the user resides, from the list. The timezones are listed as time difference to Greenwich Mean Time (GMT) in hours.");
-$help["reach_api"] = dgettext("help", "Allow this user to access to Centreon Rest API with its account.");
+$help["reach_api"] = dgettext("help", "Allow this user to access to Centreon Rest API Configuration with its account.");
+$help["reach_api_rt"] = dgettext("help", "Allow this user to access to Centreon Rest API Realtime with its account.");
 
 /*
  * Additional Information
diff --git a/www/include/core/header/htmlHeader.php b/www/include/core/header/htmlHeader.php
index 9f007d194602ea7bfddd37ad9f2095f7d8014239..b8838054f5e8a066900e9b38ed6fa9ab22e6b6c2 100644
--- a/www/include/core/header/htmlHeader.php
+++ b/www/include/core/header/htmlHeader.php
@@ -83,6 +83,7 @@ print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
         <script type="text/javascript" src="./include/common/javascript/scriptaculous/scriptaculous.js?load=effects,dragdrop"></script>
         <script type="text/javascript" src="./include/common/javascript/modalbox.js"></script>
         <script type="text/javascript" src="./include/common/javascript/jquery/jquery.min.js"></script>
+        <script type="text/javascript" src="./include/common/javascript/jquery/plugins/toggleClick/jquery.toggleClick.js"></script>
         <script type="text/javascript" src="./include/common/javascript/jquery/plugins/select2/js/select2.full.min.js"></script>
         <script type="text/javascript" src="./include/common/javascript/centreon/centreon-select2.js"></script>
         <script type="text/javascript" src="./include/common/javascript/jquery/jquery-ui.js"></script>
diff --git a/www/include/options/accessLists/actionsACL/formActionsAccess.ihtml b/www/include/options/accessLists/actionsACL/formActionsAccess.ihtml
index e9263ae42983fb07ac6853d7fdb17a91ae51eb45..586c1c5e500f6dcb5a66798ed37742ad64a90997 100644
--- a/www/include/options/accessLists/actionsACL/formActionsAccess.ihtml
+++ b/www/include/options/accessLists/actionsACL/formActionsAccess.ihtml
@@ -140,29 +140,29 @@
 {literal}
 <script>
 
-    jQuery('input[name=all_service]').change(function(){
-        if(jQuery(this).attr('checked')){
-                jQuery('.serviceCheckbox input').attr('checked',true);
-        }else{
-                jQuery('.serviceCheckbox input').attr('checked',false);
-        }
-    });
+  jQuery('input[name=all_service]').change(function(){
+    if (jQuery(this).prop('checked')) {
+      jQuery('.serviceCheckbox input').attr('checked',true);
+    } else {
+      jQuery('.serviceCheckbox input').attr('checked',false);
+    }
+  });
 
-    jQuery('input[name=all_host]').change(function(){
-        if(jQuery(this).attr('checked')){
-                jQuery('.hostCheckbox input').attr('checked',true);
-        }else{
-                jQuery('.hostCheckbox input').attr('checked',false);
-        }
-    });
+  jQuery('input[name=all_host]').change(function(){
+    if (jQuery(this).prop('checked')) {
+      jQuery('.hostCheckbox input').attr('checked',true);
+    } else {
+      jQuery('.hostCheckbox input').attr('checked',false);
+    }
+  });
 
-    jQuery('input[name=all_engine]').change(function(){
-        if(jQuery(this).attr('checked')){
-                jQuery('.engineCheckbox input').attr('checked',true);
-        }else{
-                jQuery('.engineCheckbox input').attr('checked',false);
-        }
-    });
+  jQuery('input[name=all_engine]').change(function(){
+    if (jQuery(this).prop('checked')) {
+      jQuery('.engineCheckbox input').attr('checked',true);
+    } else {
+      jQuery('.engineCheckbox input').attr('checked',false);
+    }
+  });
 
 </script>
 {/literal}
diff --git a/www/include/reporting/dashboard/template/viewHostGroupLog.ihtml b/www/include/reporting/dashboard/template/viewHostGroupLog.ihtml
index 8d7911b5a493d9972b8a834aaffabfd28ef1f956..558a83c0abab5f41169468a4ef2e578996d97b35 100644
--- a/www/include/reporting/dashboard/template/viewHostGroupLog.ihtml
+++ b/www/include/reporting/dashboard/template/viewHostGroupLog.ihtml
@@ -152,7 +152,7 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
@@ -160,12 +160,12 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
     jQuery( "select[name='period']" ).click(function() {
-        jQuery( "input:[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
+        jQuery( "input[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
     });
 
     jQuery(function () {
diff --git a/www/include/reporting/dashboard/template/viewHostLog.ihtml b/www/include/reporting/dashboard/template/viewHostLog.ihtml
index a5d20af15dffe4c9d022728b0ba35b0f35f8f5cc..96e21a8645021b4681a025c75ce5de1ba8b316b4 100644
--- a/www/include/reporting/dashboard/template/viewHostLog.ihtml
+++ b/www/include/reporting/dashboard/template/viewHostLog.ihtml
@@ -175,7 +175,7 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
@@ -183,12 +183,12 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
     jQuery( "select[name='period']" ).click(function() {
-        jQuery( "input:[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
+        jQuery( "input[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
     });
 
     jQuery(function () {
diff --git a/www/include/reporting/dashboard/template/viewServicesGroupLog.ihtml b/www/include/reporting/dashboard/template/viewServicesGroupLog.ihtml
index 88867fd8ed8aa67ecf64b0dc5790e13270f2560e..4d5b02f13bfca3f50a3f4b092cca8a442aeec6fb 100644
--- a/www/include/reporting/dashboard/template/viewServicesGroupLog.ihtml
+++ b/www/include/reporting/dashboard/template/viewServicesGroupLog.ihtml
@@ -165,7 +165,7 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
@@ -173,12 +173,12 @@
         maxDate: '-1',
         onSelect : function(data){  
             jQuery( "select[name='period'] > option[value='']" ).prop('selected', true);
-            jQuery( "input:[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
+            jQuery( "input[value='custom'][name='period_choice'][type='radio']").prop('checked', true);
         }
     });
 
     jQuery( "select[name='period']" ).click(function() {
-        jQuery( "input:[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
+        jQuery( "input[value='preset'][name='period_choice'][type='radio']").prop('checked', true);
     });
 
     jQuery(function () {
diff --git a/www/install/createTables.sql b/www/install/createTables.sql
index 07c4aed9574a389c06e674966359af41f962668c..a9dcc2dc62cfa68ecb6144a6d6cbbd974edf1e8a 100644
--- a/www/install/createTables.sql
+++ b/www/install/createTables.sql
@@ -749,6 +749,7 @@ CREATE TABLE `contact` (
   `contact_location` int(11) DEFAULT '0',
   `contact_oreon` enum('0','1') DEFAULT NULL,
   `reach_api` int(11) DEFAULT '0',
+  `reach_api_rt` int(1) DEFAULT 0,
   `contact_enable_notifications` enum('0','1','2') DEFAULT '2',
   `contact_template_id` int(11) DEFAULT NULL,
   `contact_admin` enum('0','1') DEFAULT '0',
diff --git a/www/install/insertBaseConf.sql b/www/install/insertBaseConf.sql
index d49f1aab6800da0cc9d422b8f4962e6dd8a6bba4..486d9315eed29dd32afcff580aa39c55c505f360 100644
--- a/www/install/insertBaseConf.sql
+++ b/www/install/insertBaseConf.sql
@@ -2,7 +2,7 @@
 -- Insert version
 --
 
-INSERT INTO `informations` (`key` ,`value`) VALUES ('version', '2.8.21');
+INSERT INTO `informations` (`key` ,`value`) VALUES ('version', '2.8.23');
 
 --
 -- Contenu de la table `contact`
diff --git a/www/install/sql/centreon/Update-DB-2.8.20_to_2.8.21.sql b/www/install/sql/centreon/Update-DB-2.8.20_to_2.8.21.sql
index dccabf1b4ac5fbc690593ba6d9adb56b6f74d87e..01f7e7ff91480a587a72c1e73c5850d3919c5d11 100644
--- a/www/install/sql/centreon/Update-DB-2.8.20_to_2.8.21.sql
+++ b/www/install/sql/centreon/Update-DB-2.8.20_to_2.8.21.sql
@@ -1,2 +1,7 @@
 -- Change version of Centreon
 UPDATE `informations` SET `value` = '2.8.21' WHERE CONVERT( `informations`.`key` USING utf8 ) = 'version' AND CONVERT ( `informations`.`value` USING utf8 ) = '2.8.20' LIMIT 1;
+
+-- Temporary fix for limit realtime and configuration Rest API
+ALTER TABLE `contact` ADD COLUMN `reach_api_rt` int(1) DEFAULT 0 AFTER `reach_api`;
+-- Update users with right to reach api
+UPDATE contact SET reach_api_rt = "1" WHERE reach_api = "1";
diff --git a/www/install/sql/centreon/Update-DB-2.8.21_to_2.8.22.sql b/www/install/sql/centreon/Update-DB-2.8.21_to_2.8.22.sql
new file mode 100644
index 0000000000000000000000000000000000000000..98ca1b3d98e95c2a7222f491a3a91505a733c5df
--- /dev/null
+++ b/www/install/sql/centreon/Update-DB-2.8.21_to_2.8.22.sql
@@ -0,0 +1,2 @@
+-- Change version of Centreon
+UPDATE `informations` SET `value` = '2.8.22' WHERE CONVERT( `informations`.`key` USING utf8 ) = 'version' AND CONVERT ( `informations`.`value` USING utf8 ) = '2.8.21' LIMIT 1;
diff --git a/www/install/sql/centreon/Update-DB-2.8.22_to_2.8.23.sql b/www/install/sql/centreon/Update-DB-2.8.22_to_2.8.23.sql
new file mode 100644
index 0000000000000000000000000000000000000000..488524c7261abd695bc99aaf44e44c258ce25d45
--- /dev/null
+++ b/www/install/sql/centreon/Update-DB-2.8.22_to_2.8.23.sql
@@ -0,0 +1,2 @@
+-- Change version of Centreon
+UPDATE `informations` SET `value` = '2.8.23' WHERE CONVERT( `informations`.`key` USING utf8 ) = 'version' AND CONVERT ( `informations`.`value` USING utf8 ) = '2.8.22' LIMIT 1;