diff --git a/core/Plugin/Report.php b/core/Plugin/Report.php
index b09fed2d9a06be7ec799dda243ba58ec51054a37..36b002fa0754892aacb7c2a1d38307ce8ec66e62 100644
--- a/core/Plugin/Report.php
+++ b/core/Plugin/Report.php
@@ -39,7 +39,7 @@ class Report
     protected $isSubtableReport = null;
     protected $parameters = null;
     
-    private static $orderOfReports = array(
+    public static $orderOfReports = array(
         'General_MultiSitesSummary',
         'VisitsSummary_VisitsSummary',
         'Goals_Ecommerce',
@@ -316,7 +316,7 @@ class Report
      * @param Report $b
      * @return int
      */
-    public static function sort($a, $b)
+    private static function sort($a, $b)
     {
         return ($category = strcmp(array_search($a->category, self::$orderOfReports), array_search($b->category, self::$orderOfReports))) == 0
             ? ($a->order < $b->order ? -1 : 1)
diff --git a/plugins/API/ProcessedReport.php b/plugins/API/ProcessedReport.php
index 05a1a960eed4cfeff303d35310f5dc7a277505f8..c552ef674bd14965cab21bd66ec1bdeae3130e20 100644
--- a/plugins/API/ProcessedReport.php
+++ b/plugins/API/ProcessedReport.php
@@ -245,6 +245,9 @@ class ProcessedReport
          */
         Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters));
 
+        // Sort results to ensure consistent order
+        usort($availableReports, array('self', 'sortReports'));
+
         // Add the magic API.get report metadata aggregating all plugins API.get API calls automatically
         $this->addApiGetMetdata($availableReports);
 
@@ -314,6 +317,28 @@ class ProcessedReport
         return array_values($availableReports); // make sure array has contiguous key values
     }
 
+    /**
+     * API metadata are sorted by category/name,
+     * with a little tweak to replicate the standard Piwik category ordering
+     *
+     * @param array $a
+     * @param array $b
+     * @return int
+     */
+    private static function sortReports($a, $b)
+    {
+        static $order = null;
+        if (is_null($order)) {
+            $order = array();
+            foreach (Report::$orderOfReports as $category) {
+                $order[] = Piwik::translate($category);
+            }
+        }
+        return ($category = strcmp(array_search($a['category'], $order), array_search($b['category'], $order))) == 0
+            ? (@$a['order'] < @$b['order'] ? -1 : 1)
+            : $category;
+    }
+
     /**
      * Add the metadata for the API.get report
      * In other plugins, this would hook on 'API.getReportMetadata'
diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php
index 9dff08bb5e3940572f4758ee70a0be49ef70bb84..bde21ee5d815da3ae8aa314133b3b2bbde068d9c 100644
--- a/plugins/Goals/Goals.php
+++ b/plugins/Goals/Goals.php
@@ -47,11 +47,16 @@ class Goals extends \Piwik\Plugin
 
     public static function sortGoalDimensionsByModule($a, $b)
     {
-        $order = array(
-            Piwik::translate('Referrers_Referrers'),
-            Piwik::translate('General_Visit'),
-            Piwik::translate('VisitTime_ColumnServerTime'),
-        );
+        static $order = null;
+
+        if (is_null($order)) {
+            $order = array(
+                Piwik::translate('Referrers_Referrers'),
+                Piwik::translate('General_Visit'),
+                Piwik::translate('VisitTime_ColumnServerTime'),
+            );
+        }
+
         $orderA = array_search($a, $order);
         $orderB = array_search($b, $order);
         return $orderA > $orderB;
@@ -161,7 +166,7 @@ class Goals extends \Piwik\Plugin
             foreach ($reports as &$apiReportToUpdate) {
                 if ($apiReportToUpdate['module'] == $reportWithGoals['module']
                     && $apiReportToUpdate['action'] == $reportWithGoals['action']
-                ) {
+                    && empty($apiReportToUpdate['parameters'])) {
                     $apiReportToUpdate['metricsGoal'] = $goalMetrics;
                     $apiReportToUpdate['processedMetricsGoal'] = $goalProcessedMetrics;
                     break;