diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/index.ts
new file mode 100644
index 0000000000000..d7a36e3e447b7
--- /dev/null
+++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/index.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context';
+
+export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) {
+  describe('entities', () => {
+    loadTestFile(require.resolve('./service_logs_error_rate_timeseries.spec.ts'));
+    loadTestFile(require.resolve('./service_logs_rate_timeseries.spec.ts'));
+  });
+}
diff --git a/x-pack/test/apm_api_integration/tests/entities/logs/service_logs_error_rate_timeseries.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_error_rate_timeseries.spec.ts
similarity index 85%
rename from x-pack/test/apm_api_integration/tests/entities/logs/service_logs_error_rate_timeseries.spec.ts
rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_error_rate_timeseries.spec.ts
index 282039b8957c9..f6e167db0318e 100644
--- a/x-pack/test/apm_api_integration/tests/entities/logs/service_logs_error_rate_timeseries.spec.ts
+++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_error_rate_timeseries.spec.ts
@@ -9,12 +9,12 @@ import { log, timerange } from '@kbn/apm-synthtrace-client';
 import { first, last } from 'lodash';
 import { RecursivePartial } from '@kbn/apm-plugin/typings/common';
 import { APIClientRequestParamsOf } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
-import { FtrProviderContext } from '../../../common/ftr_provider_context';
+import { LogsSynthtraceEsClient } from '@kbn/apm-synthtrace';
+import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context';
 
-export default function ApiTest({ getService }: FtrProviderContext) {
-  const registry = getService('registry');
-  const apmApiClient = getService('apmApiClient');
-  const logSynthtrace = getService('logSynthtraceEsClient');
+export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) {
+  const apmApiClient = getService('apmApi');
+  const synthtrace = getService('synthtrace');
 
   const serviceName = 'synth-go';
   const start = new Date('2024-01-01T00:00:00.000Z').getTime();
@@ -45,25 +45,26 @@ export default function ApiTest({ getService }: FtrProviderContext) {
     });
     return response;
   }
+  describe('logs error rate timeseries', () => {
+    describe('when data is not loaded', () => {
+      it('handles empty state', async () => {
+        const response = await getLogsErrorRateTimeseries();
+        expect(response.status).to.be(200);
+        expect(response.body.currentPeriod).to.empty();
+      });
+    });
 
-  registry.when(
-    'Logs error rate timeseries when data is not loaded',
-    { config: 'basic', archives: [] },
-    () => {
-      describe('Logs error rate api', () => {
-        it('handles the empty state', async () => {
-          const response = await getLogsErrorRateTimeseries();
-          expect(response.status).to.be(200);
-          expect(response.body.currentPeriod).to.empty();
-        });
+    describe('when data loaded', () => {
+      let logSynthtrace: LogsSynthtraceEsClient;
+
+      before(async () => {
+        logSynthtrace = await synthtrace.createLogsSynthtraceEsClient();
+      });
+
+      after(async () => {
+        await logSynthtrace.clean();
       });
-    }
-  );
 
-  registry.when(
-    'Logs error rate timeseries when data loaded',
-    { config: 'basic', archives: [] },
-    () => {
       describe('Logs without log level field', () => {
         before(async () => {
           return logSynthtrace.index([
@@ -170,6 +171,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
           });
         });
       });
-    }
-  );
+    });
+  });
 }
diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_rate_timeseries.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_rate_timeseries.spec.ts
new file mode 100644
index 0000000000000..fb10925b9906d
--- /dev/null
+++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/entities/service_logs_rate_timeseries.spec.ts
@@ -0,0 +1,180 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import expect from '@kbn/expect';
+import { log, timerange } from '@kbn/apm-synthtrace-client';
+import { RecursivePartial } from '@kbn/apm-plugin/typings/common';
+import { APIClientRequestParamsOf } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
+import { first, last } from 'lodash';
+import { LogsSynthtraceEsClient } from '@kbn/apm-synthtrace';
+import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context';
+
+export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) {
+  const apmApiClient = getService('apmApi');
+  const synthtrace = getService('synthtrace');
+
+  const serviceName = 'synth-go';
+  const start = new Date('2024-01-01T00:00:00.000Z').getTime();
+  const end = new Date('2024-01-01T00:15:00.000Z').getTime() - 1;
+
+  const hostName = 'synth-host';
+
+  async function getLogsRateTimeseries(
+    overrides?: RecursivePartial<
+      APIClientRequestParamsOf<'GET /internal/apm/entities/services/{serviceName}/logs_rate_timeseries'>['params']
+    >
+  ) {
+    const response = await apmApiClient.readUser({
+      endpoint: 'GET /internal/apm/entities/services/{serviceName}/logs_rate_timeseries',
+      params: {
+        path: {
+          serviceName: 'synth-go',
+          ...overrides?.path,
+        },
+        query: {
+          start: new Date(start).toISOString(),
+          end: new Date(end).toISOString(),
+          environment: 'ENVIRONMENT_ALL',
+          kuery: '',
+          ...overrides?.query,
+        },
+      },
+    });
+    return response;
+  }
+  describe('logs rate timeseries', () => {
+    describe('when data is not loaded', () => {
+      it('handles empty state', async () => {
+        const response = await getLogsRateTimeseries();
+        expect(response.status).to.be(200);
+        expect(response.body.currentPeriod).to.empty();
+      });
+    });
+
+    describe('when data loaded', () => {
+      let logSynthtrace: LogsSynthtraceEsClient;
+
+      before(async () => {
+        logSynthtrace = await synthtrace.createLogsSynthtraceEsClient();
+      });
+
+      after(async () => {
+        await logSynthtrace.clean();
+      });
+
+      describe('Logs without log level field', () => {
+        before(async () => {
+          return logSynthtrace.index([
+            timerange(start, end)
+              .interval('1m')
+              .rate(1)
+              .generator((timestamp) =>
+                log.create().message('This is a log message').timestamp(timestamp).defaults({
+                  'log.file.path': '/my-service.log',
+                  'service.name': serviceName,
+                  'host.name': hostName,
+                })
+              ),
+          ]);
+        });
+        after(async () => {
+          await logSynthtrace.clean();
+        });
+
+        it('returns {} if log level is not available ', async () => {
+          const response = await getLogsRateTimeseries();
+          expect(response.status).to.be(200);
+        });
+      });
+
+      describe('Logs with log.level=error', () => {
+        before(async () => {
+          return logSynthtrace.index([
+            timerange(start, end)
+              .interval('1m')
+              .rate(1)
+              .generator((timestamp) =>
+                log
+                  .create()
+                  .message('This is a log message')
+                  .logLevel('error')
+                  .timestamp(timestamp)
+                  .defaults({
+                    'log.file.path': '/my-service.log',
+                    'service.name': serviceName,
+                    'host.name': hostName,
+                    'service.environment': 'test',
+                  })
+              ),
+            timerange(start, end)
+              .interval('2m')
+              .rate(1)
+              .generator((timestamp) =>
+                log
+                  .create()
+                  .message('This is an error log message')
+                  .logLevel('error')
+                  .timestamp(timestamp)
+                  .defaults({
+                    'log.file.path': '/my-service.log',
+                    'service.name': 'my-service',
+                    'host.name': hostName,
+                    'service.environment': 'production',
+                  })
+              ),
+            timerange(start, end)
+              .interval('5m')
+              .rate(1)
+              .generator((timestamp) =>
+                log
+                  .create()
+                  .message('This is an info message')
+                  .logLevel('info')
+                  .timestamp(timestamp)
+                  .defaults({
+                    'log.file.path': '/my-service.log',
+                    'service.name': 'my-service',
+                    'host.name': hostName,
+                    'service.environment': 'production',
+                  })
+              ),
+          ]);
+        });
+        after(async () => {
+          await logSynthtrace.clean();
+        });
+
+        it('returns log rate timeseries', async () => {
+          const response = await getLogsRateTimeseries();
+          expect(response.status).to.be(200);
+          expect(
+            response.body.currentPeriod[serviceName].every(({ y }) => y === 0.06666666666666667)
+          ).to.be(true);
+        });
+
+        it('handles environment filter', async () => {
+          const response = await getLogsRateTimeseries({ query: { environment: 'foo' } });
+          expect(response.status).to.be(200);
+          expect(response.body.currentPeriod).to.empty();
+        });
+
+        describe('when my-service is selected', () => {
+          it('returns some data', async () => {
+            const response = await getLogsRateTimeseries({
+              path: { serviceName: 'my-service' },
+            });
+
+            expect(response.status).to.be(200);
+            expect(first(response.body.currentPeriod?.['my-service'])?.y).to.be(
+              0.18181818181818182
+            );
+            expect(last(response.body.currentPeriod?.['my-service'])?.y).to.be(0.09090909090909091);
+          });
+        });
+      });
+    });
+  });
+}
diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts
index 3e490a621d3f9..f8c0352984473 100644
--- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts
+++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts
@@ -15,6 +15,7 @@ export default function apmApiIntegrationTests({
     loadTestFile(require.resolve('./mobile'));
     loadTestFile(require.resolve('./custom_dashboards'));
     loadTestFile(require.resolve('./dependencies'));
+    loadTestFile(require.resolve('./entities'));
     loadTestFile(require.resolve('./cold_start'));
   });
 }
diff --git a/x-pack/test/apm_api_integration/tests/entities/logs/service_logs_rate_timeseries.spec.ts b/x-pack/test/apm_api_integration/tests/entities/logs/service_logs_rate_timeseries.spec.ts
deleted file mode 100644
index d4717b25bba93..0000000000000
--- a/x-pack/test/apm_api_integration/tests/entities/logs/service_logs_rate_timeseries.spec.ts
+++ /dev/null
@@ -1,173 +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
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-import expect from '@kbn/expect';
-import { log, timerange } from '@kbn/apm-synthtrace-client';
-import { RecursivePartial } from '@kbn/apm-plugin/typings/common';
-import { APIClientRequestParamsOf } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
-import { first, last } from 'lodash';
-import { FtrProviderContext } from '../../../common/ftr_provider_context';
-
-export default function ApiTest({ getService }: FtrProviderContext) {
-  const registry = getService('registry');
-  const apmApiClient = getService('apmApiClient');
-  const logSynthtrace = getService('logSynthtraceEsClient');
-
-  const serviceName = 'synth-go';
-  const start = new Date('2024-01-01T00:00:00.000Z').getTime();
-  const end = new Date('2024-01-01T00:15:00.000Z').getTime() - 1;
-
-  const hostName = 'synth-host';
-
-  async function getLogsRateTimeseries(
-    overrides?: RecursivePartial<
-      APIClientRequestParamsOf<'GET /internal/apm/entities/services/{serviceName}/logs_rate_timeseries'>['params']
-    >
-  ) {
-    const response = await apmApiClient.readUser({
-      endpoint: 'GET /internal/apm/entities/services/{serviceName}/logs_rate_timeseries',
-      params: {
-        path: {
-          serviceName: 'synth-go',
-          ...overrides?.path,
-        },
-        query: {
-          start: new Date(start).toISOString(),
-          end: new Date(end).toISOString(),
-          environment: 'ENVIRONMENT_ALL',
-          kuery: '',
-          ...overrides?.query,
-        },
-      },
-    });
-    return response;
-  }
-
-  registry.when(
-    'Logs rate timeseries when data is not loaded',
-    { config: 'basic', archives: [] },
-    () => {
-      describe('Logs rate api', () => {
-        it('handles the empty state', async () => {
-          const response = await getLogsRateTimeseries();
-          expect(response.status).to.be(200);
-          expect(response.body.currentPeriod).to.empty();
-        });
-      });
-    }
-  );
-
-  registry.when('Logs rate timeseries when data loaded', { config: 'basic', archives: [] }, () => {
-    describe('Logs without log level field', () => {
-      before(async () => {
-        return logSynthtrace.index([
-          timerange(start, end)
-            .interval('1m')
-            .rate(1)
-            .generator((timestamp) =>
-              log.create().message('This is a log message').timestamp(timestamp).defaults({
-                'log.file.path': '/my-service.log',
-                'service.name': serviceName,
-                'host.name': hostName,
-              })
-            ),
-        ]);
-      });
-      after(async () => {
-        await logSynthtrace.clean();
-      });
-
-      it('returns {} if log level is not available ', async () => {
-        const response = await getLogsRateTimeseries();
-        expect(response.status).to.be(200);
-      });
-    });
-
-    describe('Logs with log.level=error', () => {
-      before(async () => {
-        return logSynthtrace.index([
-          timerange(start, end)
-            .interval('1m')
-            .rate(1)
-            .generator((timestamp) =>
-              log
-                .create()
-                .message('This is a log message')
-                .logLevel('error')
-                .timestamp(timestamp)
-                .defaults({
-                  'log.file.path': '/my-service.log',
-                  'service.name': serviceName,
-                  'host.name': hostName,
-                  'service.environment': 'test',
-                })
-            ),
-          timerange(start, end)
-            .interval('2m')
-            .rate(1)
-            .generator((timestamp) =>
-              log
-                .create()
-                .message('This is an error log message')
-                .logLevel('error')
-                .timestamp(timestamp)
-                .defaults({
-                  'log.file.path': '/my-service.log',
-                  'service.name': 'my-service',
-                  'host.name': hostName,
-                  'service.environment': 'production',
-                })
-            ),
-          timerange(start, end)
-            .interval('5m')
-            .rate(1)
-            .generator((timestamp) =>
-              log
-                .create()
-                .message('This is an info message')
-                .logLevel('info')
-                .timestamp(timestamp)
-                .defaults({
-                  'log.file.path': '/my-service.log',
-                  'service.name': 'my-service',
-                  'host.name': hostName,
-                  'service.environment': 'production',
-                })
-            ),
-        ]);
-      });
-      after(async () => {
-        await logSynthtrace.clean();
-      });
-
-      it('returns log rate timeseries', async () => {
-        const response = await getLogsRateTimeseries();
-        expect(response.status).to.be(200);
-        expect(
-          response.body.currentPeriod[serviceName].every(({ y }) => y === 0.06666666666666667)
-        ).to.be(true);
-      });
-
-      it('handles environment filter', async () => {
-        const response = await getLogsRateTimeseries({ query: { environment: 'foo' } });
-        expect(response.status).to.be(200);
-        expect(response.body.currentPeriod).to.empty();
-      });
-
-      describe('when my-service is selected', () => {
-        it('returns some data', async () => {
-          const response = await getLogsRateTimeseries({
-            path: { serviceName: 'my-service' },
-          });
-
-          expect(response.status).to.be(200);
-          expect(first(response.body.currentPeriod?.['my-service'])?.y).to.be(0.18181818181818182);
-          expect(last(response.body.currentPeriod?.['my-service'])?.y).to.be(0.09090909090909091);
-        });
-      });
-    });
-  });
-}