diff --git a/.eslintrc.js b/.eslintrc.js
index 561e9bc55bf9d..ad9de04251e4c 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1035,12 +1035,19 @@ module.exports = {
      * Alerting Services overrides
      */
     {
-      // typescript only for front and back end
+      // typescript for front and back end
       files: ['x-pack/plugins/{alerts,stack_alerts,actions,task_manager,event_log}/**/*.{ts,tsx}'],
       rules: {
         '@typescript-eslint/no-explicit-any': 'error',
       },
     },
+    {
+      // typescript only for back end
+      files: ['x-pack/plugins/triggers_actions_ui/server/**/*.ts'],
+      rules: {
+        '@typescript-eslint/no-explicit-any': 'error',
+      },
+    },
 
     /**
      * Lens overrides
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index 701b7cab21600..e326c8e2cac39 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -102,3 +102,4 @@ pageLoadAssetSize:
   visualizations: 295025
   visualize: 57431
   watcher: 43598
+  stackAlerts: 29684
diff --git a/x-pack/plugins/stack_alerts/server/config.ts b/x-pack/plugins/stack_alerts/common/config.ts
similarity index 85%
rename from x-pack/plugins/stack_alerts/server/config.ts
rename to x-pack/plugins/stack_alerts/common/config.ts
index 8a13aedd5fdd8..2e997ce0ebad6 100644
--- a/x-pack/plugins/stack_alerts/server/config.ts
+++ b/x-pack/plugins/stack_alerts/common/config.ts
@@ -8,6 +8,7 @@ import { schema, TypeOf } from '@kbn/config-schema';
 
 export const configSchema = schema.object({
   enabled: schema.boolean({ defaultValue: true }),
+  enableGeoTrackingThresholdAlert: schema.boolean({ defaultValue: false }),
 });
 
 export type Config = TypeOf<typeof configSchema>;
diff --git a/x-pack/plugins/stack_alerts/common/index.ts b/x-pack/plugins/stack_alerts/common/index.ts
index 79dd18d321f07..a75625d0641aa 100644
--- a/x-pack/plugins/stack_alerts/common/index.ts
+++ b/x-pack/plugins/stack_alerts/common/index.ts
@@ -3,5 +3,5 @@
  * or more contributor license agreements. Licensed under the Elastic License;
  * you may not use this file except in compliance with the Elastic License.
  */
-
+export * from './config';
 export const STACK_ALERTS_FEATURE_ID = 'stackAlerts';
diff --git a/x-pack/plugins/stack_alerts/kibana.json b/x-pack/plugins/stack_alerts/kibana.json
index b26114577c430..b7405c38d1611 100644
--- a/x-pack/plugins/stack_alerts/kibana.json
+++ b/x-pack/plugins/stack_alerts/kibana.json
@@ -3,7 +3,7 @@
   "server": true,
   "version": "8.0.0",
   "kibanaVersion": "kibana",
-  "requiredPlugins": ["alerts", "features"],
+  "requiredPlugins": ["alerts", "features", "triggersActionsUi", "kibanaReact"],
   "configPath": ["xpack", "stack_alerts"],
-  "ui": false
+  "ui": true
 }
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/index.ts b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/index.ts
similarity index 75%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/index.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/index.ts
index 00d9ebbbbc066..35f5648de40f3 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/index.ts
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/index.ts
@@ -5,18 +5,17 @@
  */
 import { lazy } from 'react';
 import { i18n } from '@kbn/i18n';
-import { AlertTypeModel } from '../../../../types';
 import { validateExpression } from './validation';
 import { GeoThresholdAlertParams } from './types';
-import { AlertsContextValue } from '../../../context/alerts_context';
+import { AlertTypeModel, AlertsContextValue } from '../../../../triggers_actions_ui/public';
 
 export function getAlertType(): AlertTypeModel<GeoThresholdAlertParams, AlertsContextValue> {
   return {
     id: '.geo-threshold',
-    name: i18n.translate('xpack.triggersActionsUI.geoThreshold.name.trackingThreshold', {
+    name: i18n.translate('xpack.stackAlerts.geoThreshold.name.trackingThreshold', {
       defaultMessage: 'Tracking threshold',
     }),
-    description: i18n.translate('xpack.triggersActionsUI.geoThreshold.descriptionText', {
+    description: i18n.translate('xpack.stackAlerts.geoThreshold.descriptionText', {
       defaultMessage: 'Alert when an entity enters or leaves a geo boundary.',
     }),
     iconClass: 'globe',
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx
similarity index 85%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx
index 497e053a4ed60..55dfc82bdbdb8 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/boundary_index_expression.tsx
@@ -7,14 +7,13 @@
 import React, { Fragment, FunctionComponent, useEffect, useRef } from 'react';
 import { EuiFormRow } from '@elastic/eui';
 import { i18n } from '@kbn/i18n';
-import { IErrorObject } from '../../../../../../types';
+import { IErrorObject, AlertsContextValue } from '../../../../../../triggers_actions_ui/public';
 import { ES_GEO_SHAPE_TYPES, GeoThresholdAlertParams } from '../../types';
-import { AlertsContextValue } from '../../../../../context/alerts_context';
 import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select';
 import { SingleFieldSelect } from '../util_components/single_field_select';
 import { ExpressionWithPopover } from '../util_components/expression_with_popover';
-import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
-import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
+import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';
+import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
 
 interface Props {
   alertParams: GeoThresholdAlertParams;
@@ -117,12 +116,12 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
       <EuiFormRow
         id="geoField"
         fullWidth
-        label={i18n.translate('xpack.triggersActionsUI.geoThreshold.geofieldLabel', {
+        label={i18n.translate('xpack.stackAlerts.geoThreshold.geofieldLabel', {
           defaultMessage: 'Geospatial field',
         })}
       >
         <SingleFieldSelect
-          placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectLabel', {
+          placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectLabel', {
             defaultMessage: 'Select geo field',
           })}
           value={boundaryGeoField}
@@ -133,12 +132,12 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
       <EuiFormRow
         id="boundaryNameFieldSelect"
         fullWidth
-        label={i18n.translate('xpack.triggersActionsUI.geoThreshold.boundaryNameSelectLabel', {
+        label={i18n.translate('xpack.stackAlerts.geoThreshold.boundaryNameSelectLabel', {
           defaultMessage: 'Human-readable boundary name (optional)',
         })}
       >
         <SingleFieldSelect
-          placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.boundaryNameSelect', {
+          placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.boundaryNameSelect', {
             defaultMessage: 'Select boundary name',
           })}
           value={boundaryNameField || null}
@@ -156,7 +155,7 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
       defaultValue={'Select an index pattern and geo shape field'}
       value={boundaryIndexPattern.title}
       popoverContent={indexPopover}
-      expressionDescription={i18n.translate('xpack.triggersActionsUI.geoThreshold.indexLabel', {
+      expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.indexLabel', {
         defaultMessage: 'index',
       })}
     />
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx
similarity index 87%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx
index f355d25796b7c..f519ad882802c 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_by_expression.tsx
@@ -8,10 +8,10 @@ import React, { FunctionComponent, useEffect, useRef } from 'react';
 import { EuiFormRow } from '@elastic/eui';
 import { i18n } from '@kbn/i18n';
 import _ from 'lodash';
-import { IErrorObject } from '../../../../../../types';
+import { IErrorObject } from '../../../../../../triggers_actions_ui/public';
 import { SingleFieldSelect } from '../util_components/single_field_select';
 import { ExpressionWithPopover } from '../util_components/expression_with_popover';
-import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
+import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';
 
 interface Props {
   errors: IErrorObject;
@@ -59,7 +59,7 @@ export const EntityByExpression: FunctionComponent<Props> = ({
     <EuiFormRow id="entitySelect" fullWidth error={errors.index}>
       <SingleFieldSelect
         placeholder={i18n.translate(
-          'xpack.triggersActionsUI.geoThreshold.topHitsSplitFieldSelectPlaceholder',
+          'xpack.stackAlerts.geoThreshold.topHitsSplitFieldSelectPlaceholder',
           {
             defaultMessage: 'Select entity field',
           }
@@ -77,7 +77,7 @@ export const EntityByExpression: FunctionComponent<Props> = ({
       value={entity}
       defaultValue={'Select entity field'}
       popoverContent={indexPopover}
-      expressionDescription={i18n.translate('xpack.triggersActionsUI.geoThreshold.entityByLabel', {
+      expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.entityByLabel', {
         defaultMessage: 'by',
       })}
     />
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx
similarity index 83%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx
index 506530c171cd4..e5e43210d1e6b 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/expressions/entity_index_expression.tsx
@@ -8,14 +8,13 @@ import React, { Fragment, FunctionComponent, useEffect, useRef } from 'react';
 import { EuiFormRow } from '@elastic/eui';
 import { FormattedMessage } from '@kbn/i18n/react';
 import { i18n } from '@kbn/i18n';
-import { IErrorObject } from '../../../../../../types';
+import { IErrorObject, AlertsContextValue } from '../../../../../../triggers_actions_ui/public';
 import { ES_GEO_FIELD_TYPES } from '../../types';
-import { AlertsContextValue } from '../../../../../context/alerts_context';
 import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select';
 import { SingleFieldSelect } from '../util_components/single_field_select';
 import { ExpressionWithPopover } from '../util_components/expression_with_popover';
-import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
-import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
+import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';
+import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
 
 interface Props {
   dateField: string;
@@ -105,13 +104,13 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
         fullWidth
         label={
           <FormattedMessage
-            id="xpack.triggersActionsUI.geoThreshold.timeFieldLabel"
+            id="xpack.stackAlerts.geoThreshold.timeFieldLabel"
             defaultMessage="Time field"
           />
         }
       >
         <SingleFieldSelect
-          placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectTimeLabel', {
+          placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectTimeLabel', {
             defaultMessage: 'Select time field',
           })}
           value={timeField}
@@ -124,12 +123,12 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
       <EuiFormRow
         id="geoField"
         fullWidth
-        label={i18n.translate('xpack.triggersActionsUI.geoThreshold.geofieldLabel', {
+        label={i18n.translate('xpack.stackAlerts.geoThreshold.geofieldLabel', {
           defaultMessage: 'Geospatial field',
         })}
       >
         <SingleFieldSelect
-          placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectGeoLabel', {
+          placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectGeoLabel', {
             defaultMessage: 'Select geo field',
           })}
           value={geoField}
@@ -148,12 +147,9 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
       value={indexPattern.title}
       defaultValue={'Select an index pattern and geo shape/point field'}
       popoverContent={indexPopover}
-      expressionDescription={i18n.translate(
-        'xpack.triggersActionsUI.geoThreshold.entityIndexLabel',
-        {
-          defaultMessage: 'index',
-        }
-      )}
+      expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.entityIndexLabel', {
+        defaultMessage: 'index',
+      })}
     />
   );
 };
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/index.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/index.tsx
similarity index 89%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/index.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/index.tsx
index ccc2ddd9c01ca..f138c08c0f993 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/index.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/index.tsx
@@ -19,15 +19,17 @@ import {
 } from '@elastic/eui';
 import { FormattedMessage } from '@kbn/i18n/react';
 import { i18n } from '@kbn/i18n';
-import { AlertTypeParamsExpressionProps } from '../../../../../types';
+import {
+  AlertTypeParamsExpressionProps,
+  getTimeOptions,
+  AlertsContextValue,
+} from '../../../../../triggers_actions_ui/public';
 import { GeoThresholdAlertParams, TrackingEvent } from '../types';
-import { AlertsContextValue } from '../../../../context/alerts_context';
 import { ExpressionWithPopover } from './util_components/expression_with_popover';
 import { EntityIndexExpression } from './expressions/entity_index_expression';
 import { EntityByExpression } from './expressions/entity_by_expression';
 import { BoundaryIndexExpression } from './expressions/boundary_index_expression';
-import { IIndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns';
-import { getTimeOptions } from '../../../../../common/lib/get_time_options';
+import { IIndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns';
 
 const DEFAULT_VALUES = {
   TRACKING_EVENT: '',
@@ -45,20 +47,20 @@ const DEFAULT_VALUES = {
 };
 
 const conditionOptions = Object.keys(TrackingEvent).map((key) => ({
-  text: (TrackingEvent as any)[key],
-  value: (TrackingEvent as any)[key],
+  text: TrackingEvent[key as TrackingEvent],
+  value: TrackingEvent[key as TrackingEvent],
 }));
 
 const labelForDelayOffset = (
   <>
     <FormattedMessage
-      id="xpack.triggersActionsUI.geoThreshold.delayOffset"
+      id="xpack.stackAlerts.geoThreshold.delayOffset"
       defaultMessage="Delayed evaluation offset"
     />{' '}
     <EuiIconTip
       position="right"
       type="questionInCircle"
-      content={i18n.translate('xpack.triggersActionsUI.geoThreshold.delayOffsetTooltip', {
+      content={i18n.translate('xpack.stackAlerts.geoThreshold.delayOffsetTooltip', {
         defaultMessage: 'Evaluate alerts on a delayed cycle to adjust for data latency',
       })}
     />
@@ -125,7 +127,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
 
   const hasExpressionErrors = false;
   const expressionErrorMessage = i18n.translate(
-    'xpack.triggersActionsUI.geoThreshold.fixErrorInExpressionBelowValidationMessage',
+    'xpack.stackAlerts.geoThreshold.fixErrorInExpressionBelowValidationMessage',
     {
       defaultMessage: 'Expression contains errors.',
     }
@@ -180,7 +182,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.geoThreshold.selectOffset"
+            id="xpack.stackAlerts.geoThreshold.selectOffset"
             defaultMessage="Select offset (optional)"
           />
         </h5>
@@ -221,7 +223,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.geoThreshold.selectEntity"
+            id="xpack.stackAlerts.geoThreshold.selectEntity"
             defaultMessage="Select entity"
           />
         </h5>
@@ -251,7 +253,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.geoThreshold.selectIndex"
+            id="xpack.stackAlerts.geoThreshold.selectIndex"
             defaultMessage="Define the condition"
           />
         </h5>
@@ -280,19 +282,16 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
             </div>
           </EuiFormRow>
         }
-        expressionDescription={i18n.translate(
-          'xpack.triggersActionsUI.geoThreshold.whenEntityLabel',
-          {
-            defaultMessage: 'when entity',
-          }
-        )}
+        expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.whenEntityLabel', {
+          defaultMessage: 'when entity',
+        })}
       />
 
       <EuiSpacer size="l" />
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.geoThreshold.selectBoundaryIndex"
+            id="xpack.stackAlerts.geoThreshold.selectBoundaryIndex"
             defaultMessage="Select boundary:"
           />
         </h5>
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx
similarity index 88%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx
index 7e1cae51f1411..a83667cfd92c6 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/expression_with_popover.tsx
@@ -4,7 +4,7 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import React, { useState } from 'react';
+import React, { ReactNode, useState } from 'react';
 import {
   EuiButtonIcon,
   EuiExpression,
@@ -22,10 +22,10 @@ export const ExpressionWithPopover: ({
   value,
   isInvalid,
 }: {
-  popoverContent: any;
-  expressionDescription: any;
-  defaultValue?: any;
-  value?: any;
+  popoverContent: ReactNode;
+  expressionDescription: ReactNode;
+  defaultValue?: ReactNode;
+  value?: ReactNode;
   isInvalid?: boolean;
 }) => JSX.Element = ({ popoverContent, expressionDescription, defaultValue, value, isInvalid }) => {
   const [popoverOpen, setPopoverOpen] = useState(false);
@@ -61,7 +61,7 @@ export const ExpressionWithPopover: ({
                 iconType="cross"
                 color="danger"
                 aria-label={i18n.translate(
-                  'xpack.triggersActionsUI.sections.alertAdd.geoThreshold.closePopoverLabel',
+                  'xpack.stackAlerts.geoThreshold.ui.expressionPopover.closePopoverLabel',
                   {
                     defaultMessage: 'Close',
                   }
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx
similarity index 80%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx
index 42995dfb1b9d6..a552d6d998c7e 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/geo_index_pattern_select.tsx
@@ -14,6 +14,7 @@ import { HttpSetup } from 'kibana/public';
 interface Props {
   onChange: (indexPattern: IndexPattern) => void;
   value: string | undefined;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   IndexPatternSelectComponent: any;
   indexPatternService: IndexPatternsContract | undefined;
   http: HttpSetup;
@@ -39,7 +40,7 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
     this._isMounted = true;
   }
 
-  _onIndexPatternSelect = async (indexPatternId: any) => {
+  _onIndexPatternSelect = async (indexPatternId: string) => {
     if (!indexPatternId || indexPatternId.length === 0 || !this.props.indexPatternService) {
       return;
     }
@@ -70,42 +71,39 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
     return (
       <>
         <EuiCallOut
-          title={i18n.translate(
-            'xpack.triggersActionsUI.geoThreshold.noIndexPattern.messageTitle',
-            {
-              defaultMessage: `Couldn't find any index patterns with geospatial fields`,
-            }
-          )}
+          title={i18n.translate('xpack.stackAlerts.geoThreshold.noIndexPattern.messageTitle', {
+            defaultMessage: `Couldn't find any index patterns with geospatial fields`,
+          })}
           color="warning"
         >
           <p>
             <FormattedMessage
-              id="xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisPrefixDescription"
+              id="xpack.stackAlerts.geoThreshold.noIndexPattern.doThisPrefixDescription"
               defaultMessage="You'll need to "
             />
             <EuiLink
               href={this.props.http.basePath.prepend(`/app/management/kibana/indexPatterns`)}
             >
               <FormattedMessage
-                id="xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisLinkTextDescription"
+                id="xpack.stackAlerts.geoThreshold.noIndexPattern.doThisLinkTextDescription"
                 defaultMessage="create an index pattern"
               />
             </EuiLink>
             <FormattedMessage
-              id="xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisSuffixDescription"
+              id="xpack.stackAlerts.geoThreshold.noIndexPattern.doThisSuffixDescription"
               defaultMessage=" with geospatial fields."
             />
           </p>
           <p>
             <FormattedMessage
-              id="xpack.triggersActionsUI.geoThreshold.noIndexPattern.hintDescription"
+              id="xpack.stackAlerts.geoThreshold.noIndexPattern.hintDescription"
               defaultMessage="Don't have any geospatial data sets? "
             />
             <EuiLink
               href={this.props.http.basePath.prepend('/app/home#/tutorial_directory/sampleData')}
             >
               <FormattedMessage
-                id="xpack.triggersActionsUI.geoThreshold.noIndexPattern.getStartedLinkText"
+                id="xpack.stackAlerts.geoThreshold.noIndexPattern.getStartedLinkText"
                 defaultMessage="Get started with some sample data sets."
               />
             </EuiLink>
@@ -123,7 +121,7 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
         {this._renderNoIndexPatternWarning()}
 
         <EuiFormRow
-          label={i18n.translate('xpack.triggersActionsUI.geoThreshold.indexPatternSelectLabel', {
+          label={i18n.translate('xpack.stackAlerts.geoThreshold.indexPatternSelectLabel', {
             defaultMessage: 'Index pattern',
           })}
         >
@@ -133,7 +131,7 @@ export class GeoIndexPatternSelect extends Component<Props, State> {
               indexPatternId={this.props.value}
               onChange={this._onIndexPatternSelect}
               placeholder={i18n.translate(
-                'xpack.triggersActionsUI.geoThreshold.indexPatternSelectPlaceholder',
+                'xpack.stackAlerts.geoThreshold.indexPatternSelectPlaceholder',
                 {
                   defaultMessage: 'Select index pattern',
                 }
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx
similarity index 96%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx
index 30389b31ce8c8..ef6e6f6f5e18f 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/query_builder/util_components/single_field_select.tsx
@@ -14,7 +14,7 @@ import {
   EuiFlexItem,
 } from '@elastic/eui';
 import { IFieldType } from 'src/plugins/data/public';
-import { FieldIcon } from '../../../../../../../../../../src/plugins/kibana_react/public';
+import { FieldIcon } from '../../../../../../../../src/plugins/kibana_react/public';
 
 function fieldsToOptions(fields?: IFieldType[]): Array<EuiComboBoxOptionOption<IFieldType>> {
   if (!fields) {
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/types.ts b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/types.ts
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/types.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/types.ts
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/validation.test.ts b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/validation.test.ts
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/validation.test.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/validation.test.ts
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/validation.ts b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/validation.ts
similarity index 72%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/validation.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/validation.ts
index 078a88d9e8415..7a511f681ecaa 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/geo_threshold/validation.ts
+++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_threshold/validation.ts
@@ -4,7 +4,7 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 import { i18n } from '@kbn/i18n';
-import { ValidationResult } from '../../../../types';
+import { ValidationResult } from '../../../../triggers_actions_ui/public';
 import { GeoThresholdAlertParams } from './types';
 
 export const validateExpression = (alertParams: GeoThresholdAlertParams): ValidationResult => {
@@ -35,7 +35,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!index) {
     errors.index.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredIndexTitleText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredIndexTitleText', {
         defaultMessage: 'Index pattern is required.',
       })
     );
@@ -43,7 +43,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!geoField) {
     errors.geoField.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredGeoFieldText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredGeoFieldText', {
         defaultMessage: 'Geo field is required.',
       })
     );
@@ -51,7 +51,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!entity) {
     errors.entity.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredEntityText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredEntityText', {
         defaultMessage: 'Entity is required.',
       })
     );
@@ -59,7 +59,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!dateField) {
     errors.dateField.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredDateFieldText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredDateFieldText', {
         defaultMessage: 'Date field is required.',
       })
     );
@@ -67,7 +67,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!trackingEvent) {
     errors.trackingEvent.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredTrackingEventText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredTrackingEventText', {
         defaultMessage: 'Tracking event is required.',
       })
     );
@@ -75,7 +75,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!boundaryType) {
     errors.boundaryType.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryTypeText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredBoundaryTypeText', {
         defaultMessage: 'Boundary type is required.',
       })
     );
@@ -83,7 +83,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!boundaryIndexTitle) {
     errors.boundaryIndexTitle.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryIndexTitleText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredBoundaryIndexTitleText', {
         defaultMessage: 'Boundary index pattern title is required.',
       })
     );
@@ -91,7 +91,7 @@ export const validateExpression = (alertParams: GeoThresholdAlertParams): Valida
 
   if (!boundaryGeoField) {
     errors.boundaryGeoField.push(
-      i18n.translate('xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryGeoFieldText', {
+      i18n.translate('xpack.stackAlerts.geoThreshold.error.requiredBoundaryGeoFieldText', {
         defaultMessage: 'Boundary geo field is required.',
       })
     );
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/index.ts b/x-pack/plugins/stack_alerts/public/alert_types/index.ts
similarity index 57%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/index.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/index.ts
index 4b2860dcf9b72..61cf7193fedb7 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/index.ts
+++ b/x-pack/plugins/stack_alerts/public/alert_types/index.ts
@@ -6,18 +6,17 @@
 
 import { getAlertType as getGeoThresholdAlertType } from './geo_threshold';
 import { getAlertType as getThresholdAlertType } from './threshold';
-import { TypeRegistry } from '../../type_registry';
-import { AlertTypeModel } from '../../../types';
-import { TriggersActionsUiConfigType } from '../../../plugin';
+import { Config } from '../../common';
+import { TriggersAndActionsUIPublicPluginSetup } from '../../../triggers_actions_ui/public';
 
-export function registerBuiltInAlertTypes({
+export function registerAlertTypes({
   alertTypeRegistry,
-  triggerActionsUiConfig,
+  config,
 }: {
-  alertTypeRegistry: TypeRegistry<AlertTypeModel>;
-  triggerActionsUiConfig: TriggersActionsUiConfigType;
+  alertTypeRegistry: TriggersAndActionsUIPublicPluginSetup['alertTypeRegistry'];
+  config: Config;
 }) {
-  if (triggerActionsUiConfig.enableGeoTrackingThresholdAlert) {
+  if (config.enableGeoTrackingThresholdAlert) {
     alertTypeRegistry.register(getGeoThresholdAlertType());
   }
   alertTypeRegistry.register(getThresholdAlertType());
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.scss b/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.scss
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.scss
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.scss
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx
similarity index 86%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx
index e309d97b57f34..92cb8c9055bde 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx
@@ -29,21 +29,20 @@ import {
   getIndexPatterns,
   getIndexOptions,
   getFields,
-} from '../../../../common/index_controls';
-import { COMPARATORS, builtInComparators } from '../../../../common/constants';
-import { getTimeFieldOptions } from '../../../../common/lib/get_time_options';
-import { ThresholdVisualization } from './visualization';
-import { WhenExpression } from '../../../../common';
-import {
+  COMPARATORS,
+  builtInComparators,
+  getTimeFieldOptions,
   OfExpression,
   ThresholdExpression,
   ForLastExpression,
   GroupByExpression,
-} from '../../../../common';
-import { builtInAggregationTypes } from '../../../../common/constants';
+  WhenExpression,
+  builtInAggregationTypes,
+  AlertTypeParamsExpressionProps,
+  AlertsContextValue,
+} from '../../../../triggers_actions_ui/public';
+import { ThresholdVisualization } from './visualization';
 import { IndexThresholdAlertParams } from './types';
-import { AlertTypeParamsExpressionProps } from '../../../../types';
-import { AlertsContextValue } from '../../../context/alerts_context';
 import './expression.scss';
 
 const DEFAULT_VALUES = {
@@ -89,7 +88,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
 
   const [indexPopoverOpen, setIndexPopoverOpen] = useState(false);
   const [indexPatterns, setIndexPatterns] = useState([]);
-  const [esFields, setEsFields] = useState<Record<string, any>>([]);
+  const [esFields, setEsFields] = useState<unknown[]>([]);
   const [indexOptions, setIndexOptions] = useState<EuiComboBoxOptionOption[]>([]);
   const [timeFieldOptions, setTimeFieldOptions] = useState([firstFieldOption]);
   const [isIndiciesLoading, setIsIndiciesLoading] = useState<boolean>(false);
@@ -98,7 +97,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
     (errorKey) =>
       expressionFieldsWithValidation.includes(errorKey) &&
       errors[errorKey].length >= 1 &&
-      (alertParams as { [key: string]: any })[errorKey] !== undefined
+      alertParams[errorKey as keyof IndexThresholdAlertParams] !== undefined
   );
 
   const canShowVizualization = !!Object.keys(errors).find(
@@ -106,7 +105,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
   );
 
   const expressionErrorMessage = i18n.translate(
-    'xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage',
+    'xpack.stackAlerts.threshold.ui.alertParams.fixErrorInExpressionBelowValidationMessage',
     {
       defaultMessage: 'Expression contains errors.',
     }
@@ -126,7 +125,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
 
     if (index && index.length > 0) {
       const currentEsFields = await getFields(http, index);
-      const timeFields = getTimeFieldOptions(currentEsFields as any);
+      const timeFields = getTimeFieldOptions(currentEsFields);
 
       setEsFields(currentEsFields);
       setTimeFieldOptions([firstFieldOption, ...timeFields]);
@@ -159,7 +158,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
         fullWidth
         label={
           <FormattedMessage
-            id="xpack.triggersActionsUI.sections.alertAdd.threshold.indicesToQueryLabel"
+            id="xpack.stackAlerts.threshold.ui.alertParams.indicesToQueryLabel"
             defaultMessage="Indices to query"
           />
         }
@@ -167,7 +166,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
         error={errors.index}
         helpText={
           <FormattedMessage
-            id="xpack.triggersActionsUI.sections.alertAdd.threshold.howToBroadenSearchQueryDescription"
+            id="xpack.stackAlerts.threshold.ui.alertParams.howToBroadenSearchQueryDescription"
             defaultMessage="Use * to broaden your query."
           />
         }
@@ -211,7 +210,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
               return;
             }
             const currentEsFields = await getFields(http, indices);
-            const timeFields = getTimeFieldOptions(currentEsFields as any);
+            const timeFields = getTimeFieldOptions(currentEsFields);
 
             setEsFields(currentEsFields);
             setTimeFieldOptions([firstFieldOption, ...timeFields]);
@@ -233,7 +232,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
         fullWidth
         label={
           <FormattedMessage
-            id="xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldLabel"
+            id="xpack.stackAlerts.threshold.ui.alertParams.timeFieldLabel"
             defaultMessage="Time field"
           />
         }
@@ -284,7 +283,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.sections.alertAdd.selectIndex"
+            id="xpack.stackAlerts.threshold.ui.selectIndex"
             defaultMessage="Select an index"
           />
         </h5>
@@ -296,12 +295,9 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
           <EuiExpression
             display="columns"
             data-test-subj="selectIndexExpression"
-            description={i18n.translate(
-              'xpack.triggersActionsUI.sections.alertAdd.threshold.indexLabel',
-              {
-                defaultMessage: 'index',
-              }
-            )}
+            description={i18n.translate('xpack.stackAlerts.threshold.ui.alertParams.indexLabel', {
+              defaultMessage: 'index',
+            })}
             value={index && index.length > 0 ? renderIndices(index) : firstFieldOption.text}
             isActive={indexPopoverOpen}
             onClick={() => {
@@ -321,12 +317,9 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
           <EuiPopoverTitle>
             <EuiFlexGroup alignItems="center" gutterSize="s">
               <EuiFlexItem>
-                {i18n.translate(
-                  'xpack.triggersActionsUI.sections.alertAdd.threshold.indexButtonLabel',
-                  {
-                    defaultMessage: 'index',
-                  }
-                )}
+                {i18n.translate('xpack.stackAlerts.threshold.ui.alertParams.indexButtonLabel', {
+                  defaultMessage: 'index',
+                })}
               </EuiFlexItem>
               <EuiFlexItem grow={false}>
                 <EuiButtonIcon
@@ -334,7 +327,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
                   iconType="cross"
                   color="danger"
                   aria-label={i18n.translate(
-                    'xpack.triggersActionsUI.sections.alertAdd.threshold.closeIndexPopoverLabel',
+                    'xpack.stackAlerts.threshold.ui.alertParams.closeIndexPopoverLabel',
                     {
                       defaultMessage: 'Close',
                     }
@@ -386,7 +379,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
       <EuiTitle size="xs">
         <h5>
           <FormattedMessage
-            id="xpack.triggersActionsUI.sections.alertAdd.conditionPrompt"
+            id="xpack.stackAlerts.threshold.ui.conditionPrompt"
             defaultMessage="Define the condition"
           />
         </h5>
@@ -411,10 +404,10 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
         timeWindowUnit={timeWindowUnit}
         display="fullWidth"
         errors={errors}
-        onChangeWindowSize={(selectedWindowSize: any) =>
+        onChangeWindowSize={(selectedWindowSize: number | undefined) =>
           setAlertParams('timeWindowSize', selectedWindowSize)
         }
-        onChangeWindowUnit={(selectedWindowUnit: any) =>
+        onChangeWindowUnit={(selectedWindowUnit: string) =>
           setAlertParams('timeWindowUnit', selectedWindowUnit)
         }
       />
@@ -427,7 +420,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<AlertTyp
               body={
                 <EuiText color="subdued">
                   <FormattedMessage
-                    id="xpack.triggersActionsUI.sections.alertAdd.previewAlertVisualizationDescription"
+                    id="xpack.stackAlerts.threshold.ui.previewAlertVisualizationDescription"
                     defaultMessage="Complete the expression to generate a preview."
                   />
                 </EuiText>
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts b/x-pack/plugins/stack_alerts/public/alert_types/threshold/index.ts
similarity index 77%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/index.ts
index a5b2fbb37e838..b7923a3013613 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts
+++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/index.ts
@@ -5,18 +5,17 @@
  */
 import { lazy } from 'react';
 import { i18n } from '@kbn/i18n';
-import { AlertTypeModel } from '../../../../types';
 import { validateExpression } from './validation';
 import { IndexThresholdAlertParams } from './types';
-import { AlertsContextValue } from '../../../context/alerts_context';
+import { AlertTypeModel, AlertsContextValue } from '../../../../triggers_actions_ui/public';
 
 export function getAlertType(): AlertTypeModel<IndexThresholdAlertParams, AlertsContextValue> {
   return {
     id: '.index-threshold',
-    name: i18n.translate('xpack.triggersActionsUI.indexThresholdAlert.nameText', {
+    name: i18n.translate('xpack.stackAlerts.threshold.ui.alertType.nameText', {
       defaultMessage: 'Index threshold',
     }),
-    description: i18n.translate('xpack.triggersActionsUI.indexThresholdAlert.descriptionText', {
+    description: i18n.translate('xpack.stackAlerts.threshold.ui.alertType.descriptionText', {
       defaultMessage: 'Alert when an aggregated query meets the threshold.',
     }),
     iconClass: 'alert',
@@ -26,7 +25,7 @@ export function getAlertType(): AlertTypeModel<IndexThresholdAlertParams, Alerts
     alertParamsExpression: lazy(() => import('./expression')),
     validate: validateExpression,
     defaultActionMessage: i18n.translate(
-      'xpack.triggersActionsUI.components.builtinAlertTypes.threshold.alertDefaultActionMessage',
+      'xpack.stackAlerts.threshold.ui.alertType.defaultActionMessage',
       {
         defaultMessage: `alert \\{\\{alertName\\}\\} group \\{\\{context.group\\}\\} value \\{\\{context.value\\}\\} exceeded threshold \\{\\{context.function\\}\\} over \\{\\{params.timeWindowSize\\}\\}\\{\\{params.timeWindowUnit\\}\\} on \\{\\{context.date\\}\\}`,
       }
diff --git a/x-pack/plugins/stack_alerts/public/alert_types/threshold/index_threshold_api.ts b/x-pack/plugins/stack_alerts/public/alert_types/threshold/index_threshold_api.ts
new file mode 100644
index 0000000000000..ec531b26fc8c6
--- /dev/null
+++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/index_threshold_api.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { HttpSetup } from 'kibana/public';
+import { TimeSeriesResult } from '../../../../triggers_actions_ui/common';
+import { IndexThresholdAlertParams } from './types';
+
+const INDEX_THRESHOLD_DATA_API_ROOT = '/api/triggers_actions_ui/data';
+
+export interface GetThresholdAlertVisualizationDataParams {
+  model: IndexThresholdAlertParams;
+  visualizeOptions: {
+    rangeFrom: string;
+    rangeTo: string;
+    interval: string;
+  };
+  http: HttpSetup;
+}
+
+export async function getThresholdAlertVisualizationData({
+  model,
+  visualizeOptions,
+  http,
+}: GetThresholdAlertVisualizationDataParams): Promise<TimeSeriesResult> {
+  const timeSeriesQueryParams = {
+    index: model.index,
+    timeField: model.timeField,
+    aggType: model.aggType,
+    aggField: model.aggField,
+    groupBy: model.groupBy,
+    termField: model.termField,
+    termSize: model.termSize,
+    timeWindowSize: model.timeWindowSize,
+    timeWindowUnit: model.timeWindowUnit,
+    dateStart: new Date(visualizeOptions.rangeFrom).toISOString(),
+    dateEnd: new Date(visualizeOptions.rangeTo).toISOString(),
+    interval: visualizeOptions.interval,
+  };
+
+  return await http.post<TimeSeriesResult>(`${INDEX_THRESHOLD_DATA_API_ROOT}/_time_series_query`, {
+    body: JSON.stringify(timeSeriesQueryParams),
+  });
+}
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts b/x-pack/plugins/stack_alerts/public/alert_types/threshold/types.ts
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/types.ts
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/validation.test.ts b/x-pack/plugins/stack_alerts/public/alert_types/threshold/validation.test.ts
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/validation.test.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/validation.test.ts
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/validation.ts b/x-pack/plugins/stack_alerts/public/alert_types/threshold/validation.ts
similarity index 81%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/validation.ts
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/validation.ts
index 3912b2fffae1e..4bbf80906377b 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/validation.ts
+++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/validation.ts
@@ -4,13 +4,13 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 import { i18n } from '@kbn/i18n';
-import { ValidationResult } from '../../../../types';
 import { IndexThresholdAlertParams } from './types';
 import {
+  ValidationResult,
   builtInGroupByTypes,
   builtInAggregationTypes,
   builtInComparators,
-} from '../../../../common/constants';
+} from '../../../../triggers_actions_ui/public';
 
 export const validateExpression = (alertParams: IndexThresholdAlertParams): ValidationResult => {
   const {
@@ -39,21 +39,21 @@ export const validateExpression = (alertParams: IndexThresholdAlertParams): Vali
   validationResult.errors = errors;
   if (!index || index.length === 0) {
     errors.index.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredIndexText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredIndexText', {
         defaultMessage: 'Index is required.',
       })
     );
   }
   if (!timeField) {
     errors.timeField.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredTimeFieldText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredTimeFieldText', {
         defaultMessage: 'Time field is required.',
       })
     );
   }
   if (aggType && builtInAggregationTypes[aggType].fieldRequired && !aggField) {
     errors.aggField.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredAggFieldText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredAggFieldText', {
         defaultMessage: 'Aggregation field is required.',
       })
     );
@@ -65,7 +65,7 @@ export const validateExpression = (alertParams: IndexThresholdAlertParams): Vali
     !termSize
   ) {
     errors.termSize.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredTermSizedText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredTermSizedText', {
         defaultMessage: 'Term size is required.',
       })
     );
@@ -77,21 +77,21 @@ export const validateExpression = (alertParams: IndexThresholdAlertParams): Vali
     !termField
   ) {
     errors.termField.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredtTermFieldText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredTermFieldText', {
         defaultMessage: 'Term field is required.',
       })
     );
   }
   if (!timeWindowSize) {
     errors.timeWindowSize.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredTimeWindowSizeText', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredTimeWindowSizeText', {
         defaultMessage: 'Time window size is required.',
       })
     );
   }
   if (!threshold || threshold.length === 0 || threshold[0] === undefined) {
     errors.threshold0.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold0Text', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold0Text', {
         defaultMessage: 'Threshold0 is required.',
       })
     );
@@ -104,14 +104,14 @@ export const validateExpression = (alertParams: IndexThresholdAlertParams): Vali
       (threshold && threshold.length < builtInComparators[thresholdComparator!].requiredValues))
   ) {
     errors.threshold1.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold1Text', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold1Text', {
         defaultMessage: 'Threshold1 is required.',
       })
     );
   }
   if (threshold && threshold.length === 2 && threshold[0] > threshold[1]) {
     errors.threshold1.push(
-      i18n.translate('xpack.triggersActionsUI.sections.addAlert.error.greaterThenThreshold0Text', {
+      i18n.translate('xpack.stackAlerts.threshold.ui.validation.error.greaterThenThreshold0Text', {
         defaultMessage: 'Threshold1 should be > Threshold0.',
       })
     );
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx
similarity index 86%
rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx
rename to x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx
index a282fa08e8f38..6145aa3671a7f 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx
+++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx
@@ -29,11 +29,17 @@ import {
   EuiLoadingSpinner,
 } from '@elastic/eui';
 import { FormattedMessage } from '@kbn/i18n/react';
-import { getThresholdAlertVisualizationData } from '../../../../common/lib/index_threshold_api';
-import { AggregationType, Comparator } from '../../../../common/types';
-import { AlertsContextValue } from '../../../context/alerts_context';
+import {
+  getThresholdAlertVisualizationData,
+  GetThresholdAlertVisualizationDataParams,
+} from './index_threshold_api';
+import {
+  AlertsContextValue,
+  AggregationType,
+  Comparator,
+} from '../../../../triggers_actions_ui/public';
 import { IndexThresholdAlertParams } from './types';
-import { parseDuration } from '../../../../../../alerts/common/parse_duration';
+import { parseDuration } from '../../../../alerts/common/parse_duration';
 
 const customTheme = () => {
   return {
@@ -125,7 +131,7 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
   const { http, toastNotifications, charts, uiSettings, dataFieldsFormats } = alertsContext;
 
   const [loadingState, setLoadingState] = useState<LoadingStateType | null>(null);
-  const [error, setError] = useState<undefined | any>(undefined);
+  const [error, setError] = useState<undefined | Error>(undefined);
   const [visualizationData, setVisualizationData] = useState<Record<string, MetricResult[]>>();
   const [startVisualizationAt, setStartVisualizationAt] = useState<Date>(new Date());
 
@@ -150,7 +156,7 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
         if (toastNotifications) {
           toastNotifications.addDanger({
             title: i18n.translate(
-              'xpack.triggersActionsUI.sections.alertAdd.unableToLoadVisualizationMessage',
+              'xpack.stackAlerts.threshold.ui.visualization.unableToLoadVisualizationMessage',
               { defaultMessage: 'Unable to load visualization' }
             ),
           });
@@ -199,7 +205,7 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
         body={
           <EuiText color="subdued">
             <FormattedMessage
-              id="xpack.triggersActionsUI.sections.alertAdd.loadingAlertVisualizationDescription"
+              id="xpack.stackAlerts.threshold.ui.visualization.loadingAlertVisualizationDescription"
               defaultMessage="Loading alert visualization…"
             />
           </EuiText>
@@ -215,7 +221,7 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
         <EuiCallOut
           title={
             <FormattedMessage
-              id="xpack.triggersActionsUI.sections.alertAdd.errorLoadingAlertVisualizationTitle"
+              id="xpack.stackAlerts.threshold.ui.visualization.errorLoadingAlertVisualizationTitle"
               defaultMessage="Cannot load alert visualization"
               values={{}}
             />
@@ -239,7 +245,7 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
     const alertVisualizationDataKeys = Object.keys(visualizationData);
     const timezone = getTimezone(uiSettings);
     const actualThreshold = getThreshold();
-    let maxY = actualThreshold[actualThreshold.length - 1] as any;
+    let maxY = actualThreshold[actualThreshold.length - 1];
 
     (Object.values(visualizationData) as number[][][]).forEach((data) => {
       data.forEach(([, y]) => {
@@ -288,14 +294,14 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
                 />
               );
             })}
-            {actualThreshold.map((_value: any, i: number) => {
-              const specId = i === 0 ? 'threshold' : `threshold${i}`;
+            {actualThreshold.map((_value: number, thresholdIndex: number) => {
+              const specId = thresholdIndex === 0 ? 'threshold' : `threshold${thresholdIndex}`;
               return (
                 <LineAnnotation
                   key={specId}
                   id={specId}
                   domainType={AnnotationDomainTypes.YDomain}
-                  dataValues={[{ dataValue: threshold[i], details: specId }]}
+                  dataValues={[{ dataValue: threshold[thresholdIndex], details: specId }]}
                 />
               );
             })}
@@ -305,14 +311,14 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
             size="s"
             title={
               <FormattedMessage
-                id="xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.noDataTitle"
+                id="xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.noDataTitle"
                 defaultMessage="No data matches this query"
               />
             }
             color="warning"
           >
             <FormattedMessage
-              id="xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.dataDoesNotExistTextMessage"
+              id="xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.dataDoesNotExistTextMessage"
               defaultMessage="Check that your time range and filters are correct."
             />
           </EuiCallOut>
@@ -325,7 +331,11 @@ export const ThresholdVisualization: React.FunctionComponent<Props> = ({
 };
 
 // convert the data from the visualization API into something easier to digest with charts
-async function getVisualizationData(model: any, visualizeOptions: any, http: HttpSetup) {
+async function getVisualizationData(
+  model: IndexThresholdAlertParams,
+  visualizeOptions: GetThresholdAlertVisualizationDataParams['visualizeOptions'],
+  http: HttpSetup
+) {
   const vizData = await getThresholdAlertVisualizationData({
     model,
     visualizeOptions,
diff --git a/x-pack/plugins/stack_alerts/public/index.ts b/x-pack/plugins/stack_alerts/public/index.ts
new file mode 100644
index 0000000000000..2f84a5949f111
--- /dev/null
+++ b/x-pack/plugins/stack_alerts/public/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { PluginInitializerContext } from 'src/core/public';
+import { StackAlertsPublicPlugin } from './plugin';
+
+export const plugin = (ctx: PluginInitializerContext) => new StackAlertsPublicPlugin(ctx);
diff --git a/x-pack/plugins/stack_alerts/public/plugin.tsx b/x-pack/plugins/stack_alerts/public/plugin.tsx
new file mode 100644
index 0000000000000..63176e7b30277
--- /dev/null
+++ b/x-pack/plugins/stack_alerts/public/plugin.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public';
+import { TriggersAndActionsUIPublicPluginSetup } from '../../../plugins/triggers_actions_ui/public';
+import { registerAlertTypes } from './alert_types';
+import { Config } from '../common';
+
+export type Setup = void;
+export type Start = void;
+
+export interface StackAlertsPublicSetupDeps {
+  triggersActionsUi: TriggersAndActionsUIPublicPluginSetup;
+}
+
+export class StackAlertsPublicPlugin implements Plugin<Setup, Start, StackAlertsPublicSetupDeps> {
+  private initializerContext: PluginInitializerContext;
+
+  constructor(initializerContext: PluginInitializerContext) {
+    this.initializerContext = initializerContext;
+  }
+
+  public setup(core: CoreSetup, { triggersActionsUi }: StackAlertsPublicSetupDeps) {
+    registerAlertTypes({
+      alertTypeRegistry: triggersActionsUi.alertTypeRegistry,
+      config: this.initializerContext.config.get<Config>(),
+    });
+  }
+
+  public start() {}
+  public stop() {}
+}
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/alert_type.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/alert_type.ts
index 360a6eb169573..9fc46fe2f2586 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/alert_type.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/alert_type.ts
@@ -6,7 +6,7 @@
 
 import { i18n } from '@kbn/i18n';
 import { schema } from '@kbn/config-schema';
-import { Service } from '../../types';
+import { Logger } from 'src/core/server';
 import { STACK_ALERTS_FEATURE_ID } from '../../../common';
 import { getGeoThresholdExecutor } from './geo_threshold';
 import {
@@ -173,7 +173,7 @@ export interface GeoThresholdParams {
 }
 
 export function getAlertType(
-  service: Omit<Service, 'indexThreshold'>
+  logger: Logger
 ): {
   defaultActionGroupId: string;
   actionGroups: ActionGroup[];
@@ -222,7 +222,7 @@ export function getAlertType(
     name: alertTypeName,
     actionGroups: [{ id: ActionGroupId, name: actionGroupName }],
     defaultActionGroupId: ActionGroupId,
-    executor: getGeoThresholdExecutor(service),
+    executor: getGeoThresholdExecutor(logger),
     producer: STACK_ALERTS_FEATURE_ID,
     validate: {
       params: ParamsSchema,
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/es_query_builder.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/es_query_builder.ts
index c4238e62ff261..97be51b2a6256 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/es_query_builder.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/es_query_builder.ts
@@ -6,7 +6,7 @@
 
 import { ILegacyScopedClusterClient } from 'kibana/server';
 import { SearchResponse } from 'elasticsearch';
-import { Logger } from '../../types';
+import { Logger } from 'src/core/server';
 
 export const OTHER_CATEGORY = 'other';
 // Consider dynamically obtaining from config?
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/geo_threshold.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/geo_threshold.ts
index f30dea151ece8..394ee8d606abe 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/geo_threshold.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/geo_threshold.ts
@@ -6,10 +6,10 @@
 
 import _ from 'lodash';
 import { SearchResponse } from 'elasticsearch';
+import { Logger } from 'src/core/server';
 import { executeEsQueryFactory, getShapesFilters, OTHER_CATEGORY } from './es_query_builder';
 import { AlertServices, AlertTypeState } from '../../../../alerts/server';
 import { ActionGroupId, GEO_THRESHOLD_ID, GeoThresholdParams } from './alert_type';
-import { Logger } from '../../types';
 
 interface LatestEntityLocation {
   location: number[];
@@ -169,7 +169,7 @@ function getOffsetTime(delayOffsetWithUnits: string, oldTime: Date): Date {
   return adjustedDate;
 }
 
-export const getGeoThresholdExecutor = ({ logger: log }: { logger: Logger }) =>
+export const getGeoThresholdExecutor = (log: Logger) =>
   async function ({
     previousStartedAt,
     startedAt,
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/index.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/index.ts
index d57f219bb8f9a..2fa2bed9d8419 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/index.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/index.ts
@@ -4,15 +4,16 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Service, AlertingSetup } from '../../types';
+import { Logger } from 'src/core/server';
+import { AlertingSetup } from '../../types';
 import { getAlertType } from './alert_type';
 
 interface RegisterParams {
-  service: Omit<Service, 'indexThreshold'>;
+  logger: Logger;
   alerts: AlertingSetup;
 }
 
 export function register(params: RegisterParams) {
-  const { service, alerts } = params;
-  alerts.registerType(getAlertType(service));
+  const { logger, alerts } = params;
+  alerts.registerType(getAlertType(logger));
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/tests/alert_type.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/tests/alert_type.test.ts
index 5cf113f519a5a..49b56b5571b44 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/tests/alert_type.test.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_threshold/tests/alert_type.test.ts
@@ -8,11 +8,9 @@ import { loggingSystemMock } from '../../../../../../../src/core/server/mocks';
 import { getAlertType, GeoThresholdParams } from '../alert_type';
 
 describe('alertType', () => {
-  const service = {
-    logger: loggingSystemMock.create().get(),
-  };
+  const logger = loggingSystemMock.create().get();
 
-  const alertType = getAlertType(service);
+  const alertType = getAlertType(logger);
 
   it('alert type creation structure is the expected value', async () => {
     expect(alertType.id).toBe('.geo-threshold');
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index.ts b/x-pack/plugins/stack_alerts/server/alert_types/index.ts
index dd9f1488092f4..461358d1296e2 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index.ts
@@ -4,15 +4,15 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Service, IRouter, AlertingSetup } from '../types';
+import { Logger } from 'src/core/server';
+import { AlertingSetup, StackAlertsStartDeps } from '../types';
 import { register as registerIndexThreshold } from './index_threshold';
 import { register as registerGeoThreshold } from './geo_threshold';
 
 interface RegisterAlertTypesParams {
-  service: Service;
-  router: IRouter;
+  logger: Logger;
+  data: Promise<StackAlertsStartDeps['triggersActionsUi']['data']>;
   alerts: AlertingSetup;
-  baseRoute: string;
 }
 
 export function registerBuiltInAlertTypes(params: RegisterAlertTypesParams) {
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/README.md b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/README.md
index 0ff01ddfb49c7..9b0eb23950cc3 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/README.md
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/README.md
@@ -13,10 +13,7 @@ is exceeded.
 
 ## alertType `.index-threshold`
 
-The alertType parameters are specified in
-[`lib/core_query_types.ts`][it-core-query]
-and
-[`alert_type_params.ts`][it-alert-params].
+The alertType parameters are specified in [`alert_type_params.ts`][it-alert-params].
 
 The alertType has a single actionGroup, `'threshold met'`.  The `context` object
 provided to actions is specified in
@@ -123,227 +120,6 @@ server    log   [17:32:10.060] [warning][actions][actions][plugins] \
 [now-iso]: https://github.com/pmuellr/now-iso
 
 
-## http endpoints
+## Data Apis via the TriggersActionsUi plugin and its http endpoints
 
-The following endpoints are provided for this alert type:
-
-- `POST /api/stack_alerts/index_threshold/_indices`
-- `POST /api/stack_alerts/index_threshold/_fields`
-- `POST /api/stack_alerts/index_threshold/_time_series_query`
-
-### `POST .../_indices`
-
-This HTTP endpoint is provided for the alerting ui to list the available
-"index names" for the user to select to use with the alert.  This API also
-returns aliases which match the supplied pattern.
-
-The request body is expected to be a JSON object in the following form, where the
-`pattern` value may include comma-separated names and wildcards.
-
-```js
-{
-  pattern: "index-name-pattern"
-}
-```
-
-The response body is a JSON object in the following form, where each element
-of the `indices` array is the name of an index or alias.  The number of elements
-returned is limited, as this API is intended to be used to help narrow down
-index names to use with the alert, and not support pagination, etc.
-
-```js
-{
-  indices: ["index-name-1", "alias-name-1", ...]
-}
-```
-
-### `POST .../_fields`
-
-This HTTP endpoint is provided for the alerting ui to list the available
-fields for the user to select to use with the alert.
-
-The request body is expected to be a JSON object in the following form, where the
-`indexPatterns` array elements may include comma-separated names and wildcards.
-
-```js
-{
-  indexPatterns: ["index-pattern-1", "index-pattern-2"]
-}
-```
-
-The response body is a JSON object in the following form, where each element
-fields array is a field object.
-
-```js
-{
-  fields: [fieldObject1, fieldObject2, ...]
-}
-```
-
-A field object is the following shape:
-
-```typescript
-{
-  name: string,           // field name
-  type: string,           // field type - eg 'keyword', 'date', 'long', etc
-  normalizedType: string, // for numeric types, this will be 'number'
-  aggregatable: true,     // value from elasticsearch field capabilities
-  searchable: true,       // value from elasticsearch field capabilities
-}
-```
-
-### `POST .../_time_series_query`
-
-This HTTP endpoint is provided to return the values the alertType would calculate,
-over a series of time.  It is intended to be used in the alerting UI to 
-provide a "preview" of the alert during creation/editing based on recent data,
-and could be used to show a "simulation" of the the alert over an arbitrary
-range of time.
-
-The endpoint is `POST /api/stack_alerts/index_threshold/_time_series_query`.
-The request and response bodies are specifed in 
-[`lib/core_query_types.ts`][it-core-query]
-and
-[`lib/time_series_types.ts`][it-timeSeries-types].
-The request body is very similar to the alertType's parameters.
-
-### example
-
-Continuing with the example above, here's a query to get the values calculated
-for the last 10 seconds.
-This example uses [now-iso][] to generate iso date strings.
-
-```console
-curl -k  "https://elastic:changeme@localhost:5601/api/stack_alerts/index_threshold/_time_series_query" \
-    -H "kbn-xsrf: foo" -H "content-type: application/json"   -d "{
-    \"index\":           \"es-hb-sim\",
-    \"timeField\":       \"@timestamp\",
-    \"aggType\":         \"avg\",
-    \"aggField\":        \"summary.up\",
-    \"groupBy\":         \"top\",
-    \"termSize\":        100,
-    \"termField\":       \"monitor.name.keyword\",
-    \"interval\":        \"1s\",
-    \"dateStart\":       \"`now-iso -10s`\",
-    \"dateEnd\":         \"`now-iso`\",
-    \"timeWindowSize\":  5,
-    \"timeWindowUnit\":  \"s\"
-}"
-```
-
-```
-{
-  "results": [
-    {
-      "group": "host-A",
-      "metrics": [
-        [ "2020-02-26T15:10:40.000Z", 0 ],
-        [ "2020-02-26T15:10:41.000Z", 0 ],
-        [ "2020-02-26T15:10:42.000Z", 0 ],
-        [ "2020-02-26T15:10:43.000Z", 0 ],
-        [ "2020-02-26T15:10:44.000Z", 0 ],
-        [ "2020-02-26T15:10:45.000Z", 0 ],
-        [ "2020-02-26T15:10:46.000Z", 0 ],
-        [ "2020-02-26T15:10:47.000Z", 0 ],
-        [ "2020-02-26T15:10:48.000Z", 0 ],
-        [ "2020-02-26T15:10:49.000Z", 0 ],
-        [ "2020-02-26T15:10:50.000Z", 0 ]
-      ]
-    }
-  ]
-}
-```
-
-To get the current value of the calculated metric, you can leave off the date:
-
-```
-curl -k  "https://elastic:changeme@localhost:5601/api/stack_alerts/index_threshold/_time_series_query" \
-    -H "kbn-xsrf: foo" -H "content-type: application/json"   -d '{
-    "index":           "es-hb-sim",
-    "timeField":       "@timestamp",
-    "aggType":         "avg",
-    "aggField":        "summary.up",
-    "groupBy":         "top",
-    "termField":       "monitor.name.keyword",
-    "termSize":        100,
-    "interval":        "1s",
-    "timeWindowSize":  5,
-    "timeWindowUnit":  "s"
-}'
-```
-
-```
-{
-  "results": [
-    {
-      "group": "host-A",
-      "metrics": [
-        [ "2020-02-26T15:23:36.635Z", 0 ]
-      ]
-    }
-  ]
-}
-```
-
-[it-timeSeries-types]: lib/time_series_types.ts
-
-## service functions
-
-A single service function is available that provides the functionality
-of the http endpoint `POST /api/stack_alerts/index_threshold/_time_series_query`,
-but as an API for Kibana plugins.  The function is available as
-`alertingService.indexThreshold.timeSeriesQuery()`
-
-The parameters and return value for the function are the same as for the HTTP
-request, though some additional parameters are required (logger, callCluster,
-etc).
-
-## notes on the timeSeriesQuery API / http endpoint
-
-This API provides additional parameters beyond what the alertType itself uses:
-
-- `dateStart`
-- `dateEnd`
-- `interval`
-
-The `dateStart` and `dateEnd` parameters are ISO date strings.
-
-The `interval` parameter is intended to model the `interval` the alert is
-currently using, and uses the same `1s`, `2m`, `3h`, etc format.  Over the
-supplied date range, a time-series data point will be calculated every
-`interval` duration.
-
-So the number of time-series points in the output of the API should be:
-
-```
-( dateStart - dateEnd ) / interval
-```
-
-Example: 
-
-```
-dateStart: '2020-01-01T00:00:00'
-dateEnd:   '2020-01-02T00:00:00'
-interval:  '1h'
-```
-
-The date range is 1 day === 24 hours.  The interval is 1 hour.  So there should
-be ~24 time series points in the output.
-
-For preview purposes:
-
-- The `termSize` parameter should be used to help cut
-down on the amount of work ES does, and keep the generated graphs a little
-simpler.  Probably something like `10`.
-
-- For queries with long date ranges, you probably don't want to use the
-`interval` the alert is set to, as the `interval` used in the query, as this
-could result in a lot of time-series points being generated, which is both
-costly in ES, and may result in noisy graphs.
-
-- The `timeWindow*` parameters should be the same as what the alert is using, 
-especially for the `count` and `sum` aggregation types.  Those aggregations
-don't scale the same way the others do, when the window changes.  Even for
-the other aggregations, changing the window could result in dramatically
-different values being generated - `avg` will be more "average-y", `min`
-and `max` will be a little stickier.
\ No newline at end of file
+The Index Threshold Alert Type is backed by Apis exposed by the [TriggersActionsUi plugin](../../../../triggers_actions_ui/README.md).
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.test.ts
index d75f3af22ab06..0febe805af4e0 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.test.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.test.ts
@@ -9,14 +9,12 @@ import { getAlertType } from './alert_type';
 import { Params } from './alert_type_params';
 
 describe('alertType', () => {
-  const service = {
-    indexThreshold: {
-      timeSeriesQuery: jest.fn(),
-    },
-    logger: loggingSystemMock.create().get(),
+  const logger = loggingSystemMock.create().get();
+  const data = {
+    timeSeriesQuery: jest.fn(),
   };
 
-  const alertType = getAlertType(service);
+  const alertType = getAlertType(logger, Promise.resolve(data));
 
   it('alert type creation structure is the expected value', async () => {
     expect(alertType.id).toBe('.index-threshold');
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.ts
index e0a9cd981dac0..2d9e1b3adc1b8 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.ts
@@ -5,23 +5,26 @@
  */
 
 import { i18n } from '@kbn/i18n';
-import { AlertType, AlertExecutorOptions } from '../../types';
+import { Logger } from 'src/core/server';
+import { AlertType, AlertExecutorOptions, StackAlertsStartDeps } from '../../types';
 import { Params, ParamsSchema } from './alert_type_params';
 import { ActionContext, BaseActionContext, addMessages } from './action_context';
-import { TimeSeriesQuery } from './lib/time_series_query';
-import { Service } from '../../types';
 import { STACK_ALERTS_FEATURE_ID } from '../../../common';
+import {
+  CoreQueryParamsSchemaProperties,
+  TimeSeriesQuery,
+} from '../../../../triggers_actions_ui/server';
 
 export const ID = '.index-threshold';
 
-import { CoreQueryParamsSchemaProperties } from './lib/core_query_types';
 const ActionGroupId = 'threshold met';
 const ComparatorFns = getComparatorFns();
 export const ComparatorFnNames = new Set(ComparatorFns.keys());
 
-export function getAlertType(service: Service): AlertType<Params, {}, {}, ActionContext> {
-  const { logger } = service;
-
+export function getAlertType(
+  logger: Logger,
+  data: Promise<StackAlertsStartDeps['triggersActionsUi']['data']>
+): AlertType<Params, {}, {}, ActionContext> {
   const alertTypeName = i18n.translate('xpack.stackAlerts.indexThreshold.alertTypeTitle', {
     defaultMessage: 'Index threshold',
   });
@@ -152,7 +155,7 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
       interval: undefined,
     };
     // console.log(`index_threshold: query: ${JSON.stringify(queryParams, null, 4)}`);
-    const result = await service.indexThreshold.timeSeriesQuery({
+    const result = await (await data).timeSeriesQuery({
       logger,
       callCluster,
       query: queryParams,
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.test.ts
index 3b771403b8b1a..8350193b2fd0b 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.test.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.test.ts
@@ -5,9 +5,9 @@
  */
 
 import { ParamsSchema, Params } from './alert_type_params';
-import { runTests } from './lib/core_query_types.test';
-import { TypeOf } from '@kbn/config-schema';
+import { ObjectType, TypeOf } from '@kbn/config-schema';
 import type { Writable } from '@kbn/utility-types';
+import { CoreQueryParams, MAX_GROUPS } from '../../../../triggers_actions_ui/server';
 
 const DefaultParams: Writable<Partial<Params>> = {
   index: 'index-name',
@@ -71,3 +71,185 @@ describe('alertType Params validate()', () => {
     return ParamsSchema.validate(params);
   }
 });
+
+export function runTests(schema: ObjectType, defaultTypeParams: Record<string, unknown>): void {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let params: any;
+
+  const CoreDefaultParams: Writable<Partial<CoreQueryParams>> = {
+    index: 'index-name',
+    timeField: 'time-field',
+    aggType: 'count',
+    groupBy: 'all',
+    timeWindowSize: 5,
+    timeWindowUnit: 'm',
+  };
+
+  describe('coreQueryTypes', () => {
+    beforeEach(() => {
+      params = { ...CoreDefaultParams, ...defaultTypeParams };
+    });
+
+    it('succeeds with minimal properties', async () => {
+      expect(validate()).toBeTruthy();
+    });
+
+    it('succeeds with maximal properties', async () => {
+      params.aggType = 'avg';
+      params.aggField = 'agg-field';
+      params.groupBy = 'top';
+      params.termField = 'group-field';
+      params.termSize = 200;
+      expect(validate()).toBeTruthy();
+
+      params.index = ['index-name-1', 'index-name-2'];
+      params.aggType = 'avg';
+      params.aggField = 'agg-field';
+      params.groupBy = 'top';
+      params.termField = 'group-field';
+      params.termSize = 200;
+      expect(validate()).toBeTruthy();
+    });
+
+    it('fails for invalid index', async () => {
+      delete params.index;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[index]: expected at least one defined value but got [undefined]"`
+      );
+
+      params.index = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(`
+"[index]: types that failed validation:
+- [index.0]: expected value of type [string] but got [number]
+- [index.1]: expected value of type [array] but got [number]"
+`);
+
+      params.index = '';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(`
+"[index]: types that failed validation:
+- [index.0]: value has length [0] but it must have a minimum length of [1].
+- [index.1]: could not parse array value from json input"
+`);
+
+      params.index = ['', 'a'];
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(`
+"[index]: types that failed validation:
+- [index.0]: expected value of type [string] but got [Array]
+- [index.1.0]: value has length [0] but it must have a minimum length of [1]."
+`);
+    });
+
+    it('fails for invalid timeField', async () => {
+      delete params.timeField;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeField]: expected value of type [string] but got [undefined]"`
+      );
+
+      params.timeField = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeField]: expected value of type [string] but got [number]"`
+      );
+
+      params.timeField = '';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeField]: value has length [0] but it must have a minimum length of [1]."`
+      );
+    });
+
+    it('fails for invalid aggType', async () => {
+      params.aggType = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[aggType]: expected value of type [string] but got [number]"`
+      );
+
+      params.aggType = '-not-a-valid-aggType-';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[aggType]: invalid aggType: \\"-not-a-valid-aggType-\\""`
+      );
+    });
+
+    it('fails for invalid aggField', async () => {
+      params.aggField = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[aggField]: expected value of type [string] but got [number]"`
+      );
+
+      params.aggField = '';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[aggField]: value has length [0] but it must have a minimum length of [1]."`
+      );
+    });
+
+    it('fails for invalid termField', async () => {
+      params.groupBy = 'top';
+      params.termField = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[termField]: expected value of type [string] but got [number]"`
+      );
+
+      params.termField = '';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[termField]: value has length [0] but it must have a minimum length of [1]."`
+      );
+    });
+
+    it('fails for invalid termSize', async () => {
+      params.groupBy = 'top';
+      params.termField = 'fee';
+      params.termSize = 'foo';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[termSize]: expected value of type [number] but got [string]"`
+      );
+
+      params.termSize = MAX_GROUPS + 1;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[termSize]: must be less than or equal to 1000"`
+      );
+
+      params.termSize = 0;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[termSize]: Value must be equal to or greater than [1]."`
+      );
+    });
+
+    it('fails for invalid timeWindowSize', async () => {
+      params.timeWindowSize = 'foo';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeWindowSize]: expected value of type [number] but got [string]"`
+      );
+
+      params.timeWindowSize = 0;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeWindowSize]: Value must be equal to or greater than [1]."`
+      );
+    });
+
+    it('fails for invalid timeWindowUnit', async () => {
+      params.timeWindowUnit = 42;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeWindowUnit]: expected value of type [string] but got [number]"`
+      );
+
+      params.timeWindowUnit = 'x';
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[timeWindowUnit]: invalid timeWindowUnit: \\"x\\""`
+      );
+    });
+
+    it('fails for invalid aggType/aggField', async () => {
+      params.aggType = 'avg';
+      delete params.aggField;
+      expect(onValidate()).toThrowErrorMatchingInlineSnapshot(
+        `"[aggField]: must have a value when [aggType] is \\"avg\\""`
+      );
+    });
+  });
+
+  function onValidate(): () => void {
+    return () => validate();
+  }
+
+  function validate(): unknown {
+    return schema.validate(params);
+  }
+}
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.ts
index 34d74fa98f959..b51545770dd7b 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type_params.ts
@@ -7,7 +7,10 @@
 import { i18n } from '@kbn/i18n';
 import { schema, TypeOf } from '@kbn/config-schema';
 import { ComparatorFnNames, getInvalidComparatorMessage } from './alert_type';
-import { CoreQueryParamsSchemaProperties, validateCoreQueryBody } from './lib/core_query_types';
+import {
+  CoreQueryParamsSchemaProperties,
+  validateCoreQueryBody,
+} from '../../../../triggers_actions_ui/server';
 
 // alert type parameters
 
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/index.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/index.ts
index 9787ece323c59..a075b0d614cbb 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/index.ts
+++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/index.ts
@@ -4,34 +4,22 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Service, AlertingSetup, IRouter } from '../../types';
-import { timeSeriesQuery } from './lib/time_series_query';
+import { Logger } from 'src/core/server';
+import { AlertingSetup, StackAlertsStartDeps } from '../../types';
 import { getAlertType } from './alert_type';
-import { registerRoutes } from './routes';
 
 // future enhancement: make these configurable?
 export const MAX_INTERVALS = 1000;
 export const MAX_GROUPS = 1000;
 export const DEFAULT_GROUPS = 100;
 
-export function getService() {
-  return {
-    timeSeriesQuery,
-  };
-}
-
 interface RegisterParams {
-  service: Service;
-  router: IRouter;
+  logger: Logger;
+  data: Promise<StackAlertsStartDeps['triggersActionsUi']['data']>;
   alerts: AlertingSetup;
-  baseRoute: string;
 }
 
 export function register(params: RegisterParams) {
-  const { service, router, alerts, baseRoute } = params;
-
-  alerts.registerType(getAlertType(service));
-
-  const baseBuiltInRoute = `${baseRoute}/index_threshold`;
-  registerRoutes({ service, router, baseRoute: baseBuiltInRoute });
+  const { logger, data, alerts } = params;
+  alerts.registerType(getAlertType(logger, data));
 }
diff --git a/x-pack/plugins/stack_alerts/server/index.ts b/x-pack/plugins/stack_alerts/server/index.ts
index 108393c0d1469..adb617558e6f4 100644
--- a/x-pack/plugins/stack_alerts/server/index.ts
+++ b/x-pack/plugins/stack_alerts/server/index.ts
@@ -4,15 +4,22 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { PluginInitializerContext } from 'src/core/server';
+import { PluginConfigDescriptor, PluginInitializerContext } from 'src/core/server';
 import { AlertingBuiltinsPlugin } from './plugin';
-import { configSchema } from './config';
+import { configSchema, Config } from '../common/config';
 export { ID as INDEX_THRESHOLD_ID } from './alert_types/index_threshold/alert_type';
 
-export const plugin = (ctx: PluginInitializerContext) => new AlertingBuiltinsPlugin(ctx);
-
-export const config = {
+export const config: PluginConfigDescriptor<Config> = {
+  exposeToBrowser: {
+    enableGeoTrackingThresholdAlert: true,
+  },
   schema: configSchema,
+  deprecations: ({ renameFromRoot }) => [
+    renameFromRoot(
+      'xpack.triggers_actions_ui.enableGeoTrackingThresholdAlert',
+      'xpack.stack_alerts.enableGeoTrackingThresholdAlert'
+    ),
+  ],
 };
 
-export { IService } from './types';
+export const plugin = (ctx: PluginInitializerContext) => new AlertingBuiltinsPlugin(ctx);
diff --git a/x-pack/plugins/stack_alerts/server/plugin.test.ts b/x-pack/plugins/stack_alerts/server/plugin.test.ts
index 3e2a919be0f13..71972707852fe 100644
--- a/x-pack/plugins/stack_alerts/server/plugin.test.ts
+++ b/x-pack/plugins/stack_alerts/server/plugin.test.ts
@@ -69,34 +69,5 @@ describe('AlertingBuiltins Plugin', () => {
 
       expect(featuresSetup.registerKibanaFeature).toHaveBeenCalledWith(BUILT_IN_ALERTS_FEATURE);
     });
-
-    it('should return a service in the expected shape', async () => {
-      const alertingSetup = alertsMock.createSetup();
-      const featuresSetup = featuresPluginMock.createSetup();
-      const service = await plugin.setup(coreSetup, {
-        alerts: alertingSetup,
-        features: featuresSetup,
-      });
-
-      expect(typeof service.indexThreshold.timeSeriesQuery).toBe('function');
-    });
-  });
-
-  describe('start()', () => {
-    let context: ReturnType<typeof coreMock['createPluginInitializerContext']>;
-    let plugin: AlertingBuiltinsPlugin;
-    let coreStart: ReturnType<typeof coreMock['createStart']>;
-
-    beforeEach(() => {
-      context = coreMock.createPluginInitializerContext();
-      plugin = new AlertingBuiltinsPlugin(context);
-      coreStart = coreMock.createStart();
-    });
-
-    it('should return a service in the expected shape', async () => {
-      const service = await plugin.start(coreStart);
-
-      expect(typeof service.indexThreshold.timeSeriesQuery).toBe('function');
-    });
   });
 });
diff --git a/x-pack/plugins/stack_alerts/server/plugin.ts b/x-pack/plugins/stack_alerts/server/plugin.ts
index f250bbc70fb80..66ac9e455e8b6 100644
--- a/x-pack/plugins/stack_alerts/server/plugin.ts
+++ b/x-pack/plugins/stack_alerts/server/plugin.ts
@@ -4,40 +4,35 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Plugin, Logger, CoreSetup, CoreStart, PluginInitializerContext } from 'src/core/server';
+import { Plugin, Logger, CoreSetup, PluginInitializerContext } from 'src/core/server';
 
-import { Service, IService, StackAlertsDeps } from './types';
-import { getService as getServiceIndexThreshold } from './alert_types/index_threshold';
+import { StackAlertsDeps, StackAlertsStartDeps } from './types';
 import { registerBuiltInAlertTypes } from './alert_types';
 import { BUILT_IN_ALERTS_FEATURE } from './feature';
 
-export class AlertingBuiltinsPlugin implements Plugin<IService, IService> {
+export class AlertingBuiltinsPlugin
+  implements Plugin<void, void, StackAlertsDeps, StackAlertsStartDeps> {
   private readonly logger: Logger;
-  private readonly service: Service;
 
   constructor(ctx: PluginInitializerContext) {
     this.logger = ctx.logger.get();
-    this.service = {
-      indexThreshold: getServiceIndexThreshold(),
-      logger: this.logger,
-    };
   }
 
-  public async setup(core: CoreSetup, { alerts, features }: StackAlertsDeps): Promise<IService> {
+  public async setup(
+    core: CoreSetup<StackAlertsStartDeps>,
+    { alerts, features }: StackAlertsDeps
+  ): Promise<void> {
     features.registerKibanaFeature(BUILT_IN_ALERTS_FEATURE);
 
     registerBuiltInAlertTypes({
-      service: this.service,
-      router: core.http.createRouter(),
+      logger: this.logger,
+      data: core
+        .getStartServices()
+        .then(async ([, { triggersActionsUi }]) => triggersActionsUi.data),
       alerts,
-      baseRoute: '/api/stack_alerts',
     });
-    return this.service;
-  }
-
-  public async start(core: CoreStart): Promise<IService> {
-    return this.service;
   }
 
+  public async start(): Promise<void> {}
   public async stop(): Promise<void> {}
 }
diff --git a/x-pack/plugins/stack_alerts/server/types.ts b/x-pack/plugins/stack_alerts/server/types.ts
index d0eb8aa768915..e37596e8ff970 100644
--- a/x-pack/plugins/stack_alerts/server/types.ts
+++ b/x-pack/plugins/stack_alerts/server/types.ts
@@ -4,11 +4,8 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Logger, LegacyScopedClusterClient } from '../../../../src/core/server';
+import { PluginStartContract as TriggersActionsUiStartContract } from '../../triggers_actions_ui/server';
 import { PluginSetupContract as AlertingSetup } from '../../alerts/server';
-import { getService as getServiceIndexThreshold } from './alert_types/index_threshold';
-
-export { Logger, IRouter } from '../../../../src/core/server';
 
 export {
   PluginSetupContract as AlertingSetup,
@@ -23,14 +20,6 @@ export interface StackAlertsDeps {
   features: FeaturesPluginSetup;
 }
 
-// external service exposed through plugin setup/start
-export interface IService {
-  indexThreshold: ReturnType<typeof getServiceIndexThreshold>;
-}
-
-// version of service for internal use
-export interface Service extends IService {
-  logger: Logger;
+export interface StackAlertsStartDeps {
+  triggersActionsUi: TriggersActionsUiStartContract;
 }
-
-export type CallCluster = LegacyScopedClusterClient['callAsCurrentUser'];
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 852c3ffd9bfd6..1892174550a1f 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -19532,24 +19532,24 @@
     "xpack.stackAlerts.indexThreshold.actionVariableContextThresholdLabel": "しきい値として使用する値の配列。「between」と「notBetween」には2つの値が必要です。その他は1つの値が必要です。",
     "xpack.stackAlerts.indexThreshold.actionVariableContextTitleLabel": "アラートの事前構成タイトル。",
     "xpack.stackAlerts.indexThreshold.actionVariableContextValueLabel": "しきい値を超えた値。",
-    "xpack.stackAlerts.indexThreshold.aggTypeRequiredErrorMessage": "[aggType]が「{aggType}」のときには[aggField]に値が必要です",
+    "xpack.triggersActionsUI.data.coreQueryParams.aggTypeRequiredErrorMessage": "[aggType]が「{aggType}」のときには[aggField]に値が必要です",
     "xpack.stackAlerts.indexThreshold.alertTypeContextMessageDescription": "アラート{name}グループ{group}値{value}が{date}に{window}にわたってしきい値{function}を超えました",
     "xpack.stackAlerts.indexThreshold.alertTypeContextSubjectTitle": "アラート{name}グループ{group}がしきい値を超えました",
     "xpack.stackAlerts.indexThreshold.alertTypeTitle": "インデックスしきい値",
-    "xpack.stackAlerts.indexThreshold.dateStartGTdateEndErrorMessage": "[dateStart]が[dateEnd]よりも大です",
-    "xpack.stackAlerts.indexThreshold.formattedFieldErrorMessage": "{fieldName}の無効な{formatName}形式:「{fieldValue}」",
-    "xpack.stackAlerts.indexThreshold.intervalRequiredErrorMessage": "[interval]: [dateStart]が[dateEnd]と等しくない場合に指定する必要があります",
-    "xpack.stackAlerts.indexThreshold.invalidAggTypeErrorMessage": "無効な aggType:「{aggType}」",
+    "xpack.triggersActionsUI.data.coreQueryParams.dateStartGTdateEndErrorMessage": "[dateStart]が[dateEnd]よりも大です",
+    "xpack.triggersActionsUI.data.coreQueryParams.formattedFieldErrorMessage": "{fieldName}の無効な{formatName}形式:「{fieldValue}」",
+    "xpack.triggersActionsUI.data.coreQueryParams.intervalRequiredErrorMessage": "[interval]: [dateStart]が[dateEnd]と等しくない場合に指定する必要があります",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidAggTypeErrorMessage": "無効な aggType:「{aggType}」",
     "xpack.stackAlerts.indexThreshold.invalidComparatorErrorMessage": "無効なthresholdComparatorが指定されました: {comparator}",
-    "xpack.stackAlerts.indexThreshold.invalidDateErrorMessage": "無効な日付{date}",
-    "xpack.stackAlerts.indexThreshold.invalidDurationErrorMessage": "無効な期間:「{duration}」",
-    "xpack.stackAlerts.indexThreshold.invalidGroupByErrorMessage": "無効なgroupBy:「{groupBy}」",
-    "xpack.stackAlerts.indexThreshold.invalidTermSizeMaximumErrorMessage": "[termSize]: {maxGroups}以下でなければなりません。",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidDateErrorMessage": "無効な日付{date}",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidDurationErrorMessage": "無効な期間:「{duration}」",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidGroupByErrorMessage": "無効なgroupBy:「{groupBy}」",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidTermSizeMaximumErrorMessage": "[termSize]: {maxGroups}以下でなければなりません。",
     "xpack.stackAlerts.indexThreshold.invalidThreshold2ErrorMessage": "[threshold]: 「{thresholdComparator}」比較子の場合には2つの要素が必要です",
-    "xpack.stackAlerts.indexThreshold.invalidTimeWindowUnitsErrorMessage": "無効なtimeWindowUnit:「{timeWindowUnit}」",
-    "xpack.stackAlerts.indexThreshold.maxIntervalsErrorMessage": "間隔{intervals}の計算値が{maxIntervals}よりも大です",
-    "xpack.stackAlerts.indexThreshold.termFieldRequiredErrorMessage": "[termField]: [groupBy]がトップのときにはtermFieldが必要です",
-    "xpack.stackAlerts.indexThreshold.termSizeRequiredErrorMessage": "[termSize]: [groupBy]がトップのときにはtermSizeが必要です",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidTimeWindowUnitsErrorMessage": "無効なtimeWindowUnit:「{timeWindowUnit}」",
+    "xpack.triggersActionsUI.data.coreQueryParams.maxIntervalsErrorMessage": "間隔{intervals}の計算値が{maxIntervals}よりも大です",
+    "xpack.triggersActionsUI.data.coreQueryParams.termFieldRequiredErrorMessage": "[termField]: [groupBy]がトップのときにはtermFieldが必要です",
+    "xpack.triggersActionsUI.data.coreQueryParams.termSizeRequiredErrorMessage": "[termSize]: [groupBy]がトップのときにはtermSizeが必要です",
     "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "ディスティネーションインデックスの削除",
     "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "ディスティネーションインデックスパターンの削除",
     "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "ディスティネーションインデックス{destinationIndex}の削除",
@@ -20085,42 +20085,42 @@
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.cancelButtonLabel": "キャンセル",
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.deleteButtonLabel": "{numIdsToDelete, plural, one {{singleTitle}} other {# {multipleTitle}}}を削除 ",
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.descriptionText": "{numIdsToDelete, plural, one {a deleted {singleTitle}} other {deleted {multipleTitle}}}を回復できません。",
-    "xpack.triggersActionsUI.geoThreshold.boundaryNameSelect": "境界名を選択",
-    "xpack.triggersActionsUI.geoThreshold.boundaryNameSelectLabel": "人間が読み取れる境界名(任意)",
-    "xpack.triggersActionsUI.geoThreshold.delayOffset": "遅延評価オフセット",
-    "xpack.triggersActionsUI.geoThreshold.delayOffsetTooltip": "遅延サイクルでアラートを評価し、データレイテンシに合わせて調整します",
-    "xpack.triggersActionsUI.geoThreshold.entityByLabel": "グループ基準",
-    "xpack.triggersActionsUI.geoThreshold.entityIndexLabel": "インデックス",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryGeoFieldText": "境界地理フィールドは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryIndexTitleText": "境界インデックスパターンタイトルは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryTypeText": "境界タイプは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredDateFieldText": "日付フィールドが必要です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredEntityText": "エンティティは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredGeoFieldText": "地理フィールドは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredIndexTitleText": "インデックスパターンが必要です。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredTrackingEventText": "追跡イベントは必須です。",
-    "xpack.triggersActionsUI.geoThreshold.fixErrorInExpressionBelowValidationMessage": "下の表現のエラーを修正してください。",
-    "xpack.triggersActionsUI.geoThreshold.geofieldLabel": "地理空間フィールド",
-    "xpack.triggersActionsUI.geoThreshold.indexLabel": "インデックス",
-    "xpack.triggersActionsUI.geoThreshold.indexPatternSelectLabel": "インデックスパターン",
-    "xpack.triggersActionsUI.geoThreshold.indexPatternSelectPlaceholder": "インデックスパターンを選択",
-    "xpack.triggersActionsUI.geoThreshold.name.trackingThreshold": "追跡しきい値",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisLinkTextDescription": "インデックスパターンを作成します",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisPrefixDescription": "次のことが必要です ",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisSuffixDescription": " 地理空間フィールドを含む",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.getStartedLinkText": "サンプルデータセットで始めましょう。",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.hintDescription": "地理空間データセットがありませんか? ",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.messageTitle": "地理空間フィールドを含むインデックスパターンが見つかりませんでした",
-    "xpack.triggersActionsUI.geoThreshold.selectBoundaryIndex": "境界を選択:",
-    "xpack.triggersActionsUI.geoThreshold.selectEntity": "エンティティを選択",
-    "xpack.triggersActionsUI.geoThreshold.selectGeoLabel": "ジオフィールドを選択",
-    "xpack.triggersActionsUI.geoThreshold.selectIndex": "条件を定義してください",
-    "xpack.triggersActionsUI.geoThreshold.selectLabel": "ジオフィールドを選択",
-    "xpack.triggersActionsUI.geoThreshold.selectOffset": "オフセットを選択(任意)",
-    "xpack.triggersActionsUI.geoThreshold.selectTimeLabel": "時刻フィールドを選択",
-    "xpack.triggersActionsUI.geoThreshold.timeFieldLabel": "時間フィールド",
-    "xpack.triggersActionsUI.geoThreshold.topHitsSplitFieldSelectPlaceholder": "エンティティフィールドを選択",
-    "xpack.triggersActionsUI.geoThreshold.whenEntityLabel": "エンティティ",
+    "xpack.stackAlerts.geoThreshold.boundaryNameSelect": "境界名を選択",
+    "xpack.stackAlerts.geoThreshold.boundaryNameSelectLabel": "人間が読み取れる境界名(任意)",
+    "xpack.stackAlerts.geoThreshold.delayOffset": "遅延評価オフセット",
+    "xpack.stackAlerts.geoThreshold.delayOffsetTooltip": "遅延サイクルでアラートを評価し、データレイテンシに合わせて調整します",
+    "xpack.stackAlerts.geoThreshold.entityByLabel": "グループ基準",
+    "xpack.stackAlerts.geoThreshold.entityIndexLabel": "インデックス",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryGeoFieldText": "境界地理フィールドは必須です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryIndexTitleText": "境界インデックスパターンタイトルは必須です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryTypeText": "境界タイプは必須です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredDateFieldText": "日付フィールドが必要です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredEntityText": "エンティティは必須です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredGeoFieldText": "地理フィールドは必須です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredIndexTitleText": "インデックスパターンが必要です。",
+    "xpack.stackAlerts.geoThreshold.error.requiredTrackingEventText": "追跡イベントは必須です。",
+    "xpack.stackAlerts.geoThreshold.fixErrorInExpressionBelowValidationMessage": "下の表現のエラーを修正してください。",
+    "xpack.stackAlerts.geoThreshold.geofieldLabel": "地理空間フィールド",
+    "xpack.stackAlerts.geoThreshold.indexLabel": "インデックス",
+    "xpack.stackAlerts.geoThreshold.indexPatternSelectLabel": "インデックスパターン",
+    "xpack.stackAlerts.geoThreshold.indexPatternSelectPlaceholder": "インデックスパターンを選択",
+    "xpack.stackAlerts.geoThreshold.name.trackingThreshold": "追跡しきい値",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisLinkTextDescription": "インデックスパターンを作成します",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisPrefixDescription": "次のことが必要です ",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisSuffixDescription": " 地理空間フィールドを含む",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.getStartedLinkText": "サンプルデータセットで始めましょう。",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.hintDescription": "地理空間データセットがありませんか? ",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.messageTitle": "地理空間フィールドを含むインデックスパターンが見つかりませんでした",
+    "xpack.stackAlerts.geoThreshold.selectBoundaryIndex": "境界を選択:",
+    "xpack.stackAlerts.geoThreshold.selectEntity": "エンティティを選択",
+    "xpack.stackAlerts.geoThreshold.selectGeoLabel": "ジオフィールドを選択",
+    "xpack.stackAlerts.geoThreshold.selectIndex": "条件を定義してください",
+    "xpack.stackAlerts.geoThreshold.selectLabel": "ジオフィールドを選択",
+    "xpack.stackAlerts.geoThreshold.selectOffset": "オフセットを選択(任意)",
+    "xpack.stackAlerts.geoThreshold.selectTimeLabel": "時刻フィールドを選択",
+    "xpack.stackAlerts.geoThreshold.timeFieldLabel": "時間フィールド",
+    "xpack.stackAlerts.geoThreshold.topHitsSplitFieldSelectPlaceholder": "エンティティフィールドを選択",
+    "xpack.stackAlerts.geoThreshold.whenEntityLabel": "エンティティ",
     "xpack.triggersActionsUI.home.alertsTabTitle": "アラート",
     "xpack.triggersActionsUI.home.appTitle": "アラートとアクション",
     "xpack.triggersActionsUI.home.breadcrumbTitle": "アラートとアクション",
@@ -20163,15 +20163,15 @@
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderValueText": "値が必要です。",
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredMethodText": "メソッドが必要です",
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredPasswordText": "パスワードが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.greaterThenThreshold0Text": "しきい値 1 はしきい値 0 よりも大きい値にしてください。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredAggFieldText": "集約フィールドが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredIndexText": "インデックスが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTermSizedText": "用語サイズが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold0Text": "しきい値 0 が必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold1Text": "しきい値 1 が必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeFieldText": "時間フィールドが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeWindowSizeText": "時間ウィンドウサイズが必要です。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredtTermFieldText": "用語フィールドが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.greaterThenThreshold0Text": "しきい値 1 はしきい値 0 よりも大きい値にしてください。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredAggFieldText": "集約フィールドが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredIndexText": "インデックスが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTermSizedText": "用語サイズが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold0Text": "しきい値 0 が必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold1Text": "しきい値 1 が必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTimeFieldText": "時間フィールドが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTimeWindowSizeText": "時間ウィンドウサイズが必要です。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTermFieldText": "用語フィールドが必要です。",
     "xpack.triggersActionsUI.sections.addConnectorForm.flyoutTitle": "{actionTypeName} コネクタ",
     "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "コネクターを選択",
     "xpack.triggersActionsUI.sections.addConnectorForm.updateErrorNotificationText": "コネクターを作成できません。",
@@ -20180,27 +20180,27 @@
     "xpack.triggersActionsUI.sections.addModalConnectorForm.flyoutTitle": "{actionTypeName} コネクター",
     "xpack.triggersActionsUI.sections.addModalConnectorForm.saveButtonLabel": "保存",
     "xpack.triggersActionsUI.sections.addModalConnectorForm.updateSuccessNotificationText": "「{connectorName}」を作成しました",
-    "xpack.triggersActionsUI.sections.alertAdd.conditionPrompt": "条件を定義してください",
-    "xpack.triggersActionsUI.sections.alertAdd.errorLoadingAlertVisualizationTitle": "アラートビジュアライゼーションを読み込めません",
+    "xpack.stackAlerts.threshold.ui.conditionPrompt": "条件を定義してください",
+    "xpack.stackAlerts.threshold.ui.visualization.errorLoadingAlertVisualizationTitle": "アラートビジュアライゼーションを読み込めません",
     "xpack.triggersActionsUI.sections.alertAdd.flyoutTitle": "アラートの作成",
-    "xpack.triggersActionsUI.sections.alertAdd.geoThreshold.closePopoverLabel": "閉じる",
-    "xpack.triggersActionsUI.sections.alertAdd.loadingAlertVisualizationDescription": "アラートビジュアライゼーションを読み込み中...",
+    "xpack.stackAlerts.geoThreshold.ui.expressionPopover.closePopoverLabel": "閉じる",
+    "xpack.stackAlerts.threshold.ui.visualization.loadingAlertVisualizationDescription": "アラートビジュアライゼーションを読み込み中...",
     "xpack.triggersActionsUI.sections.alertAdd.operationName": "作成",
-    "xpack.triggersActionsUI.sections.alertAdd.previewAlertVisualizationDescription": "プレビューを生成するための式を完成します。",
+    "xpack.stackAlerts.threshold.ui.previewAlertVisualizationDescription": "プレビューを生成するための式を完成します。",
     "xpack.triggersActionsUI.sections.alertAdd.saveErrorNotificationText": "アラートを作成できません。",
     "xpack.triggersActionsUI.sections.alertAdd.saveSuccessNotificationText": "「{alertName}」 を保存しました",
-    "xpack.triggersActionsUI.sections.alertAdd.selectIndex": "インデックスを選択してください",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.closeIndexPopoverLabel": "閉じる",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage": "下の表現のエラーを修正してください。",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.howToBroadenSearchQueryDescription": "* で検索クエリの範囲を広げます。",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indexButtonLabel": "インデックス",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indexLabel": "インデックス",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indicesToQueryLabel": "クエリを実行するインデックス",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldLabel": "時間フィールド",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldOptionLabel": "フィールドを選択",
-    "xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.dataDoesNotExistTextMessage": "時間範囲とフィルターが正しいことを確認してください。",
-    "xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.noDataTitle": "このクエリに一致するデータはありません",
-    "xpack.triggersActionsUI.sections.alertAdd.unableToLoadVisualizationMessage": "ビジュアライゼーションを読み込めません",
+    "xpack.stackAlerts.threshold.ui.selectIndex": "インデックスを選択してください",
+    "xpack.stackAlerts.threshold.ui.alertParams.closeIndexPopoverLabel": "閉じる",
+    "xpack.stackAlerts.threshold.ui.alertParams.fixErrorInExpressionBelowValidationMessage": "下の表現のエラーを修正してください。",
+    "xpack.stackAlerts.threshold.ui.alertParams.howToBroadenSearchQueryDescription": "* で検索クエリの範囲を広げます。",
+    "xpack.stackAlerts.threshold.ui.alertParams.indexButtonLabel": "インデックス",
+    "xpack.stackAlerts.threshold.ui.alertParams.indexLabel": "インデックス",
+    "xpack.stackAlerts.threshold.ui.alertParams.indicesToQueryLabel": "クエリを実行するインデックス",
+    "xpack.stackAlerts.threshold.ui.alertParams.timeFieldLabel": "時間フィールド",
+    "xpack.triggersActionsUI.sections.alertAdd.indexControls.timeFieldOptionLabel": "フィールドを選択",
+    "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.dataDoesNotExistTextMessage": "時間範囲とフィルターが正しいことを確認してください。",
+    "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.noDataTitle": "このクエリに一致するデータはありません",
+    "xpack.stackAlerts.threshold.ui.visualization.unableToLoadVisualizationMessage": "ビジュアライゼーションを読み込めません",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstances.disabledAlert": "このアラートは無効になっていて再表示できません。[↑ を無効にする]を切り替えてアクティブにします。",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.duration": "期間",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.instance": "インスタンス",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 461b93e2e081d..65b7f4dfe9f27 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -19551,24 +19551,24 @@
     "xpack.stackAlerts.indexThreshold.actionVariableContextThresholdLabel": "用作阈值的值数组;“between”和“notBetween”需要两个值,其他则需要一个值。",
     "xpack.stackAlerts.indexThreshold.actionVariableContextTitleLabel": "告警的预构造标题。",
     "xpack.stackAlerts.indexThreshold.actionVariableContextValueLabel": "超过阈值的值。",
-    "xpack.stackAlerts.indexThreshold.aggTypeRequiredErrorMessage": "[aggField]:当 [aggType] 为“{aggType}”时必须有值",
+    "xpack.triggersActionsUI.data.coreQueryParams.aggTypeRequiredErrorMessage": "[aggField]:当 [aggType] 为“{aggType}”时必须有值",
     "xpack.stackAlerts.indexThreshold.alertTypeContextMessageDescription": "告警 {name} 组 {group} 值 {value} 在 {window} 于 {date}超过了阈值 {function}",
     "xpack.stackAlerts.indexThreshold.alertTypeContextSubjectTitle": "告警 {name} 组 {group} 超过了阈值",
     "xpack.stackAlerts.indexThreshold.alertTypeTitle": "索引阈值",
-    "xpack.stackAlerts.indexThreshold.dateStartGTdateEndErrorMessage": "[dateStart]:晚于 [dateEnd]",
-    "xpack.stackAlerts.indexThreshold.formattedFieldErrorMessage": "{fieldName} 的 {formatName} 格式无效:“{fieldValue}”",
-    "xpack.stackAlerts.indexThreshold.intervalRequiredErrorMessage": "[interval]:如果 [dateStart] 不等于 [dateEnd],则必须指定",
-    "xpack.stackAlerts.indexThreshold.invalidAggTypeErrorMessage": "aggType 无效:“{aggType}”",
+    "xpack.triggersActionsUI.data.coreQueryParams.dateStartGTdateEndErrorMessage": "[dateStart]:晚于 [dateEnd]",
+    "xpack.triggersActionsUI.data.coreQueryParams.formattedFieldErrorMessage": "{fieldName} 的 {formatName} 格式无效:“{fieldValue}”",
+    "xpack.triggersActionsUI.data.coreQueryParams.intervalRequiredErrorMessage": "[interval]:如果 [dateStart] 不等于 [dateEnd],则必须指定",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidAggTypeErrorMessage": "aggType 无效:“{aggType}”",
     "xpack.stackAlerts.indexThreshold.invalidComparatorErrorMessage": "指定的 thresholdComparator 无效:{comparator}",
-    "xpack.stackAlerts.indexThreshold.invalidDateErrorMessage": "日期 {date} 无效",
-    "xpack.stackAlerts.indexThreshold.invalidDurationErrorMessage": "持续时间无效:“{duration}”",
-    "xpack.stackAlerts.indexThreshold.invalidGroupByErrorMessage": "groupBy 无效:“{groupBy}”",
-    "xpack.stackAlerts.indexThreshold.invalidTermSizeMaximumErrorMessage": "[termSize]:必须小于或等于 {maxGroups}",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidDateErrorMessage": "日期 {date} 无效",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidDurationErrorMessage": "持续时间无效:“{duration}”",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidGroupByErrorMessage": "groupBy 无效:“{groupBy}”",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidTermSizeMaximumErrorMessage": "[termSize]:必须小于或等于 {maxGroups}",
     "xpack.stackAlerts.indexThreshold.invalidThreshold2ErrorMessage": "[threshold]:对于“{thresholdComparator}”比较运算符,必须包含两个元素",
-    "xpack.stackAlerts.indexThreshold.invalidTimeWindowUnitsErrorMessage": "timeWindowUnit 无效:“{timeWindowUnit}”",
-    "xpack.stackAlerts.indexThreshold.maxIntervalsErrorMessage": "时间间隔 {intervals} 的计算数目大于最大值 {maxIntervals}",
-    "xpack.stackAlerts.indexThreshold.termFieldRequiredErrorMessage": "[termField]:[groupBy] 为 top 时,termField 为必需",
-    "xpack.stackAlerts.indexThreshold.termSizeRequiredErrorMessage": "[termSize]:[groupBy] 为 top 时,termSize 为必需",
+    "xpack.triggersActionsUI.data.coreQueryParams.invalidTimeWindowUnitsErrorMessage": "timeWindowUnit 无效:“{timeWindowUnit}”",
+    "xpack.triggersActionsUI.data.coreQueryParams.maxIntervalsErrorMessage": "时间间隔 {intervals} 的计算数目大于最大值 {maxIntervals}",
+    "xpack.triggersActionsUI.data.coreQueryParams.termFieldRequiredErrorMessage": "[termField]:[groupBy] 为 top 时,termField 为必需",
+    "xpack.triggersActionsUI.data.coreQueryParams.termSizeRequiredErrorMessage": "[termSize]:[groupBy] 为 top 时,termSize 为必需",
     "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "删除目标索引",
     "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "删除目标索引模式",
     "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "删除目标索引 {destinationIndex}",
@@ -20104,42 +20104,42 @@
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.cancelButtonLabel": "取消",
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.deleteButtonLabel": "删除{numIdsToDelete, plural, one {{singleTitle}} other { # 个{multipleTitle}}} ",
     "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.descriptionText": "无法恢复{numIdsToDelete, plural, one {删除的{singleTitle}} other {删除的{multipleTitle}}}。",
-    "xpack.triggersActionsUI.geoThreshold.boundaryNameSelect": "选择边界名称",
-    "xpack.triggersActionsUI.geoThreshold.boundaryNameSelectLabel": "可人工读取的边界名称(可选)",
-    "xpack.triggersActionsUI.geoThreshold.delayOffset": "已延迟的评估偏移",
-    "xpack.triggersActionsUI.geoThreshold.delayOffsetTooltip": "评估延迟周期内的告警,以针对数据延迟进行调整",
-    "xpack.triggersActionsUI.geoThreshold.entityByLabel": "方式",
-    "xpack.triggersActionsUI.geoThreshold.entityIndexLabel": "索引",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryGeoFieldText": "“边界地理”字段必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryIndexTitleText": "“边界索引模式标题”必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredBoundaryTypeText": "“边界类型”必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredDateFieldText": "“日期”字段必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredEntityText": "“实体”必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredGeoFieldText": "“地理”字段必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredIndexTitleText": "“索引模式”必填。",
-    "xpack.triggersActionsUI.geoThreshold.error.requiredTrackingEventText": "“跟踪事件”必填。",
-    "xpack.triggersActionsUI.geoThreshold.fixErrorInExpressionBelowValidationMessage": "表达式包含错误。",
-    "xpack.triggersActionsUI.geoThreshold.geofieldLabel": "地理空间字段",
-    "xpack.triggersActionsUI.geoThreshold.indexLabel": "索引",
-    "xpack.triggersActionsUI.geoThreshold.indexPatternSelectLabel": "索引模式",
-    "xpack.triggersActionsUI.geoThreshold.indexPatternSelectPlaceholder": "选择索引模式",
-    "xpack.triggersActionsUI.geoThreshold.name.trackingThreshold": "跟踪阈值",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisLinkTextDescription": "创建索引模式",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisPrefixDescription": "您将需要 ",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.doThisSuffixDescription": " (包含地理空间字段)。",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.getStartedLinkText": "开始使用一些样例数据集。",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.hintDescription": "没有任何地理空间数据集? ",
-    "xpack.triggersActionsUI.geoThreshold.noIndexPattern.messageTitle": "找不到任何具有地理空间字段的索引模式",
-    "xpack.triggersActionsUI.geoThreshold.selectBoundaryIndex": "选择边界:",
-    "xpack.triggersActionsUI.geoThreshold.selectEntity": "选择实体",
-    "xpack.triggersActionsUI.geoThreshold.selectGeoLabel": "选择地理字段",
-    "xpack.triggersActionsUI.geoThreshold.selectIndex": "定义条件",
-    "xpack.triggersActionsUI.geoThreshold.selectLabel": "选择地理字段",
-    "xpack.triggersActionsUI.geoThreshold.selectOffset": "选择偏移(可选)",
-    "xpack.triggersActionsUI.geoThreshold.selectTimeLabel": "选择时间字段",
-    "xpack.triggersActionsUI.geoThreshold.timeFieldLabel": "时间字段",
-    "xpack.triggersActionsUI.geoThreshold.topHitsSplitFieldSelectPlaceholder": "选择实体字段",
-    "xpack.triggersActionsUI.geoThreshold.whenEntityLabel": "当实体",
+    "xpack.stackAlerts.geoThreshold.boundaryNameSelect": "选择边界名称",
+    "xpack.stackAlerts.geoThreshold.boundaryNameSelectLabel": "可人工读取的边界名称(可选)",
+    "xpack.stackAlerts.geoThreshold.delayOffset": "已延迟的评估偏移",
+    "xpack.stackAlerts.geoThreshold.delayOffsetTooltip": "评估延迟周期内的告警,以针对数据延迟进行调整",
+    "xpack.stackAlerts.geoThreshold.entityByLabel": "方式",
+    "xpack.stackAlerts.geoThreshold.entityIndexLabel": "索引",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryGeoFieldText": "“边界地理”字段必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryIndexTitleText": "“边界索引模式标题”必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredBoundaryTypeText": "“边界类型”必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredDateFieldText": "“日期”字段必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredEntityText": "“实体”必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredGeoFieldText": "“地理”字段必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredIndexTitleText": "“索引模式”必填。",
+    "xpack.stackAlerts.geoThreshold.error.requiredTrackingEventText": "“跟踪事件”必填。",
+    "xpack.stackAlerts.geoThreshold.fixErrorInExpressionBelowValidationMessage": "表达式包含错误。",
+    "xpack.stackAlerts.geoThreshold.geofieldLabel": "地理空间字段",
+    "xpack.stackAlerts.geoThreshold.indexLabel": "索引",
+    "xpack.stackAlerts.geoThreshold.indexPatternSelectLabel": "索引模式",
+    "xpack.stackAlerts.geoThreshold.indexPatternSelectPlaceholder": "选择索引模式",
+    "xpack.stackAlerts.geoThreshold.name.trackingThreshold": "跟踪阈值",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisLinkTextDescription": "创建索引模式",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisPrefixDescription": "您将需要 ",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.doThisSuffixDescription": " (包含地理空间字段)。",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.getStartedLinkText": "开始使用一些样例数据集。",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.hintDescription": "没有任何地理空间数据集? ",
+    "xpack.stackAlerts.geoThreshold.noIndexPattern.messageTitle": "找不到任何具有地理空间字段的索引模式",
+    "xpack.stackAlerts.geoThreshold.selectBoundaryIndex": "选择边界:",
+    "xpack.stackAlerts.geoThreshold.selectEntity": "选择实体",
+    "xpack.stackAlerts.geoThreshold.selectGeoLabel": "选择地理字段",
+    "xpack.stackAlerts.geoThreshold.selectIndex": "定义条件",
+    "xpack.stackAlerts.geoThreshold.selectLabel": "选择地理字段",
+    "xpack.stackAlerts.geoThreshold.selectOffset": "选择偏移(可选)",
+    "xpack.stackAlerts.geoThreshold.selectTimeLabel": "选择时间字段",
+    "xpack.stackAlerts.geoThreshold.timeFieldLabel": "时间字段",
+    "xpack.stackAlerts.geoThreshold.topHitsSplitFieldSelectPlaceholder": "选择实体字段",
+    "xpack.stackAlerts.geoThreshold.whenEntityLabel": "当实体",
     "xpack.triggersActionsUI.home.alertsTabTitle": "告警",
     "xpack.triggersActionsUI.home.appTitle": "告警和操作",
     "xpack.triggersActionsUI.home.breadcrumbTitle": "告警和操作",
@@ -20183,15 +20183,15 @@
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderValueText": "“值”必填。",
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredMethodText": "“方法”必填",
     "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredPasswordText": "“密码”必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.greaterThenThreshold0Text": "阈值 1 应 > 阈值 0。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredAggFieldText": "聚合字段必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredIndexText": "“索引”必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTermSizedText": "“词大小”必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold0Text": "阈值 0 必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredThreshold1Text": "阈值 1 必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeFieldText": "时间字段必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeWindowSizeText": "“时间窗大小”必填。",
-    "xpack.triggersActionsUI.sections.addAlert.error.requiredtTermFieldText": "词字段必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.greaterThenThreshold0Text": "阈值 1 应 > 阈值 0。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredAggFieldText": "聚合字段必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredIndexText": "“索引”必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTermSizedText": "“词大小”必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold0Text": "阈值 0 必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredThreshold1Text": "阈值 1 必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTimeFieldText": "时间字段必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTimeWindowSizeText": "“时间窗大小”必填。",
+    "xpack.stackAlerts.threshold.ui.validation.error.requiredTermFieldText": "词字段必填。",
     "xpack.triggersActionsUI.sections.addConnectorForm.flyoutTitle": "{actionTypeName} 连接器",
     "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "选择连接器",
     "xpack.triggersActionsUI.sections.addConnectorForm.updateErrorNotificationText": "无法创建连接器。",
@@ -20200,27 +20200,27 @@
     "xpack.triggersActionsUI.sections.addModalConnectorForm.flyoutTitle": "{actionTypeName} 连接器",
     "xpack.triggersActionsUI.sections.addModalConnectorForm.saveButtonLabel": "保存",
     "xpack.triggersActionsUI.sections.addModalConnectorForm.updateSuccessNotificationText": "已创建“{connectorName}”",
-    "xpack.triggersActionsUI.sections.alertAdd.conditionPrompt": "定义条件",
-    "xpack.triggersActionsUI.sections.alertAdd.errorLoadingAlertVisualizationTitle": "无法加载告警可视化",
+    "xpack.stackAlerts.threshold.ui.conditionPrompt": "定义条件",
+    "xpack.stackAlerts.threshold.ui.visualization.errorLoadingAlertVisualizationTitle": "无法加载告警可视化",
     "xpack.triggersActionsUI.sections.alertAdd.flyoutTitle": "创建告警",
-    "xpack.triggersActionsUI.sections.alertAdd.geoThreshold.closePopoverLabel": "关闭",
-    "xpack.triggersActionsUI.sections.alertAdd.loadingAlertVisualizationDescription": "正在加载告警可视化……",
+    "xpack.stackAlerts.geoThreshold.ui.expressionPopover.closePopoverLabel": "关闭",
+    "xpack.stackAlerts.threshold.ui.visualization.loadingAlertVisualizationDescription": "正在加载告警可视化……",
     "xpack.triggersActionsUI.sections.alertAdd.operationName": "创建",
-    "xpack.triggersActionsUI.sections.alertAdd.previewAlertVisualizationDescription": "完成表达式以生成预览。",
+    "xpack.stackAlerts.threshold.ui.previewAlertVisualizationDescription": "完成表达式以生成预览。",
     "xpack.triggersActionsUI.sections.alertAdd.saveErrorNotificationText": "无法创建告警。",
     "xpack.triggersActionsUI.sections.alertAdd.saveSuccessNotificationText": "已保存“{alertName}”",
-    "xpack.triggersActionsUI.sections.alertAdd.selectIndex": "选择索引",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.closeIndexPopoverLabel": "关闭",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage": "表达式包含错误。",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.howToBroadenSearchQueryDescription": "使用 * 可扩大您的查询范围。",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indexButtonLabel": "索引",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indexLabel": "索引",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.indicesToQueryLabel": "要查询的索引",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldLabel": "时间字段",
-    "xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldOptionLabel": "选择字段",
-    "xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.dataDoesNotExistTextMessage": "确认您的时间范围和筛选正确。",
-    "xpack.triggersActionsUI.sections.alertAdd.thresholdPreviewChart.noDataTitle": "没有数据匹配此查询",
-    "xpack.triggersActionsUI.sections.alertAdd.unableToLoadVisualizationMessage": "无法加载可视化",
+    "xpack.stackAlerts.threshold.ui.selectIndex": "选择索引",
+    "xpack.stackAlerts.threshold.ui.alertParams.closeIndexPopoverLabel": "关闭",
+    "xpack.stackAlerts.threshold.ui.alertParams.fixErrorInExpressionBelowValidationMessage": "表达式包含错误。",
+    "xpack.stackAlerts.threshold.ui.alertParams.howToBroadenSearchQueryDescription": "使用 * 可扩大您的查询范围。",
+    "xpack.stackAlerts.threshold.ui.alertParams.indexButtonLabel": "索引",
+    "xpack.stackAlerts.threshold.ui.alertParams.indexLabel": "索引",
+    "xpack.stackAlerts.threshold.ui.alertParams.indicesToQueryLabel": "要查询的索引",
+    "xpack.stackAlerts.threshold.ui.alertParams.timeFieldLabel": "时间字段",
+    "xpack.triggersActionsUI.sections.alertAdd.indexControls.timeFieldOptionLabel": "选择字段",
+    "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.dataDoesNotExistTextMessage": "确认您的时间范围和筛选正确。",
+    "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.noDataTitle": "没有数据匹配此查询",
+    "xpack.stackAlerts.threshold.ui.visualization.unableToLoadVisualizationMessage": "无法加载可视化",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstances.disabledAlert": "此告警已禁用,无法显示。切换禁用 ↑ 以激活。",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.duration": "持续时间",
     "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.instance": "实例",
diff --git a/x-pack/plugins/triggers_actions_ui/README.md b/x-pack/plugins/triggers_actions_ui/README.md
index 32e157255c0cc..ef81065608ad4 100644
--- a/x-pack/plugins/triggers_actions_ui/README.md
+++ b/x-pack/plugins/triggers_actions_ui/README.md
@@ -220,7 +220,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent<IndexThr
       <EuiFormLabel>
         <FormattedMessage
           defaultMessage="Select Index to query:"
-          id="xpack.triggersActionsUI.sections.alertAdd.selectIndex"
+          id="xpack.stackAlerts.threshold.ui.selectIndex"
         />
   ....
       </Fragment>
diff --git a/x-pack/plugins/stack_alerts/common/alert_types/index_threshold/index.ts b/x-pack/plugins/triggers_actions_ui/common/data/index.ts
similarity index 100%
rename from x-pack/plugins/stack_alerts/common/alert_types/index_threshold/index.ts
rename to x-pack/plugins/triggers_actions_ui/common/data/index.ts
diff --git a/x-pack/plugins/triggers_actions_ui/common/index.ts b/x-pack/plugins/triggers_actions_ui/common/index.ts
new file mode 100644
index 0000000000000..5775cc2454a7e
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/common/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export * from './data';
diff --git a/x-pack/plugins/triggers_actions_ui/kibana.json b/x-pack/plugins/triggers_actions_ui/kibana.json
index 72e1f0be5f7f4..9d79ab9232bf3 100644
--- a/x-pack/plugins/triggers_actions_ui/kibana.json
+++ b/x-pack/plugins/triggers_actions_ui/kibana.json
@@ -3,8 +3,8 @@
   "version": "kibana",
   "server": true,
   "ui": true,
-  "optionalPlugins": ["alerts", "stackAlerts", "features", "home"],
-  "requiredPlugins": ["management", "charts", "data", "kibanaReact"],
+  "optionalPlugins": ["alerts", "features", "home"],
+  "requiredPlugins": ["management", "charts", "data"],
   "configPath": ["xpack", "trigger_actions_ui"],
   "extraPublicDirs": ["public/common", "public/common/constants"],
   "requiredBundles": ["home", "alerts", "esUiShared"]
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx b/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx
index 80f9ac532d1c9..bb46fd02a98a9 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx
@@ -9,7 +9,7 @@ import { render, unmountComponentAtNode } from 'react-dom';
 import { SavedObjectsClientContract } from 'src/core/public';
 
 import { App, AppDeps } from './app';
-import { setSavedObjectsClient } from '../common/lib/index_threshold_api';
+import { setSavedObjectsClient } from '../common/lib/data_apis';
 
 interface BootDeps extends AppDeps {
   element: HTMLElement;
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts
index 32b323334654e..86c33a373753f 100644
--- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts
@@ -5,6 +5,10 @@
  */
 
 export * from './expression_items';
+export * from './constants';
+export * from './index_controls';
+export * from './lib';
+export * from './types';
 
 export { connectorConfiguration as ServiceNowConnectorConfiguration } from '../application/components/builtin_action_types/servicenow/config';
 export { connectorConfiguration as JiraConnectorConfiguration } from '../application/components/builtin_action_types/jira/config';
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts
index da332aa326ccf..8d10e531930cc 100644
--- a/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts
@@ -9,10 +9,10 @@ import { HttpSetup } from 'kibana/public';
 import { i18n } from '@kbn/i18n';
 import {
   loadIndexPatterns,
-  getMatchingIndicesForThresholdAlertType,
-  getThresholdAlertTypeFields,
+  getMatchingIndices,
+  getESIndexFields,
   getSavedObjectsClient,
-} from '../lib/index_threshold_api';
+} from '../lib/data_apis';
 
 export interface IOption {
   label: string;
@@ -39,7 +39,7 @@ export const getIndexOptions = async (
     return options;
   }
 
-  const matchingIndices = (await getMatchingIndicesForThresholdAlertType({
+  const matchingIndices = (await getMatchingIndices({
     pattern,
     http,
   })) as string[];
@@ -85,12 +85,15 @@ export const getIndexOptions = async (
 };
 
 export const getFields = async (http: HttpSetup, indexes: string[]) => {
-  return await getThresholdAlertTypeFields({ indexes, http });
+  return await getESIndexFields({ indexes, http });
 };
 
 export const firstFieldOption = {
-  text: i18n.translate('xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldOptionLabel', {
-    defaultMessage: 'Select a field',
-  }),
+  text: i18n.translate(
+    'xpack.triggersActionsUI.sections.alertAdd.indexControls.timeFieldOptionLabel',
+    {
+      defaultMessage: 'Select a field',
+    }
+  ),
   value: '',
 };
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts b/x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts
new file mode 100644
index 0000000000000..573d306ae5550
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { HttpSetup } from 'kibana/public';
+
+const DATA_API_ROOT = '/api/triggers_actions_ui/data';
+
+export async function getMatchingIndices({
+  pattern,
+  http,
+}: {
+  pattern: string;
+  http: HttpSetup;
+}): Promise<Record<string, any>> {
+  if (!pattern.startsWith('*')) {
+    pattern = `*${pattern}`;
+  }
+  if (!pattern.endsWith('*')) {
+    pattern = `${pattern}*`;
+  }
+  const { indices } = await http.post(`${DATA_API_ROOT}/_indices`, {
+    body: JSON.stringify({ pattern }),
+  });
+  return indices;
+}
+
+export async function getESIndexFields({
+  indexes,
+  http,
+}: {
+  indexes: string[];
+  http: HttpSetup;
+}): Promise<
+  Array<{
+    name: string;
+    type: string;
+    normalizedType: string;
+    searchable: boolean;
+    aggregatable: boolean;
+  }>
+> {
+  const { fields } = await http.post(`${DATA_API_ROOT}/_fields`, {
+    body: JSON.stringify({ indexPatterns: indexes }),
+  });
+  return fields;
+}
+
+let savedObjectsClient: any;
+
+export const setSavedObjectsClient = (aSavedObjectsClient: any) => {
+  savedObjectsClient = aSavedObjectsClient;
+};
+
+export const getSavedObjectsClient = () => {
+  return savedObjectsClient;
+};
+
+export const loadIndexPatterns = async () => {
+  const { savedObjects } = await getSavedObjectsClient().find({
+    type: 'index-pattern',
+    fields: ['title'],
+    perPage: 10000,
+  });
+  return savedObjects;
+};
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/lib/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/lib/index.ts
new file mode 100644
index 0000000000000..7671e239f8fff
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/public/common/lib/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+export { getTimeFieldOptions, getTimeOptions } from './get_time_options';
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts b/x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts
deleted file mode 100644
index 11d273fcb7a42..0000000000000
--- a/x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-import { HttpSetup } from 'kibana/public';
-import { TimeSeriesResult } from '../../../../stack_alerts/common/alert_types/index_threshold';
-
-const INDEX_THRESHOLD_API_ROOT = '/api/stack_alerts/index_threshold';
-
-export async function getMatchingIndicesForThresholdAlertType({
-  pattern,
-  http,
-}: {
-  pattern: string;
-  http: HttpSetup;
-}): Promise<Record<string, any>> {
-  if (!pattern.startsWith('*')) {
-    pattern = `*${pattern}`;
-  }
-  if (!pattern.endsWith('*')) {
-    pattern = `${pattern}*`;
-  }
-  const { indices } = await http.post(`${INDEX_THRESHOLD_API_ROOT}/_indices`, {
-    body: JSON.stringify({ pattern }),
-  });
-  return indices;
-}
-
-export async function getThresholdAlertTypeFields({
-  indexes,
-  http,
-}: {
-  indexes: string[];
-  http: HttpSetup;
-}): Promise<Record<string, any>> {
-  const { fields } = await http.post(`${INDEX_THRESHOLD_API_ROOT}/_fields`, {
-    body: JSON.stringify({ indexPatterns: indexes }),
-  });
-  return fields;
-}
-
-let savedObjectsClient: any;
-
-export const setSavedObjectsClient = (aSavedObjectsClient: any) => {
-  savedObjectsClient = aSavedObjectsClient;
-};
-
-export const getSavedObjectsClient = () => {
-  return savedObjectsClient;
-};
-
-export const loadIndexPatterns = async () => {
-  const { savedObjects } = await getSavedObjectsClient().find({
-    type: 'index-pattern',
-    fields: ['title'],
-    perPage: 10000,
-  });
-  return savedObjects;
-};
-
-interface GetThresholdAlertVisualizationDataParams {
-  model: any;
-  visualizeOptions: any;
-  http: HttpSetup;
-}
-
-export async function getThresholdAlertVisualizationData({
-  model,
-  visualizeOptions,
-  http,
-}: GetThresholdAlertVisualizationDataParams): Promise<TimeSeriesResult> {
-  const timeSeriesQueryParams = {
-    index: model.index,
-    timeField: model.timeField,
-    aggType: model.aggType,
-    aggField: model.aggField,
-    groupBy: model.groupBy,
-    termField: model.termField,
-    termSize: model.termSize,
-    timeWindowSize: model.timeWindowSize,
-    timeWindowUnit: model.timeWindowUnit,
-    dateStart: new Date(visualizeOptions.rangeFrom).toISOString(),
-    dateEnd: new Date(visualizeOptions.rangeTo).toISOString(),
-    interval: visualizeOptions.interval,
-  };
-
-  return await http.post<TimeSeriesResult>(`${INDEX_THRESHOLD_API_ROOT}/_time_series_query`, {
-    body: JSON.stringify(timeSeriesQueryParams),
-  });
-}
diff --git a/x-pack/plugins/triggers_actions_ui/public/index.ts b/x-pack/plugins/triggers_actions_ui/public/index.ts
index a28b10683c28f..3794112e1d502 100644
--- a/x-pack/plugins/triggers_actions_ui/public/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/index.ts
@@ -4,7 +4,6 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { PluginInitializerContext } from 'src/core/public';
 import { Plugin } from './plugin';
 
 export { AlertsContextProvider, AlertsContextValue } from './application/context/alerts_context';
@@ -22,15 +21,17 @@ export {
   ValidationResult,
   ActionVariable,
   ActionConnector,
+  IErrorObject,
 } from './types';
 export {
   ConnectorAddFlyout,
   ConnectorEditFlyout,
 } from './application/sections/action_connector_form';
 export { loadActionTypes } from './application/lib/action_connector_api';
+export * from './common';
 
-export function plugin(ctx: PluginInitializerContext) {
-  return new Plugin(ctx);
+export function plugin() {
+  return new Plugin();
 }
 
 export { Plugin };
diff --git a/x-pack/plugins/triggers_actions_ui/public/plugin.ts b/x-pack/plugins/triggers_actions_ui/public/plugin.ts
index 61cd7699c50c5..2d93d368ad8e5 100644
--- a/x-pack/plugins/triggers_actions_ui/public/plugin.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/plugin.ts
@@ -4,17 +4,11 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import {
-  CoreSetup,
-  CoreStart,
-  Plugin as CorePlugin,
-  PluginInitializerContext,
-} from 'src/core/public';
+import { CoreSetup, CoreStart, Plugin as CorePlugin } from 'src/core/public';
 
 import { i18n } from '@kbn/i18n';
 import { FeaturesPluginStart } from '../../features/public';
 import { registerBuiltInActionTypes } from './application/components/builtin_action_types';
-import { registerBuiltInAlertTypes } from './application/components/builtin_alert_types';
 import { ActionTypeModel, AlertTypeModel } from './types';
 import { TypeRegistry } from './application/type_registry';
 import {
@@ -29,10 +23,6 @@ import { ChartsPluginStart } from '../../../../src/plugins/charts/public';
 import { PluginStartContract as AlertingStart } from '../../alerts/public';
 import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
 
-export interface TriggersActionsUiConfigType {
-  enableGeoTrackingThresholdAlert: boolean;
-}
-
 export interface TriggersAndActionsUIPublicPluginSetup {
   actionTypeRegistry: TypeRegistry<ActionTypeModel>;
   alertTypeRegistry: TypeRegistry<AlertTypeModel>;
@@ -66,14 +56,10 @@ export class Plugin
     > {
   private actionTypeRegistry: TypeRegistry<ActionTypeModel>;
   private alertTypeRegistry: TypeRegistry<AlertTypeModel>;
-  private initializerContext: PluginInitializerContext;
 
-  constructor(initializerContext: PluginInitializerContext) {
+  constructor() {
     this.actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
-
     this.alertTypeRegistry = new TypeRegistry<AlertTypeModel>();
-
-    this.initializerContext = initializerContext;
   }
 
   public setup(core: CoreSetup, plugins: PluginsSetup): TriggersAndActionsUIPublicPluginSetup {
@@ -142,11 +128,6 @@ export class Plugin
       actionTypeRegistry: this.actionTypeRegistry,
     });
 
-    registerBuiltInAlertTypes({
-      alertTypeRegistry: this.alertTypeRegistry,
-      triggerActionsUiConfig: this.initializerContext.config.get<TriggersActionsUiConfigType>(),
-    });
-
     return {
       actionTypeRegistry: this.actionTypeRegistry,
       alertTypeRegistry: this.alertTypeRegistry,
diff --git a/x-pack/plugins/triggers_actions_ui/server/data/README.md b/x-pack/plugins/triggers_actions_ui/server/data/README.md
new file mode 100644
index 0000000000000..78577f0783008
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/server/data/README.md
@@ -0,0 +1,228 @@
+# Data Apis
+
+The TriggersActionsUi plugin's Data Apis back the functionality needed by the Index Threshold Stack Alert.
+
+## http endpoints
+
+The following endpoints are provided for this alert type:
+
+- `POST /api/triggers_actions_ui/data/_indices`
+- `POST /api/triggers_actions_ui/data/_fields`
+- `POST /api/triggers_actions_ui/data/_time_series_query`
+
+### `POST .../_indices`
+
+This HTTP endpoint is provided for the alerting ui to list the available
+"index names" for the user to select to use with the alert.  This API also
+returns aliases which match the supplied pattern.
+
+The request body is expected to be a JSON object in the following form, where the
+`pattern` value may include comma-separated names and wildcards.
+
+```js
+{
+  pattern: "index-name-pattern"
+}
+```
+
+The response body is a JSON object in the following form, where each element
+of the `indices` array is the name of an index or alias.  The number of elements
+returned is limited, as this API is intended to be used to help narrow down
+index names to use with the alert, and not support pagination, etc.
+
+```js
+{
+  indices: ["index-name-1", "alias-name-1", ...]
+}
+```
+
+### `POST .../_fields`
+
+This HTTP endpoint is provided for the alerting ui to list the available
+fields for the user to select to use with the alert.
+
+The request body is expected to be a JSON object in the following form, where the
+`indexPatterns` array elements may include comma-separated names and wildcards.
+
+```js
+{
+  indexPatterns: ["index-pattern-1", "index-pattern-2"]
+}
+```
+
+The response body is a JSON object in the following form, where each element
+fields array is a field object.
+
+```js
+{
+  fields: [fieldObject1, fieldObject2, ...]
+}
+```
+
+A field object is the following shape:
+
+```typescript
+{
+  name: string,           // field name
+  type: string,           // field type - eg 'keyword', 'date', 'long', etc
+  normalizedType: string, // for numeric types, this will be 'number'
+  aggregatable: true,     // value from elasticsearch field capabilities
+  searchable: true,       // value from elasticsearch field capabilities
+}
+```
+
+### `POST .../_time_series_query`
+
+This HTTP endpoint is provided to return the values the alertType would calculate,
+over a series of time.  It is intended to be used in the alerting UI to 
+provide a "preview" of the alert during creation/editing based on recent data,
+and could be used to show a "simulation" of the the alert over an arbitrary
+range of time.
+
+The endpoint is `POST /api/triggers_actions_ui/data/_time_series_query`.
+The request and response bodies are specifed in 
+[`lib/core_query_types.ts`][it-core-query]
+and
+[`lib/time_series_types.ts`][it-timeSeries-types].
+The request body is very similar to the alertType's parameters.
+
+### example
+
+Continuing with the example above, here's a query to get the values calculated
+for the last 10 seconds.
+This example uses [now-iso][] to generate iso date strings.
+
+```console
+curl -k  "https://elastic:changeme@localhost:5601/api/triggers_actions_ui/data/_time_series_query" \
+    -H "kbn-xsrf: foo" -H "content-type: application/json"   -d "{
+    \"index\":           \"es-hb-sim\",
+    \"timeField\":       \"@timestamp\",
+    \"aggType\":         \"avg\",
+    \"aggField\":        \"summary.up\",
+    \"groupBy\":         \"top\",
+    \"termSize\":        100,
+    \"termField\":       \"monitor.name.keyword\",
+    \"interval\":        \"1s\",
+    \"dateStart\":       \"`now-iso -10s`\",
+    \"dateEnd\":         \"`now-iso`\",
+    \"timeWindowSize\":  5,
+    \"timeWindowUnit\":  \"s\"
+}"
+```
+
+```
+{
+  "results": [
+    {
+      "group": "host-A",
+      "metrics": [
+        [ "2020-02-26T15:10:40.000Z", 0 ],
+        [ "2020-02-26T15:10:41.000Z", 0 ],
+        [ "2020-02-26T15:10:42.000Z", 0 ],
+        [ "2020-02-26T15:10:43.000Z", 0 ],
+        [ "2020-02-26T15:10:44.000Z", 0 ],
+        [ "2020-02-26T15:10:45.000Z", 0 ],
+        [ "2020-02-26T15:10:46.000Z", 0 ],
+        [ "2020-02-26T15:10:47.000Z", 0 ],
+        [ "2020-02-26T15:10:48.000Z", 0 ],
+        [ "2020-02-26T15:10:49.000Z", 0 ],
+        [ "2020-02-26T15:10:50.000Z", 0 ]
+      ]
+    }
+  ]
+}
+```
+
+To get the current value of the calculated metric, you can leave off the date:
+
+```
+curl -k  "https://elastic:changeme@localhost:5601/api/triggers_actions_ui/data/_time_series_query" \
+    -H "kbn-xsrf: foo" -H "content-type: application/json"   -d '{
+    "index":           "es-hb-sim",
+    "timeField":       "@timestamp",
+    "aggType":         "avg",
+    "aggField":        "summary.up",
+    "groupBy":         "top",
+    "termField":       "monitor.name.keyword",
+    "termSize":        100,
+    "interval":        "1s",
+    "timeWindowSize":  5,
+    "timeWindowUnit":  "s"
+}'
+```
+
+```
+{
+  "results": [
+    {
+      "group": "host-A",
+      "metrics": [
+        [ "2020-02-26T15:23:36.635Z", 0 ]
+      ]
+    }
+  ]
+}
+```
+
+[it-timeSeries-types]: lib/time_series_types.ts
+
+## service functions
+
+A single service function is available that provides the functionality
+of the http endpoint `POST /api/triggers_actions_ui/data/_time_series_query`,
+but as an API for Kibana plugins.  The function is available as
+`triggersActionsUi.data.timeSeriesQuery()` on the plugin's _Start_ contract
+
+The parameters and return value for the function are the same as for the HTTP
+request, though some additional parameters are required (logger, callCluster,
+etc).
+
+## notes on the timeSeriesQuery API / http endpoint
+
+This API provides additional parameters beyond what the alertType itself uses:
+
+- `dateStart`
+- `dateEnd`
+- `interval`
+
+The `dateStart` and `dateEnd` parameters are ISO date strings.
+
+The `interval` parameter is intended to model the `interval` the alert is
+currently using, and uses the same `1s`, `2m`, `3h`, etc format.  Over the
+supplied date range, a time-series data point will be calculated every
+`interval` duration.
+
+So the number of time-series points in the output of the API should be:
+
+```
+( dateStart - dateEnd ) / interval
+```
+
+Example: 
+
+```
+dateStart: '2020-01-01T00:00:00'
+dateEnd:   '2020-01-02T00:00:00'
+interval:  '1h'
+```
+
+The date range is 1 day === 24 hours.  The interval is 1 hour.  So there should
+be ~24 time series points in the output.
+
+For preview purposes:
+
+- The `termSize` parameter should be used to help cut
+down on the amount of work ES does, and keep the generated graphs a little
+simpler.  Probably something like `10`.
+
+- For queries with long date ranges, you probably don't want to use the
+`interval` the alert is set to, as the `interval` used in the query, as this
+could result in a lot of time-series points being generated, which is both
+costly in ES, and may result in noisy graphs.
+
+- The `timeWindow*` parameters should be the same as what the alert is using, 
+especially for the `count` and `sum` aggregation types.  Those aggregations
+don't scale the same way the others do, when the window changes.  Even for
+the other aggregations, changing the window could result in dramatically
+different values being generated - `avg` will be more "average-y", `min`
+and `max` will be a little stickier.
\ No newline at end of file
diff --git a/x-pack/plugins/triggers_actions_ui/server/data/index.ts b/x-pack/plugins/triggers_actions_ui/server/data/index.ts
new file mode 100644
index 0000000000000..6ee2b4bb8a5fe
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/server/data/index.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { Logger, IRouter } from '../../../../../src/core/server';
+import { timeSeriesQuery } from './lib/time_series_query';
+import { registerRoutes } from './routes';
+
+export {
+  TimeSeriesQuery,
+  CoreQueryParams,
+  CoreQueryParamsSchemaProperties,
+  validateCoreQueryBody,
+} from './lib';
+
+// future enhancement: make these configurable?
+export const MAX_INTERVALS = 1000;
+export const MAX_GROUPS = 1000;
+export const DEFAULT_GROUPS = 100;
+
+export function getService() {
+  return {
+    timeSeriesQuery,
+  };
+}
+
+interface RegisterParams {
+  logger: Logger;
+  router: IRouter;
+  data: ReturnType<typeof getService>;
+  baseRoute: string;
+}
+
+export function register(params: RegisterParams) {
+  const { logger, router, data, baseRoute } = params;
+  const baseBuiltInRoute = `${baseRoute}/data`;
+  registerRoutes({ logger, router, data, baseRoute: baseBuiltInRoute });
+}
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/core_query_types.test.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/core_query_types.test.ts
similarity index 100%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/core_query_types.test.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/core_query_types.test.ts
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/core_query_types.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/core_query_types.ts
similarity index 68%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/core_query_types.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/core_query_types.ts
index d96f555eceff4..bc7d0c352756e 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/core_query_types.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/core_query_types.ts
@@ -51,33 +51,45 @@ export function validateCoreQueryBody(anyParams: unknown): string | undefined {
     termSize,
   }: CoreQueryParams = anyParams as CoreQueryParams;
   if (aggType !== 'count' && !aggField) {
-    return i18n.translate('xpack.stackAlerts.indexThreshold.aggTypeRequiredErrorMessage', {
-      defaultMessage: '[aggField]: must have a value when [aggType] is "{aggType}"',
-      values: {
-        aggType,
-      },
-    });
+    return i18n.translate(
+      'xpack.triggersActionsUI.data.coreQueryParams.aggTypeRequiredErrorMessage',
+      {
+        defaultMessage: '[aggField]: must have a value when [aggType] is "{aggType}"',
+        values: {
+          aggType,
+        },
+      }
+    );
   }
 
   // check grouping
   if (groupBy === 'top') {
     if (termField == null) {
-      return i18n.translate('xpack.stackAlerts.indexThreshold.termFieldRequiredErrorMessage', {
-        defaultMessage: '[termField]: termField required when [groupBy] is top',
-      });
+      return i18n.translate(
+        'xpack.triggersActionsUI.data.coreQueryParams.termFieldRequiredErrorMessage',
+        {
+          defaultMessage: '[termField]: termField required when [groupBy] is top',
+        }
+      );
     }
     if (termSize == null) {
-      return i18n.translate('xpack.stackAlerts.indexThreshold.termSizeRequiredErrorMessage', {
-        defaultMessage: '[termSize]: termSize required when [groupBy] is top',
-      });
+      return i18n.translate(
+        'xpack.triggersActionsUI.data.coreQueryParams.termSizeRequiredErrorMessage',
+        {
+          defaultMessage: '[termSize]: termSize required when [groupBy] is top',
+        }
+      );
     }
     if (termSize > MAX_GROUPS) {
-      return i18n.translate('xpack.stackAlerts.indexThreshold.invalidTermSizeMaximumErrorMessage', {
-        defaultMessage: '[termSize]: must be less than or equal to {maxGroups}',
-        values: {
-          maxGroups: MAX_GROUPS,
-        },
-      });
+      return i18n.translate(
+        'xpack.triggersActionsUI.data.coreQueryParams.invalidTermSizeMaximumErrorMessage',
+        {
+          defaultMessage: '[termSize]: must be less than or equal to {maxGroups}',
+          values: {
+            maxGroups: MAX_GROUPS,
+          },
+        }
+      );
     }
   }
 }
@@ -89,7 +101,7 @@ function validateAggType(aggType: string): string | undefined {
     return;
   }
 
-  return i18n.translate('xpack.stackAlerts.indexThreshold.invalidAggTypeErrorMessage', {
+  return i18n.translate('xpack.triggersActionsUI.data.coreQueryParams.invalidAggTypeErrorMessage', {
     defaultMessage: 'invalid aggType: "{aggType}"',
     values: {
       aggType,
@@ -102,7 +114,7 @@ export function validateGroupBy(groupBy: string): string | undefined {
     return;
   }
 
-  return i18n.translate('xpack.stackAlerts.indexThreshold.invalidGroupByErrorMessage', {
+  return i18n.translate('xpack.triggersActionsUI.data.coreQueryParams.invalidGroupByErrorMessage', {
     defaultMessage: 'invalid groupBy: "{groupBy}"',
     values: {
       groupBy,
@@ -117,10 +129,13 @@ export function validateTimeWindowUnits(timeWindowUnit: string): string | undefi
     return;
   }
 
-  return i18n.translate('xpack.stackAlerts.indexThreshold.invalidTimeWindowUnitsErrorMessage', {
-    defaultMessage: 'invalid timeWindowUnit: "{timeWindowUnit}"',
-    values: {
-      timeWindowUnit,
-    },
-  });
+  return i18n.translate(
+    'xpack.triggersActionsUI.data.coreQueryParams.invalidTimeWindowUnitsErrorMessage',
+    {
+      defaultMessage: 'invalid timeWindowUnit: "{timeWindowUnit}"',
+      values: {
+        timeWindowUnit,
+      },
+    }
+  );
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/date_range_info.test.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/date_range_info.test.ts
similarity index 100%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/date_range_info.test.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/date_range_info.test.ts
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/date_range_info.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/date_range_info.ts
similarity index 89%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/date_range_info.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/date_range_info.ts
index 34f276d08706b..da125ba7ea29d 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/date_range_info.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/date_range_info.ts
@@ -6,7 +6,7 @@
 
 import { i18n } from '@kbn/i18n';
 import { times } from 'lodash';
-import { parseDuration } from '../../../../../alerts/server';
+import { parseDuration } from '../../../../alerts/server';
 import { MAX_INTERVALS } from '../index';
 
 // dates as numbers are epoch millis
@@ -100,7 +100,7 @@ function getDuration(durationS: string, field: string): number {
 }
 
 function getParseErrorMessage(formatName: string, fieldName: string, fieldValue: string) {
-  return i18n.translate('xpack.stackAlerts.indexThreshold.formattedFieldErrorMessage', {
+  return i18n.translate('xpack.triggersActionsUI.data.coreQueryParams.formattedFieldErrorMessage', {
     defaultMessage: 'invalid {formatName} format for {fieldName}: "{fieldValue}"',
     values: {
       formatName,
@@ -111,7 +111,7 @@ function getParseErrorMessage(formatName: string, fieldName: string, fieldValue:
 }
 
 export function getTooManyIntervalsErrorMessage(intervals: number, maxIntervals: number) {
-  return i18n.translate('xpack.stackAlerts.indexThreshold.maxIntervalsErrorMessage', {
+  return i18n.translate('xpack.triggersActionsUI.data.coreQueryParams.maxIntervalsErrorMessage', {
     defaultMessage:
       'calculated number of intervals {intervals} is greater than maximum {maxIntervals}',
     values: {
@@ -122,7 +122,10 @@ export function getTooManyIntervalsErrorMessage(intervals: number, maxIntervals:
 }
 
 export function getDateStartAfterDateEndErrorMessage(): string {
-  return i18n.translate('xpack.stackAlerts.indexThreshold.dateStartGTdateEndErrorMessage', {
-    defaultMessage: '[dateStart]: is greater than [dateEnd]',
-  });
+  return i18n.translate(
+    'xpack.triggersActionsUI.data.coreQueryParams.dateStartGTdateEndErrorMessage',
+    {
+      defaultMessage: '[dateStart]: is greater than [dateEnd]',
+    }
+  );
 }
diff --git a/x-pack/plugins/triggers_actions_ui/server/data/lib/index.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/index.ts
new file mode 100644
index 0000000000000..096a928249fd5
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/index.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export { TimeSeriesQuery } from './time_series_query';
+export {
+  CoreQueryParams,
+  CoreQueryParamsSchemaProperties,
+  validateCoreQueryBody,
+} from './core_query_types';
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.test.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts
similarity index 58%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.test.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts
index 0565a8634fc71..f1234249a257f 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.test.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.test.ts
@@ -6,12 +6,8 @@
 
 // test error conditions of calling timeSeriesQuery - postive results tested in FT
 
-import { loggingSystemMock } from '../../../../../../../src/core/server/mocks';
-import { coreMock } from '../../../../../../../src/core/server/mocks';
-import { AlertingBuiltinsPlugin } from '../../../plugin';
-import { TimeSeriesQueryParameters, TimeSeriesResult, TimeSeriesQuery } from './time_series_query';
-
-type TimeSeriesQueryFn = (query: TimeSeriesQueryParameters) => Promise<TimeSeriesResult>;
+import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
+import { TimeSeriesQueryParameters, TimeSeriesQuery, timeSeriesQuery } from './time_series_query';
 
 const DefaultQueryParams: TimeSeriesQuery = {
   index: 'index-name',
@@ -32,16 +28,7 @@ describe('timeSeriesQuery', () => {
   let params: TimeSeriesQueryParameters;
   const mockCallCluster = jest.fn();
 
-  let timeSeriesQueryFn: TimeSeriesQueryFn;
-
   beforeEach(async () => {
-    // rather than use the function from an import, retrieve it from the plugin
-    const context = coreMock.createPluginInitializerContext();
-    const plugin = new AlertingBuiltinsPlugin(context);
-    const coreStart = coreMock.createStart();
-    const service = await plugin.start(coreStart);
-    timeSeriesQueryFn = service.indexThreshold.timeSeriesQuery;
-
     mockCallCluster.mockReset();
     params = {
       logger: loggingSystemMock.create().get(),
@@ -52,14 +39,14 @@ describe('timeSeriesQuery', () => {
 
   it('fails as expected when the callCluster call fails', async () => {
     mockCallCluster.mockRejectedValue(new Error('woopsie'));
-    expect(timeSeriesQueryFn(params)).rejects.toThrowErrorMatchingInlineSnapshot(
+    expect(timeSeriesQuery(params)).rejects.toThrowErrorMatchingInlineSnapshot(
       `"error running search"`
     );
   });
 
   it('fails as expected when the query params are invalid', async () => {
     params.query = { ...params.query, dateStart: 'x' };
-    expect(timeSeriesQueryFn(params)).rejects.toThrowErrorMatchingInlineSnapshot(
+    expect(timeSeriesQuery(params)).rejects.toThrowErrorMatchingInlineSnapshot(
       `"invalid date format for dateStart: \\"x\\""`
     );
   });
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.ts
similarity index 96%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.ts
index 9c4133be6f483..29a996bbb5ef6 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_query.ts
@@ -5,16 +5,17 @@
  */
 
 import { SearchResponse } from 'elasticsearch';
+import { Logger } from 'kibana/server';
+import { LegacyScopedClusterClient } from '../../../../../../src/core/server';
 import { DEFAULT_GROUPS } from '../index';
 import { getDateRangeInfo } from './date_range_info';
-import { Logger, CallCluster } from '../../../types';
 
 import { TimeSeriesQuery, TimeSeriesResult, TimeSeriesResultRow } from './time_series_types';
 export { TimeSeriesQuery, TimeSeriesResult } from './time_series_types';
 
 export interface TimeSeriesQueryParameters {
   logger: Logger;
-  callCluster: CallCluster;
+  callCluster: LegacyScopedClusterClient['callAsCurrentUser'];
   query: TimeSeriesQuery;
 }
 
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_types.test.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_types.test.ts
similarity index 100%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_types.test.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_types.test.ts
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_types.ts b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_types.ts
similarity index 81%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_types.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_types.ts
index a8b35c34c596f..ef0fa15cf31e9 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_types.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/lib/time_series_types.ts
@@ -10,7 +10,7 @@
 import { i18n } from '@kbn/i18n';
 import { schema, TypeOf } from '@kbn/config-schema';
 
-import { parseDuration } from '../../../../../alerts/server';
+import { parseDuration } from '../../../../alerts/server';
 import { MAX_INTERVALS } from '../index';
 import { CoreQueryParamsSchemaProperties, validateCoreQueryBody } from './core_query_types';
 import {
@@ -18,11 +18,7 @@ import {
   getDateStartAfterDateEndErrorMessage,
 } from './date_range_info';
 
-export {
-  TimeSeriesResult,
-  TimeSeriesResultRow,
-  MetricResult,
-} from '../../../../common/alert_types/index_threshold';
+export { TimeSeriesResult, TimeSeriesResultRow, MetricResult } from '../../../common/data';
 
 // The parameters here are very similar to the alert parameters.
 // Missing are `comparator` and `threshold`, which aren't needed to generate
@@ -66,9 +62,12 @@ function validateBody(anyParams: unknown): string | undefined {
     }
 
     if (epochStart !== epochEnd && !interval) {
-      return i18n.translate('xpack.stackAlerts.indexThreshold.intervalRequiredErrorMessage', {
-        defaultMessage: '[interval]: must be specified if [dateStart] does not equal [dateEnd]',
-      });
+      return i18n.translate(
+        'xpack.triggersActionsUI.data.coreQueryParams.intervalRequiredErrorMessage',
+        {
+          defaultMessage: '[interval]: must be specified if [dateStart] does not equal [dateEnd]',
+        }
+      );
     }
 
     if (interval) {
@@ -84,7 +83,7 @@ function validateBody(anyParams: unknown): string | undefined {
 function validateDate(dateString: string): string | undefined {
   const parsed = Date.parse(dateString);
   if (isNaN(parsed)) {
-    return i18n.translate('xpack.stackAlerts.indexThreshold.invalidDateErrorMessage', {
+    return i18n.translate('xpack.triggersActionsUI.data.coreQueryParams.invalidDateErrorMessage', {
       defaultMessage: 'invalid date {date}',
       values: {
         date: dateString,
@@ -97,11 +96,14 @@ export function validateDuration(duration: string): string | undefined {
   try {
     parseDuration(duration);
   } catch (err) {
-    return i18n.translate('xpack.stackAlerts.indexThreshold.invalidDurationErrorMessage', {
-      defaultMessage: 'invalid duration: "{duration}"',
-      values: {
-        duration,
-      },
-    });
+    return i18n.translate(
+      'xpack.triggersActionsUI.data.coreQueryParams.invalidDurationErrorMessage',
+      {
+        defaultMessage: 'invalid duration: "{duration}"',
+        values: {
+          duration,
+        },
+      }
+    );
   }
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/fields.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts
similarity index 90%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/fields.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts
index ea1e17002c4a5..17a2b2929f0cf 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/fields.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts
@@ -16,7 +16,7 @@ import {
   KibanaResponseFactory,
   ILegacyScopedClusterClient,
 } from 'kibana/server';
-import { Service } from '../../../types';
+import { Logger } from '../../../../../../src/core/server';
 
 const bodySchema = schema.object({
   indexPatterns: schema.arrayOf(schema.string()),
@@ -24,9 +24,9 @@ const bodySchema = schema.object({
 
 type RequestBody = TypeOf<typeof bodySchema>;
 
-export function createFieldsRoute(service: Service, router: IRouter, baseRoute: string) {
+export function createFieldsRoute(logger: Logger, router: IRouter, baseRoute: string) {
   const path = `${baseRoute}/_fields`;
-  service.logger.debug(`registering indexThreshold route POST ${path}`);
+  logger.debug(`registering indexThreshold route POST ${path}`);
   router.post(
     {
       path,
@@ -41,7 +41,7 @@ export function createFieldsRoute(service: Service, router: IRouter, baseRoute:
     req: KibanaRequest<unknown, unknown, RequestBody>,
     res: KibanaResponseFactory
   ): Promise<IKibanaResponse> {
-    service.logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
+    logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
 
     let rawFields: RawFields;
 
@@ -54,7 +54,7 @@ export function createFieldsRoute(service: Service, router: IRouter, baseRoute:
       rawFields = await getRawFields(ctx.core.elasticsearch.legacy.client, req.body.indexPatterns);
     } catch (err) {
       const indexPatterns = req.body.indexPatterns.join(',');
-      service.logger.warn(
+      logger.warn(
         `route ${path} error getting fields from pattern "${indexPatterns}": ${err.message}`
       );
       return res.ok({ body: { fields: [] } });
@@ -62,7 +62,7 @@ export function createFieldsRoute(service: Service, router: IRouter, baseRoute:
 
     const result = { fields: getFieldsFromRawFields(rawFields) };
 
-    service.logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
+    logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
     return res.ok({ body: result });
   }
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/index.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/index.ts
similarity index 55%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/index.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/routes/index.ts
index 8410e48dd46d9..664b78cabb560 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/index.ts
@@ -4,19 +4,22 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { Service, IRouter } from '../../../types';
+import { Logger } from '../../../../../../src/core/server';
 import { createTimeSeriesQueryRoute } from './time_series_query';
 import { createFieldsRoute } from './fields';
 import { createIndicesRoute } from './indices';
+import { IRouter } from '../../../../../../src/core/server';
+import { getService } from '..';
 
 interface RegisterRoutesParams {
-  service: Service;
+  logger: Logger;
   router: IRouter;
+  data: ReturnType<typeof getService>;
   baseRoute: string;
 }
 export function registerRoutes(params: RegisterRoutesParams) {
-  const { service, router, baseRoute } = params;
-  createTimeSeriesQueryRoute(service, router, baseRoute);
-  createFieldsRoute(service, router, baseRoute);
-  createIndicesRoute(service, router, baseRoute);
+  const { logger, router, baseRoute, data } = params;
+  createTimeSeriesQueryRoute(logger, data.timeSeriesQuery, router, baseRoute);
+  createFieldsRoute(logger, router, baseRoute);
+  createIndicesRoute(logger, router, baseRoute);
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/indices.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts
similarity index 85%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/indices.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts
index c94705829ec60..9b84ce5ac0bcc 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/indices.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts
@@ -19,7 +19,7 @@ import {
   ILegacyScopedClusterClient,
 } from 'kibana/server';
 import { SearchResponse } from 'elasticsearch';
-import { Service } from '../../../types';
+import { Logger } from '../../../../../../src/core/server';
 
 const bodySchema = schema.object({
   pattern: schema.string(),
@@ -27,9 +27,9 @@ const bodySchema = schema.object({
 
 type RequestBody = TypeOf<typeof bodySchema>;
 
-export function createIndicesRoute(service: Service, router: IRouter, baseRoute: string) {
+export function createIndicesRoute(logger: Logger, router: IRouter, baseRoute: string) {
   const path = `${baseRoute}/_indices`;
-  service.logger.debug(`registering indexThreshold route POST ${path}`);
+  logger.debug(`registering indexThreshold route POST ${path}`);
   router.post(
     {
       path,
@@ -45,7 +45,7 @@ export function createIndicesRoute(service: Service, router: IRouter, baseRoute:
     res: KibanaResponseFactory
   ): Promise<IKibanaResponse> {
     const pattern = req.body.pattern;
-    service.logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
+    logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
 
     if (pattern.trim() === '') {
       return res.ok({ body: { indices: [] } });
@@ -55,23 +55,19 @@ export function createIndicesRoute(service: Service, router: IRouter, baseRoute:
     try {
       aliases = await getAliasesFromPattern(ctx.core.elasticsearch.legacy.client, pattern);
     } catch (err) {
-      service.logger.warn(
-        `route ${path} error getting aliases from pattern "${pattern}": ${err.message}`
-      );
+      logger.warn(`route ${path} error getting aliases from pattern "${pattern}": ${err.message}`);
     }
 
     let indices: string[] = [];
     try {
       indices = await getIndicesFromPattern(ctx.core.elasticsearch.legacy.client, pattern);
     } catch (err) {
-      service.logger.warn(
-        `route ${path} error getting indices from pattern "${pattern}": ${err.message}`
-      );
+      logger.warn(`route ${path} error getting indices from pattern "${pattern}": ${err.message}`);
     }
 
     const result = { indices: uniqueCombined(aliases, indices, MAX_INDICES) };
 
-    service.logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
+    logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
     return res.ok({ body: result });
   }
 }
diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/time_series_query.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts
similarity index 58%
rename from x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/time_series_query.ts
rename to x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts
index 9af01dc766a99..805bd7d4004c2 100644
--- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/routes/time_series_query.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts
@@ -11,14 +11,20 @@ import {
   IKibanaResponse,
   KibanaResponseFactory,
 } from 'kibana/server';
+import { Logger } from '../../../../../../src/core/server';
+import { TimeSeriesQueryParameters } from '../lib/time_series_query';
 
-import { Service } from '../../../types';
-import { TimeSeriesQuery, TimeSeriesQuerySchema } from '../lib/time_series_types';
+import { TimeSeriesQuery, TimeSeriesQuerySchema, TimeSeriesResult } from '../lib/time_series_types';
 export { TimeSeriesQuery, TimeSeriesResult } from '../lib/time_series_types';
 
-export function createTimeSeriesQueryRoute(service: Service, router: IRouter, baseRoute: string) {
+export function createTimeSeriesQueryRoute(
+  logger: Logger,
+  timeSeriesQuery: (params: TimeSeriesQueryParameters) => Promise<TimeSeriesResult>,
+  router: IRouter,
+  baseRoute: string
+) {
   const path = `${baseRoute}/_time_series_query`;
-  service.logger.debug(`registering indexThreshold route POST ${path}`);
+  logger.debug(`registering indexThreshold route POST ${path}`);
   router.post(
     {
       path,
@@ -33,15 +39,15 @@ export function createTimeSeriesQueryRoute(service: Service, router: IRouter, ba
     req: KibanaRequest<unknown, unknown, TimeSeriesQuery>,
     res: KibanaResponseFactory
   ): Promise<IKibanaResponse> {
-    service.logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
+    logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`);
 
-    const result = await service.indexThreshold.timeSeriesQuery({
-      logger: service.logger,
+    const result = await timeSeriesQuery({
+      logger,
       callCluster: ctx.core.elasticsearch.legacy.client.callAsCurrentUser,
       query: req.body,
     });
 
-    service.logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
+    logger.debug(`route ${path} response: ${JSON.stringify(result)}`);
     return res.ok({ body: result });
   }
 }
diff --git a/x-pack/plugins/triggers_actions_ui/server/index.ts b/x-pack/plugins/triggers_actions_ui/server/index.ts
index c12572f4ea7e9..abd61f2bd3541 100644
--- a/x-pack/plugins/triggers_actions_ui/server/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/index.ts
@@ -4,8 +4,20 @@
  * you may not use this file except in compliance with the Elastic License.
  */
 
-import { PluginConfigDescriptor } from 'kibana/server';
+import { PluginConfigDescriptor, PluginInitializerContext } from 'kibana/server';
 import { configSchema, ConfigSchema } from '../config';
+import { TriggersActionsPlugin } from './plugin';
+
+export { PluginStartContract } from './plugin';
+export {
+  TimeSeriesQuery,
+  CoreQueryParams,
+  CoreQueryParamsSchemaProperties,
+  validateCoreQueryBody,
+  MAX_INTERVALS,
+  MAX_GROUPS,
+  DEFAULT_GROUPS,
+} from './data';
 
 export const config: PluginConfigDescriptor<ConfigSchema> = {
   exposeToBrowser: {
@@ -14,7 +26,4 @@ export const config: PluginConfigDescriptor<ConfigSchema> = {
   schema: configSchema,
 };
 
-export const plugin = () => ({
-  setup() {},
-  start() {},
-});
+export const plugin = (ctx: PluginInitializerContext) => new TriggersActionsPlugin(ctx);
diff --git a/x-pack/plugins/triggers_actions_ui/server/plugin.ts b/x-pack/plugins/triggers_actions_ui/server/plugin.ts
new file mode 100644
index 0000000000000..c0d29341e217b
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/server/plugin.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { Logger, Plugin, CoreSetup, PluginInitializerContext } from 'src/core/server';
+import { getService, register as registerDataService } from './data';
+
+export interface PluginStartContract {
+  data: ReturnType<typeof getService>;
+}
+
+export class TriggersActionsPlugin implements Plugin<void, PluginStartContract> {
+  private readonly logger: Logger;
+  private readonly data: PluginStartContract['data'];
+
+  constructor(ctx: PluginInitializerContext) {
+    this.logger = ctx.logger.get();
+    this.data = getService();
+  }
+
+  public async setup(core: CoreSetup): Promise<void> {
+    registerDataService({
+      logger: this.logger,
+      data: this.data,
+      router: core.http.createRouter(),
+      baseRoute: '/api/triggers_actions_ui',
+    });
+  }
+
+  public async start(): Promise<PluginStartContract> {
+    return {
+      data: this.data,
+    };
+  }
+
+  public async stop(): Promise<void> {}
+}
diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts
index c05fa6cf051ff..e918ce174a031 100644
--- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts
+++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts
@@ -15,7 +15,6 @@ import {
   ObjectRemover,
 } from '../../../../../common/lib';
 import { createEsDocuments } from './create_test_data';
-import { getAlertType } from '../../../../../../../plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/';
 
 const ALERT_TYPE_ID = '.index-threshold';
 const ACTION_TYPE_ID = '.index';
@@ -27,7 +26,7 @@ const ALERT_INTERVALS_TO_WRITE = 5;
 const ALERT_INTERVAL_SECONDS = 3;
 const ALERT_INTERVAL_MILLIS = ALERT_INTERVAL_SECONDS * 1000;
 
-const DefaultActionMessage = getAlertType().defaultActionMessage;
+const DefaultActionMessage = `alert {{alertName}} group {{context.group}} value {{context.value}} exceeded threshold {{context.function}} over {{params.timeWindowSize}}{{params.timeWindowUnit}} on {{context.date}}`;
 
 // eslint-disable-next-line import/no-default-export
 export default function alertTests({ getService }: FtrProviderContext) {
@@ -65,10 +64,6 @@ export default function alertTests({ getService }: FtrProviderContext) {
       await esTestIndexToolOutput.destroy();
     });
 
-    it('has a default action message', () => {
-      expect(DefaultActionMessage).to.be.ok();
-    });
-
     // The tests below create two alerts, one that will fire, one that will
     // never fire; the tests ensure the ones that should fire, do fire, and
     // those that shouldn't fire, do not fire.
diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/fields_endpoint.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/fields_endpoint.ts
index 76ff41aac5397..881be83236be5 100644
--- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/fields_endpoint.ts
+++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/fields_endpoint.ts
@@ -10,7 +10,7 @@ import { Spaces } from '../../../../scenarios';
 import { FtrProviderContext } from '../../../../../common/ftr_provider_context';
 import { ESTestIndexTool, ES_TEST_INDEX_NAME, getUrlPrefix } from '../../../../../common/lib';
 
-const API_URI = 'api/stack_alerts/index_threshold/_fields';
+const API_URI = 'api/triggers_actions_ui/data/_fields';
 
 // eslint-disable-next-line import/no-default-export
 export default function fieldsEndpointTests({ getService }: FtrProviderContext) {
diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/indices_endpoint.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/indices_endpoint.ts
index ba2b71e7134b6..7d89e2701d628 100644
--- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/indices_endpoint.ts
+++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/indices_endpoint.ts
@@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../../../../common/ftr_provider_context';
 import { ESTestIndexTool, ES_TEST_INDEX_NAME, getUrlPrefix } from '../../../../../common/lib';
 import { createEsDocuments } from './create_test_data';
 
-const API_URI = 'api/stack_alerts/index_threshold/_indices';
+const API_URI = 'api/triggers_actions_ui/data/_indices';
 
 // eslint-disable-next-line import/no-default-export
 export default function indicesEndpointTests({ getService }: FtrProviderContext) {
diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/time_series_query_endpoint.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/time_series_query_endpoint.ts
index 70dbb860e08d6..334f898232bbc 100644
--- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/time_series_query_endpoint.ts
+++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/time_series_query_endpoint.ts
@@ -9,11 +9,11 @@ import expect from '@kbn/expect';
 import { Spaces } from '../../../../scenarios';
 import { FtrProviderContext } from '../../../../../common/ftr_provider_context';
 import { ESTestIndexTool, ES_TEST_INDEX_NAME, getUrlPrefix } from '../../../../../common/lib';
-import { TimeSeriesQuery } from '../../../../../../../plugins/stack_alerts/server/alert_types/index_threshold/lib/time_series_query';
+import { TimeSeriesQuery } from '../../../../../../../plugins/triggers_actions_ui/server';
 
 import { createEsDocuments } from './create_test_data';
 
-const INDEX_THRESHOLD_TIME_SERIES_QUERY_URL = 'api/stack_alerts/index_threshold/_time_series_query';
+const INDEX_THRESHOLD_TIME_SERIES_QUERY_URL = 'api/triggers_actions_ui/data/_time_series_query';
 
 const START_DATE_MM_DD_HH_MM_SS_MS = '01-01T00:00:00.000Z';
 const START_DATE = `2020-${START_DATE_MM_DD_HH_MM_SS_MS}`;