diff --git a/core/API/ApiRenderer.php b/core/API/ApiRenderer.php
index fc1c11d7367b4340a9a18438856edfd493284c69..a913041514346da23629acc94f57d4effdd519ed 100644
--- a/core/API/ApiRenderer.php
+++ b/core/API/ApiRenderer.php
@@ -91,8 +91,15 @@ abstract class ApiRenderer
             $format = 'json';
         }
 
+        $idSite = Common::getRequestVar('idSite', 0, 'int', $this->request);
+
+        if (empty($idSite)) {
+            $idSite = 'all';
+        }
+
         $renderer = Renderer::factory($format);
         $renderer->setTable($dataTable);
+        $renderer->setIdSite($idSite);
         $renderer->setRenderSubTables(Common::getRequestVar('expanded', false, 'int', $this->request));
         $renderer->setHideIdSubDatableFromResponse(Common::getRequestVar('hideIdSubDatable', false, 'int', $this->request));
 
diff --git a/core/BaseFactory.php b/core/BaseFactory.php
index 32b4090bc22aa193067e1eeb009b5378d581fa7e..d240da900f024fb24796e65b68e67d291659b124 100644
--- a/core/BaseFactory.php
+++ b/core/BaseFactory.php
@@ -26,7 +26,7 @@ abstract class BaseFactory
      * Creates a new instance of a class using a string ID.
      *
      * @param string $classId The ID of the class.
-     * @return BaseFactory
+     * @return \Piwik\DataTable\Renderer
      * @throws Exception if $classId is invalid.
      */
     public static function factory($classId)
diff --git a/core/DataTable/Renderer/Csv.php b/core/DataTable/Renderer/Csv.php
index d9b2ea4fd4a51db735393fbaf225e7669c840632..4d55979347d70116938fd4c34b84446cdefb78f2 100644
--- a/core/DataTable/Renderer/Csv.php
+++ b/core/DataTable/Renderer/Csv.php
@@ -12,7 +12,6 @@ use Piwik\Common;
 use Piwik\DataTable\Renderer;
 use Piwik\DataTable\Simple;
 use Piwik\DataTable;
-use Piwik\Date;
 use Piwik\Period;
 use Piwik\Period\Range;
 use Piwik\Piwik;
diff --git a/core/ReportRenderer.php b/core/ReportRenderer.php
index 3fa20aff43f36836d496f3463edc664e324800ca..1d290533c1aa031cd1b2dcf6194e367a387cec9a 100644
--- a/core/ReportRenderer.php
+++ b/core/ReportRenderer.php
@@ -35,12 +35,24 @@ abstract class ReportRenderer extends BaseFactory
     const PDF_FORMAT = 'pdf';
     const CSV_FORMAT = 'csv';
 
+    protected $idSite = 'all';
+
     private static $availableReportRenderers = array(
         self::PDF_FORMAT,
         self::HTML_FORMAT,
         self::CSV_FORMAT,
     );
 
+    /**
+     * Sets the site id
+     *
+     * @param int $idSite
+     */
+    public function setIdSite($idSite)
+    {
+        $this->idSite = $idSite;
+    }
+
     protected static function getClassNameFromClassId($rendererType)
     {
         return 'Piwik\ReportRenderer\\' . self::normalizeRendererType($rendererType);
diff --git a/core/ReportRenderer/Csv.php b/core/ReportRenderer/Csv.php
index b76096db4416cda7684a0f34d4b8b17b5e4565c7..ef5678b1f78f6b56af5198f199393500fc593d6f 100644
--- a/core/ReportRenderer/Csv.php
+++ b/core/ReportRenderer/Csv.php
@@ -141,6 +141,7 @@ class Csv extends ReportRenderer
     protected function getRenderer(DataTableInterface $table, $uniqueId)
     {
         $csvRenderer = new CsvDataTableRenderer();
+        $csvRenderer->setIdSite($this->idSite);
         $csvRenderer->setTable($table);
         $csvRenderer->setConvertToUnicode(false);
         $csvRenderer->setApiMethod(
diff --git a/plugins/API/API.php b/plugins/API/API.php
index a3a9b4fb023612e73ff61b18702fc73472a8e06e..ea69205597c599f4c3044b57d30690fc739deac3 100644
--- a/plugins/API/API.php
+++ b/plugins/API/API.php
@@ -264,19 +264,30 @@ class API extends \Piwik\Plugin\API
      * Triggers a hook to ask plugins for available Reports.
      * Returns metadata information about each report (category, name, dimension, metrics, etc.)
      *
-     * @param string $idSites Comma separated list of website Ids
+     * @param string $idSites THIS PARAMETER IS DEPRECATED AND WILL BE REMOVED IN PIWIK 4
      * @param bool|string $period
      * @param bool|Date $date
      * @param bool $hideMetricsDoc
      * @param bool $showSubtableReports
+     * @param int $idSite
      * @return array
      */
     public function getReportMetadata($idSites = '', $period = false, $date = false, $hideMetricsDoc = false,
-                                      $showSubtableReports = false)
+                                      $showSubtableReports = false, $idSite = false)
     {
-        Piwik::checkUserHasViewAccess($idSites);
+        if (empty($idSite) && !empty($idSites)) {
+            if (is_array($idSites)) {
+                $idSite = array_shift($idSites);
+            } else {
+                $idSite = $idSites;
+            }
+        } elseif (empty($idSite) && empty($idSites)) {
+            throw new \Exception('Calling API.getReportMetadata without any idSite is no longer supported since Piwik 3.0.0. Please specifiy at least one idSite via the "idSite" parameter.');
+        }
+
+        Piwik::checkUserHasViewAccess($idSite);
 
-        $metadata = $this->processedReport->getReportMetadata($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports);
+        $metadata = $this->processedReport->getReportMetadata($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports);
         return $metadata;
     }
 
diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php
index b7dd476075831dbec3321d64ef19251364c30d4c..d957b1e717b9722337c253ced8d29fc9b9619505 100644
--- a/plugins/API/ProcessedReport.php
+++ b/plugins/API/ProcessedReport.php
@@ -109,7 +109,7 @@ class ProcessedReport
 
     public function getReportMetadataByUniqueId($idSite, $apiMethodUniqueId)
     {
-        $metadata = $this->getReportMetadata(array($idSite));
+        $metadata = $this->getReportMetadata($idSite);
 
         foreach ($metadata as $report) {
             if ($report['uniqueId'] == $apiMethodUniqueId) {
@@ -148,23 +148,20 @@ class ProcessedReport
      * Triggers a hook to ask plugins for available Reports.
      * Returns metadata information about each report (category, name, dimension, metrics, etc.)
      *
-     * @param string $idSites Comma separated list of website Ids
+     * @param int $idSite
      * @param bool|string $period
      * @param bool|Date $date
      * @param bool $hideMetricsDoc
      * @param bool $showSubtableReports
      * @return array
      */
-    public function getReportMetadata($idSites, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false)
+    public function getReportMetadata($idSite, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false)
     {
-        $idSites = Site::getIdSitesFromIdSitesString($idSites);
-        if (!empty($idSites)) {
-            Piwik::checkUserHasViewAccess($idSites);
-        }
+        Piwik::checkUserHasViewAccess($idSite);
 
         // as they cache key contains a lot of information there would be an even better cache result by caching parts of
         // this huge method separately but that makes it also more complicated. leaving it like this for now.
-        $key   = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports);
+        $key   = $this->buildReportMetadataCacheKey($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports);
         $key   = CacheId::pluginAware($key);
         $cache = PiwikCache::getTransientCache();
 
@@ -172,7 +169,7 @@ class ProcessedReport
             return $cache->fetch($key);
         }
 
-        $parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date);
+        $parameters = array('idSite' => $idSite, 'period' => $period, 'date' => $date);
 
         $availableReports = array();
 
@@ -721,7 +718,7 @@ class ProcessedReport
         return null;
     }
 
-    private function buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports)
+    private function buildReportMetadataCacheKey($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports)
     {
         if (isset($_GET) && isset($_POST) && is_array($_GET) && is_array($_POST)) {
             $request = $_GET + $_POST;
@@ -742,7 +739,7 @@ class ProcessedReport
             }
         }
 
-        $key .= implode(',', $idSites) . ($period === false ? 0 : $period) . ($date === false ? 0 : $date);
+        $key .= $idSite . 'x' . ($period === false ? 0 : $period) . 'x' . ($date === false ? 0 : $date);
         $key .= (int)$hideMetricsDoc . (int)$showSubtableReports . Piwik::getCurrentUserLogin();
         return 'reportMetadata' . md5($key);
     }
diff --git a/plugins/API/Renderer/Console.php b/plugins/API/Renderer/Console.php
index 98e3d01d1ff1a92fffb4be0d889bedc1c9a83687..90dc03928e3a7850302e323adf1144ec741f2f5b 100644
--- a/plugins/API/Renderer/Console.php
+++ b/plugins/API/Renderer/Console.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 
 class Console extends ApiRenderer
 {
diff --git a/plugins/API/Renderer/Csv.php b/plugins/API/Renderer/Csv.php
index 77caa50bcec94fdbc796f532f133d932d0191cbd..1a01134b56f8242990a08d794d1dc2fd3ec48ec4 100644
--- a/plugins/API/Renderer/Csv.php
+++ b/plugins/API/Renderer/Csv.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 use Piwik\ProxyHttp;
 
 class Csv extends ApiRenderer
diff --git a/plugins/API/Renderer/Html.php b/plugins/API/Renderer/Html.php
index 48acbb355f249d390ae37ca2815236e10dadd4cd..1aeab87f51c1ce193b59c1b7212fa9a0521674e5 100644
--- a/plugins/API/Renderer/Html.php
+++ b/plugins/API/Renderer/Html.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 
 class Html extends ApiRenderer
 {
diff --git a/plugins/API/Renderer/Json.php b/plugins/API/Renderer/Json.php
index 5037b30fbe32afbac2d690b4adc265204296fc56..8adfdaebe14461f7aa664e4ed070671c11998a1e 100644
--- a/plugins/API/Renderer/Json.php
+++ b/plugins/API/Renderer/Json.php
@@ -11,7 +11,6 @@ namespace Piwik\Plugins\API\Renderer;
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
 use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 use Piwik\Piwik;
 use Piwik\ProxyHttp;
 
@@ -34,6 +33,7 @@ class Json extends ApiRenderer
     /**
      * @param $message
      * @param Exception|\Throwable $exception
+     * @param \Exception|\Throwable $exception
      * @return string
      */
     public function renderException($message, $exception)
diff --git a/plugins/API/Renderer/Php.php b/plugins/API/Renderer/Php.php
index 5823137569ef407d193de0cb55e551422cd5d1e0..c237074541b51b8d6dc85f6657114781990ad1f8 100644
--- a/plugins/API/Renderer/Php.php
+++ b/plugins/API/Renderer/Php.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 use Piwik\Piwik;
 
 class Php extends ApiRenderer
@@ -25,7 +23,7 @@ class Php extends ApiRenderer
 
     /**
      * @param $message
-     * @param Exception|\Throwable $exception
+     * @param \Exception|\Throwable $exception
      * @return string
      */
     public function renderException($message, $exception)
diff --git a/plugins/API/Renderer/Rss.php b/plugins/API/Renderer/Rss.php
index 5bbcac78aabd9df91316250eb6617efb2ead2a7e..f5ac883b402da72e4e6b4c5b58c11c79d6be4865 100644
--- a/plugins/API/Renderer/Rss.php
+++ b/plugins/API/Renderer/Rss.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 
 class Rss extends ApiRenderer
 {
diff --git a/plugins/API/Renderer/Tsv.php b/plugins/API/Renderer/Tsv.php
index c5505159e0691ffd6b012cc2bde7ca917373b479..85304d29dd6b4a862209c5121d56ff87c8ff9290 100644
--- a/plugins/API/Renderer/Tsv.php
+++ b/plugins/API/Renderer/Tsv.php
@@ -9,8 +9,6 @@
 namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 
 class Tsv extends Csv
 {
diff --git a/plugins/API/Renderer/Xml.php b/plugins/API/Renderer/Xml.php
index 4a1f0247d704775d03b7fbc74e76095bdfcdf42c..dc1a52705736b44b9b283ea46826f0ad3f060266 100644
--- a/plugins/API/Renderer/Xml.php
+++ b/plugins/API/Renderer/Xml.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\API\Renderer;
 
 use Piwik\API\ApiRenderer;
 use Piwik\Common;
-use Piwik\DataTable\Renderer;
-use Piwik\DataTable;
 
 class Xml extends ApiRenderer
 {
diff --git a/plugins/Actions/Reports/SiteSearchBase.php b/plugins/Actions/Reports/SiteSearchBase.php
index d4715e04e63bf1c363aeddafd53123d70922e20f..787ce89fe676e1390fe7f13ae81ec55c59c028c9 100644
--- a/plugins/Actions/Reports/SiteSearchBase.php
+++ b/plugins/Actions/Reports/SiteSearchBase.php
@@ -37,9 +37,9 @@ abstract class SiteSearchBase extends Base
 
     public function configureReportMetadata(&$availableReports, $infos)
     {
-        $idSites = !empty($infos['idSites']) ? $infos['idSites'] : array();
+        $idSite = array($infos['idSite']);
 
-        if (!$this->isEnabledForIdSites($idSites, Common::getRequestVar('idSite', 0, 'int'))) {
+        if (!$this->isEnabledForIdSites($idSite, Common::getRequestVar('idSite', 0, 'int'))) {
             return;
         }
 
diff --git a/plugins/CoreHome/angularjs/common/services/report-metadata-model.js b/plugins/CoreHome/angularjs/common/services/report-metadata-model.js
index fcf8e4690e36051dbfc40eca8676e097c6046c60..c5fd42b73aa0de34b273dab148e6b869db648d86 100644
--- a/plugins/CoreHome/angularjs/common/services/report-metadata-model.js
+++ b/plugins/CoreHome/angularjs/common/services/report-metadata-model.js
@@ -39,8 +39,8 @@
             if (!reportsPromise) {
                 reportsPromise = piwikApi.fetch({
                     method: 'API.getReportMetadata',
-                    idSites: piwik.idSite || piwik.broadcast.getValueFromUrl('idSite'),
-                    filter_limit: '-1'
+                    filter_limit: '-1',
+                    idSite: piwik.idSite || piwik.broadcast.getValueFromUrl('idSite')
                 }).then(function (response) {
                     model.reports = response;
                     return response;
diff --git a/plugins/Ecommerce/Reports/Base.php b/plugins/Ecommerce/Reports/Base.php
index 28a3a4a36f162c557bf140ee95407009261877d7..5fe49dd1e8b4ca10c55fa2fc076eb11d961cc3cd 100644
--- a/plugins/Ecommerce/Reports/Base.php
+++ b/plugins/Ecommerce/Reports/Base.php
@@ -54,14 +54,12 @@ abstract class Base extends Report
 
     private function isEcommerceEnabledByInfos($infos)
     {
-        $idSites = $infos['idSites'];
+        $idSite = $infos['idSite'];
 
-        if (count($idSites) != 1) {
+        if (empty($idSite)) {
             return false;
         }
 
-        $idSite = reset($idSites);
-
         return $this->isEcommerceEnabled($idSite);
     }
 
diff --git a/plugins/Goals/Reports/Base.php b/plugins/Goals/Reports/Base.php
index f9e36d6787234b18c22878e67a7b1bbb53c81dd1..4c2a57e755bae884c8ed06c6ed34b66545b05087 100644
--- a/plugins/Goals/Reports/Base.php
+++ b/plugins/Goals/Reports/Base.php
@@ -41,14 +41,12 @@ abstract class Base extends \Piwik\Plugin\Report
 
     protected function getIdSiteFromInfos($infos)
     {
-        $idSites = $infos['idSites'];
+        $idSite = $infos['idSite'];
 
-        if (count($idSites) != 1) {
+        if (empty($idSite)) {
             return null;
         }
 
-        $idSite = reset($idSites);
-
         return $idSite;
     }
 
diff --git a/plugins/ImageGraph/ImageGraph.php b/plugins/ImageGraph/ImageGraph.php
index 9869d37081697335756801ee3ab48339b05b2d2b..86a1d45cfc3e9cc2f4d8ab433eac2a599013479d 100644
--- a/plugins/ImageGraph/ImageGraph.php
+++ b/plugins/ImageGraph/ImageGraph.php
@@ -52,14 +52,13 @@ class ImageGraph extends \Piwik\Plugin
      */
     public function getReportMetadata(&$reports, $info)
     {
-        $idSites = $info['idSites'];
+        $idSite = $info['idSite'];
 
         // If only one website is selected, we add the Graph URL
-        if (count($idSites) != 1) {
+        if (empty($idSite)) {
             return;
         }
-        $idSite = reset($idSites);
-
+        
         // in case API.getReportMetadata was not called with date/period we use sane defaults
         if (empty($info['period'])) {
             $info['period'] = 'day';
diff --git a/plugins/SEO/Widgets/GetRank.php b/plugins/SEO/Widgets/GetRank.php
index be22d61eec33106266b7435854d5b5528bf1723c..b22a6683c9cae44b7fee5572c92cee38e2dd998e 100644
--- a/plugins/SEO/Widgets/GetRank.php
+++ b/plugins/SEO/Widgets/GetRank.php
@@ -14,7 +14,6 @@ use Piwik\Widget\WidgetConfig;
 use Piwik\Site;
 use Piwik\Url;
 use Piwik\UrlHelper;
-use Piwik\View;
 use Piwik\Plugins\SEO\API;
 
 class GetRank extends \Piwik\Widget\Widget
diff --git a/plugins/ScheduledReports/API.php b/plugins/ScheduledReports/API.php
index 3391b581c81498ab3638a208a1342ed97a91f77b..be34d120fc4444426d56052a2f9fce5b6c9d3772 100644
--- a/plugins/ScheduledReports/API.php
+++ b/plugins/ScheduledReports/API.php
@@ -469,6 +469,7 @@ class API extends \Piwik\Plugin\API
         }
 
         // init report renderer
+        $reportRenderer->setIdSite($idSite);
         $reportRenderer->setLocale($language);
 
         // render report