diff --git a/packages/core/apps/core-apps-server-internal/src/core_app.ts b/packages/core/apps/core-apps-server-internal/src/core_app.ts
index c50ddd6e5cc1f..25a7c124a91a0 100644
--- a/packages/core/apps/core-apps-server-internal/src/core_app.ts
+++ b/packages/core/apps/core-apps-server-internal/src/core_app.ts
@@ -215,5 +215,10 @@ export class CoreAppsService {
       '/node_modules/@kbn/ui-framework/dist/{path*}',
       fromRoot('node_modules/@kbn/ui-framework/dist')
     );
+
+    core.http.registerStaticDir(
+      '/observabilityOnboarding/{path*}',
+      fromRoot('x-pack/plugins/observability_onboarding/public/assets')
+    );
   }
 }
diff --git a/x-pack/plugins/observability_onboarding/public/assets/standalone-agent-setup.sh b/x-pack/plugins/observability_onboarding/public/assets/standalone-agent-setup.sh
new file mode 100644
index 0000000000000..33a20de56e13a
--- /dev/null
+++ b/x-pack/plugins/observability_onboarding/public/assets/standalone-agent-setup.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# Arguments
+# ELASTIC_HOST=$1
+# ELASTIC_TOKEN=$2
+
+# download and extract Elastic Agent
+# curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.7.0-linux-x86_64.tar.gz
+# tar xzvf elastic-agent-8.7.0-linux-x86_64.tar.gz
+# cd elastic-agent-8.7.0-linux-x86_64
+
+# install Elastic Agent
+# sudo ./elastic-agent install --url=$ELASTIC_HOST --enrollment-token=$ELASTIC_TOKEN
+
+##  ➜  elastic-agent-8.7.1-linux-x86_64 sudo ./elastic-agent install
+##  [sudo] password for oliver:
+##  Elastic Agent will be installed at /opt/Elastic/Agent and will run as a service. Do you want to continue? [Y/n]:Y
+##  Do you want to enroll this Agent into Fleet? [Y/n]:n
+##  Elastic Agent has been successfully installed.
+
+# INSTALL_EXIT_CODE=$?
+
+# check the exit code to determine whether the installation was successful or not
+# if [ $INSTALL_EXIT_CODE -eq 0 ]; then
+#   INSTALL_RESULT="success"
+# else
+#   INSTALL_RESULT="failure"
+# fi
+
+# call the API with the installation result
+# curl -X POST "$KIBANA_HOST/api/observabilityOnboarding/agent-installation-status?host=$ELASTIC_HOST&token=$ELASTIC_TOKEN&result=$INSTALL_RESULT"
+
+########################
+
+API_KEY_ENCODED=$1
+STATUS_API_ENDPOINT=$2
+
+pingKibana () {
+  echo "  GET $STATUS_API_ENDPOINT?ping=$1"
+  curl --request GET \
+    --url "$STATUS_API_ENDPOINT?ping=$1" \
+    --header "Authorization: ApiKey $API_KEY_ENCODED" \
+    --header "Content-Type: application/json" \
+    --header "kbn-xsrf: true"
+  echo ""
+}
+
+echo "Downloading Elastic Agent"
+curl -L -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.7.1-linux-x86_64.tar.gz
+pingKibana "ea-download-success"
+echo "Extracting Elastic Agent"
+tar xzvf elastic-agent-8.7.1-linux-x86_64.tar.gz
+pingKibana "ea-extract-success"
+echo "Installing Elastic Agent"
+cd elastic-agent-8.7.1-linux-x86_64
+./elastic-agent install -f
+pingKibana "ea-install-success"
+echo "Sending status to Kibana..."
+pingKibana "ea-status-active"
diff --git a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx
index 410cc084608a8..f956c5613bdde 100644
--- a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx
+++ b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx
@@ -5,20 +5,16 @@
  * 2.0.
  */
 
-import React, { PropsWithChildren, useState } from 'react';
+import { Buffer } from 'buffer';
+import { flatten, zip } from 'lodash';
+import React, { useState } from 'react';
 import {
-  EuiTitle,
   EuiText,
   EuiButton,
-  EuiFlexGroup,
-  EuiFlexItem,
-  EuiHorizontalRule,
   EuiSpacer,
-  EuiCard,
-  EuiIcon,
-  EuiIconProps,
   EuiButtonGroup,
   EuiCodeBlock,
+  EuiSteps,
 } from '@elastic/eui';
 import {
   StepPanel,
@@ -26,178 +22,237 @@ import {
   StepPanelFooter,
 } from '../../../shared/step_panel';
 import { useWizard } from '.';
+import { useFetcher } from '../../../../hooks/use_fetcher';
+// import { useKibana } from '@kbn/kibana-react-plugin/public';
+// import type { CloudSetup } from '@kbn/cloud-plugin/public';
 
+type ElasticAgentPlatform = 'linux-tar' | 'macos' | 'windows';
 export function InstallElasticAgent() {
-  const { goToStep, goBack, getState, setState } = useWizard();
+  const { goToStep, goBack, getState } = useWizard();
   const wizardState = getState();
-  const [elasticAgentPlatform, setElasticAgentPlatform] = useState(
-    wizardState.elasticAgentPlatform
-  );
-  const [alternativeShippers, setAlternativeShippers] = useState(
-    wizardState.alternativeShippers
-  );
+  const [elasticAgentPlatform, setElasticAgentPlatform] =
+    useState<ElasticAgentPlatform>('linux-tar');
 
   function onContinue() {
-    setState({ ...getState(), elasticAgentPlatform, alternativeShippers });
     goToStep('collectLogs');
   }
 
-  function createAlternativeShipperToggle(
-    type: NonNullable<keyof typeof alternativeShippers>
-  ) {
-    return () => {
-      setAlternativeShippers({
-        ...alternativeShippers,
-        [type]: !alternativeShippers[type],
-      });
-    };
-  }
-
   function onBack() {
     goBack();
   }
 
+  const { data: installShipperSetup } = useFetcher((callApi) => {
+    return callApi(
+      'POST /internal/observability_onboarding/custom_logs/install_shipper_setup',
+      { params: { body: { name: wizardState.datasetName } } }
+    );
+  }, []);
+
+  const apiKeyEncoded = installShipperSetup?.apiKeyEncoded;
+  const esHost = installShipperSetup?.esHost;
+
+  // const { services } = useKibana<{ cloud?: CloudSetup }>();
+  // const isCloudEnabled = !!services?.cloud?.isCloudEnabled;
+  // const baseUrl = services?.cloud?.baseUrl;
+  // console.log(services);
+  // console.log(services.http?.getServerInfo());
+
+  const elasticAgentYaml = getElasticAgentYaml({
+    esHost,
+    apiKeyEncoded,
+    logfileId: 'custom-logs-abcdefgh',
+    logfileNamespace: 'default',
+    logfileStreams: [
+      {
+        id: 'logs-onboarding-demo-app',
+        dataset: 'demo1',
+        path: '/home/oliver/github/logs-onboarding-demo-app/combined.log',
+      },
+      // {
+      //   id: 'logfileStream-abcd1234',
+      //   dataset: 'nginxaccess',
+      //   path: '/var/log/nginx/access.log',
+      // },
+      // {
+      //   id: 'logfileStream-efgh5678',
+      //   dataset: 'nginxerror',
+      //   path: '/var/log/nginx/error.log',
+      // },
+    ],
+  });
+
   return (
-    <StepPanel
-      title="Install the Elastic Agent"
-      panelFooter={
-        <StepPanelFooter
-          items={[
-            <EuiButton color="ghost" fill onClick={onBack}>
-              Back
-            </EuiButton>,
-            <EuiButton color="primary" fill onClick={onContinue}>
-              Continue
-            </EuiButton>,
-          ]}
-        />
-      }
-    >
+    <StepPanel title="Install shipper to collect data">
       <StepPanelContent>
         <EuiText color="subdued">
           <p>
-            Select a platform and run the command to install, enroll, and start
-            the Elastic Agent. Do this for each host. For other platforms, see
-            our downloads page. Review host requirements and other installation
-            options.
+            Add Elastic Agent to your hosts to begin sending data to your
+            Elastic Cloud. Run standalone if you want to download and manage
+            each agent configuration file on your own, or enroll in Fleet, for
+            centralized management of all your agents through our Fleet managed
+            interface.
           </p>
         </EuiText>
         <EuiSpacer size="m" />
-        <EuiButtonGroup
-          isFullWidth
-          legend="Choose platform"
-          options={[
-            { id: 'linux-tar', label: 'Linux Tar' },
-            { id: 'macos', label: 'MacOs' },
-            { id: 'windows', label: 'Windows' },
-            { id: 'deb', label: 'DEB' },
-            { id: 'rpm', label: 'RPM' },
+        <EuiSteps
+          steps={[
+            {
+              title: 'Install the Elastic Agent',
+              status: 'current',
+              children: (
+                <>
+                  <EuiText color="subdued">
+                    <p>
+                      Select a platform and run the command to install in your
+                      Terminal, enroll, and start the Elastic Agent. Do this for
+                      each host. For other platforms, see our downloads page.
+                      Review host requirements and other installation options.
+                    </p>
+                  </EuiText>
+                  <EuiSpacer size="m" />
+                  <EuiButtonGroup
+                    isFullWidth
+                    legend="Choose platform"
+                    options={[
+                      { id: 'linux-tar', label: 'Linux' },
+                      { id: 'macos', label: 'MacOs', isDisabled: true },
+                      { id: 'windows', label: 'Windows', isDisabled: true },
+                    ]}
+                    type="single"
+                    idSelected={elasticAgentPlatform}
+                    onChange={(id: string) =>
+                      setElasticAgentPlatform(id as typeof elasticAgentPlatform)
+                    }
+                  />
+                  <EuiSpacer size="m" />
+                  <EuiCodeBlock language="bash" isCopyable>
+                    {getInstallShipperCommand({
+                      elasticAgentPlatform,
+                      apiKeyEncoded,
+                      statusApiEndpoint: installShipperSetup?.statusApiEndpoint,
+                      scriptDownloadUrl: installShipperSetup?.scriptDownloadUrl,
+                    })}
+                  </EuiCodeBlock>
+                </>
+              ),
+            },
+            {
+              title: 'Configure the agent',
+              status: 'incomplete',
+              children: (
+                <>
+                  <EuiText color="subdued">
+                    <p>
+                      Copy the config below to the elastic agent.yml on the host
+                      where the Elastic Agent is installed.
+                    </p>
+                  </EuiText>
+                  <EuiSpacer size="m" />
+                  <EuiCodeBlock language="yaml" isCopyable>
+                    {elasticAgentYaml}
+                  </EuiCodeBlock>
+                  <EuiSpacer size="m" />
+                  <EuiButton
+                    iconType="download"
+                    color="primary"
+                    href={`data:application/yaml;base64,${Buffer.from(
+                      elasticAgentYaml,
+                      'utf8'
+                    ).toString('base64')}`}
+                    download="elastic-agent.yml"
+                    target="_blank"
+                  >
+                    Download config file
+                  </EuiButton>
+                </>
+              ),
+            },
           ]}
-          type="single"
-          idSelected={elasticAgentPlatform}
-          onChange={(id: string) =>
-            setElasticAgentPlatform(id as typeof elasticAgentPlatform)
-          }
         />
-        <EuiSpacer size="m" />
-        <EuiCodeBlock language="html" isCopyable>
-          {PLATFORM_COMMAND[elasticAgentPlatform]}
-        </EuiCodeBlock>
-        <EuiHorizontalRule margin="l" />
-        <LogsTypeSection title="Or select alternative shippers" description="">
-          <EuiFlexGroup>
-            <EuiFlexItem>
-              <OptionCard
-                title="Filebeat"
-                iconType="document"
-                onClick={createAlternativeShipperToggle('filebeat')}
-                isSelected={alternativeShippers.filebeat}
-              />
-            </EuiFlexItem>
-            <EuiFlexItem>
-              <OptionCard
-                title="fluentbit"
-                iconType="package"
-                onClick={createAlternativeShipperToggle('fluentbit')}
-                isSelected={alternativeShippers.fluentbit}
-              />
-            </EuiFlexItem>
-          </EuiFlexGroup>
-          <EuiSpacer size="m" />
-          <EuiFlexGroup>
-            <EuiFlexItem>
-              <OptionCard
-                title="Logstash"
-                iconType="logstashIf"
-                onClick={createAlternativeShipperToggle('logstash')}
-                isSelected={alternativeShippers.logstash}
-              />
-            </EuiFlexItem>
-            <EuiFlexItem>
-              <OptionCard
-                title="Fluentd"
-                iconType="package"
-                onClick={createAlternativeShipperToggle('fluentd')}
-                isSelected={alternativeShippers.fluentd}
-              />
-            </EuiFlexItem>
-          </EuiFlexGroup>
-        </LogsTypeSection>
       </StepPanelContent>
+      <StepPanelFooter
+        items={[
+          <EuiButton color="ghost" fill onClick={onBack}>
+            Back
+          </EuiButton>,
+          <EuiButton color="primary" fill onClick={onContinue}>
+            Continue
+          </EuiButton>,
+        ]}
+      />
     </StepPanel>
   );
 }
 
-function LogsTypeSection({
-  title,
-  description,
-  children,
-}: PropsWithChildren<{ title: string; description: string }>) {
-  return (
-    <>
-      <EuiTitle size="s">
-        <h3>{title}</h3>
-      </EuiTitle>
-      <EuiSpacer size="m" />
-      <EuiText color="subdued">
-        <p>{description}</p>
-      </EuiText>
-      <EuiSpacer size="m" />
-      {children}
-    </>
-  );
+function getInstallShipperCommand({
+  elasticAgentPlatform,
+  apiKeyEncoded = '$API_KEY',
+  statusApiEndpoint = '$STATUS_API_ENDPOINT',
+  scriptDownloadUrl = '$SCRIPT_DOWNLOAD_URL',
+}: {
+  elasticAgentPlatform: ElasticAgentPlatform;
+  apiKeyEncoded: string | undefined;
+  statusApiEndpoint: string | undefined;
+  scriptDownloadUrl: string | undefined;
+}) {
+  const setupScriptFilename = 'standalone-agent-setup.sh';
+  const PLATFORM_COMMAND: Record<ElasticAgentPlatform, string> = {
+    'linux-tar': oneLine`
+      curl ${scriptDownloadUrl} -o ${setupScriptFilename} &&
+      sudo bash ${setupScriptFilename} ${apiKeyEncoded} ${statusApiEndpoint}
+    `,
+    macos: oneLine`
+      curl -O https://elastic.co/agent-setup.sh &&
+      sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==
+    `,
+    windows: oneLine`
+      curl -O https://elastic.co/agent-setup.sh &&
+      sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==
+    `,
+  };
+  return PLATFORM_COMMAND[elasticAgentPlatform];
+}
+
+function oneLine(parts: TemplateStringsArray, ...args: string[]) {
+  const str = flatten(zip(parts, args)).join('');
+  return str.replace(/\s+/g, ' ').trim();
 }
 
-function OptionCard({
-  title,
-  iconType,
-  onClick,
-  isSelected,
+function getElasticAgentYaml({
+  esHost = '$ES_HOST',
+  apiKeyEncoded = '$API_KEY',
+  logfileId,
+  logfileNamespace,
+  logfileStreams,
 }: {
-  title: string;
-  iconType: EuiIconProps['type'];
-  onClick: () => void;
-  isSelected: boolean;
+  esHost: string | undefined;
+  apiKeyEncoded: string | undefined;
+  logfileId: string;
+  logfileNamespace: string;
+  logfileStreams: Array<{ id: string; dataset: string; path: string }>;
 }) {
-  return (
-    <EuiCard
-      layout="horizontal"
-      icon={<EuiIcon type={iconType} size="l" />}
-      title={title}
-      titleSize="xs"
-      paddingSize="m"
-      style={{ height: 56 }}
-      onClick={onClick}
-      hasBorder={true}
-      display={isSelected ? 'primary' : undefined}
-    />
-  );
-}
+  const apiKeyBeats = Buffer.from(apiKeyEncoded, 'base64').toString('utf8');
+  return `
+outputs:
+  default:
+    type: elasticsearch
+    hosts:
+      - '${esHost}'
+    api_key: ${apiKeyBeats}
 
-const PLATFORM_COMMAND = {
-  'linux-tar': `curl -O https://elastic.co/agent-setup.sh && sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==`,
-  macos: `curl -O https://elastic.co/agent-setup.sh && sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==`,
-  windows: `curl -O https://elastic.co/agent-setup.sh && sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==`,
-  deb: `curl -O https://elastic.co/agent-setup.sh && sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==`,
-  rpm: `curl -O https://elastic.co/agent-setup.sh && sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==`,
-} as const;
+inputs:
+  - id: ${logfileId}
+    type: logfile
+    data_stream:
+      namespace: ${logfileNamespace}
+    streams:
+${logfileStreams
+  .map(
+    ({ id, dataset, path }) => `      - id: ${id}
+        data_stream:
+          dataset: ${dataset}
+        paths:
+          - ${path}`
+  )
+  .join('\n')}`.trim();
+}
diff --git a/x-pack/plugins/observability_onboarding/server/plugin.ts b/x-pack/plugins/observability_onboarding/server/plugin.ts
index 3045ad66c869e..6391f50e62838 100644
--- a/x-pack/plugins/observability_onboarding/server/plugin.ts
+++ b/x-pack/plugins/observability_onboarding/server/plugin.ts
@@ -60,6 +60,19 @@ export class ObservabilityOnboardingPlugin
       };
     }) as ObservabilityOnboardingRouteHandlerResources['plugins'];
 
+    // const router = core.http.createRouter();
+    // router.get(
+    //   { path: '/api/observability_onboarding/dev', validate: false },
+    //   async (context, req, res) => {
+    //     const coreContext = await context.core;
+    //     const esHosts = getESHosts({
+    //       cloudSetup: plugins.cloud,
+    //       esClient: coreContext.elasticsearch.client.asCurrentUser as Client,
+    //     });
+    //     return res.ok({ body: { esHosts } });
+    //   }
+    // );
+
     registerRoutes({
       core,
       logger: this.logger,
diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/create_shipper_api_key.ts b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/create_shipper_api_key.ts
new file mode 100644
index 0000000000000..1f0c47aaf87cf
--- /dev/null
+++ b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/create_shipper_api_key.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { ElasticsearchClient } from '@kbn/core/server';
+
+export function createShipperApiKey(
+  esClient: ElasticsearchClient,
+  name: string
+) {
+  return esClient.security.createApiKey({
+    body: {
+      name: `standalone_agent_custom_logs_${name}`,
+      metadata: { application: 'logs' },
+      role_descriptors: {
+        standalone_agent: {
+          cluster: ['monitor'],
+          indices: [
+            {
+              names: ['logs-*-*', 'metrics-*-*'],
+              privileges: ['auto_configure', 'create_doc'],
+            },
+          ],
+        },
+      },
+    },
+  });
+}
+
+export function _createShipperApiKey(
+  esClient: ElasticsearchClient,
+  name: string
+) {
+  return esClient.security.createApiKey({
+    body: {
+      name: `custom-logs-standalone-elastic-agent-${name}`,
+      metadata: {
+        application: 'logs',
+      },
+      role_descriptors: {
+        superuser: {
+          cluster: ['all'],
+          indices: [
+            {
+              names: ['*'],
+              privileges: ['all'],
+              allow_restricted_indices: false,
+            },
+            {
+              names: ['*'],
+              privileges: [
+                'monitor',
+                'read',
+                'view_index_metadata',
+                'read_cross_cluster',
+              ],
+              allow_restricted_indices: true,
+            },
+          ],
+          run_as: ['*'],
+        },
+      },
+    },
+  });
+}
diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_es_hosts.ts b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_es_hosts.ts
new file mode 100644
index 0000000000000..f9d35da7d3534
--- /dev/null
+++ b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_es_hosts.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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Client } from '@elastic/elasticsearch';
+import { CloudSetup } from '@kbn/cloud-plugin/server';
+import { decodeCloudId } from '@kbn/fleet-plugin/common';
+
+const DEFAULT_ES_HOSTS = ['http://localhost:9200'];
+
+export function getESHosts({
+  cloudSetup,
+  esClient,
+}: {
+  cloudSetup: CloudSetup;
+  esClient: Client;
+}): string[] {
+  if (cloudSetup.cloudId) {
+    const cloudUrl = decodeCloudId(cloudSetup.cloudId)?.elasticsearchUrl;
+    if (cloudUrl) {
+      return [cloudUrl];
+    }
+  }
+
+  const aliveConnections = esClient.connectionPool.connections.filter(
+    ({ status }) => status === 'alive'
+  );
+  if (aliveConnections.length) {
+    return aliveConnections.map(({ url }) => {
+      const { protocol, host } = new URL(url);
+      return `${protocol}//${host}`;
+    });
+  }
+
+  return DEFAULT_ES_HOSTS;
+}
diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_kibana_url.ts b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_kibana_url.ts
new file mode 100644
index 0000000000000..95110f4707576
--- /dev/null
+++ b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_kibana_url.ts
@@ -0,0 +1,14 @@
+/*
+ * 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 { CoreStart } from '@kbn/core/server';
+
+export function getKibanaUrl({ http }: CoreStart, path = '') {
+  const basePath = http.basePath;
+  const { protocol, hostname, port } = http.getServerInfo();
+  return `${protocol}://${hostname}:${port}${basePath.prepend(path)}`;
+}
diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts
new file mode 100644
index 0000000000000..bd2a7d52830e5
--- /dev/null
+++ b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts
@@ -0,0 +1,91 @@
+/*
+ * 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 * as t from 'io-ts';
+import type { Client } from '@elastic/elasticsearch';
+import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route';
+import { getESHosts } from './get_es_hosts';
+import { getKibanaUrl } from './get_kibana_url';
+import { createShipperApiKey } from './create_shipper_api_key';
+
+const createApiKeyRoute = createObservabilityOnboardingServerRoute({
+  endpoint:
+    'POST /internal/observability_onboarding/custom_logs/install_shipper_setup',
+  options: { tags: [] },
+  params: t.type({
+    body: t.type({
+      name: t.string,
+    }),
+  }),
+  async handler(resources): Promise<{
+    apiKeyId: string;
+    apiKeyEncoded: string;
+    statusApiEndpoint: string;
+    scriptDownloadUrl: string;
+    esHost: string;
+  }> {
+    const {
+      context,
+      params: {
+        body: { name },
+      },
+      core,
+      plugins,
+    } = resources;
+    const coreStart = await core.start();
+    const scriptDownloadUrl = getKibanaUrl(
+      coreStart,
+      '/observabilityOnboarding/standalone-agent-setup.sh'
+    );
+    const statusApiEndpoint = getKibanaUrl(
+      coreStart,
+      '/api/observability_onboarding/custom_logs/status'
+    );
+    const {
+      elasticsearch: { client },
+    } = await context.core;
+    const { id: apiKeyId, encoded: apiKeyEncoded } = await createShipperApiKey(
+      client.asCurrentUser,
+      name
+    );
+    const [esHost] = getESHosts({
+      cloudSetup: plugins.cloud.setup,
+      esClient: coreStart.elasticsearch.client.asInternalUser as Client,
+    });
+
+    return {
+      apiKeyId, //key the status off this
+      apiKeyEncoded,
+      statusApiEndpoint,
+      scriptDownloadUrl,
+      esHost,
+    };
+  },
+});
+
+const updateStatusRoute = createObservabilityOnboardingServerRoute({
+  endpoint: 'GET /api/observability_onboarding/custom_logs/status',
+  options: { tags: [] },
+  params: t.type({
+    query: t.type({
+      ping: t.string,
+    }),
+  }),
+  async handler(resources): Promise<{ ok: string; ping: string }> {
+    const {
+      params: {
+        query: { ping },
+      },
+    } = resources;
+    return { ok: 'success', ping };
+  },
+});
+
+export const customLogsRouteRepository = {
+  ...createApiKeyRoute,
+  ...updateStatusRoute,
+};
diff --git a/x-pack/plugins/observability_onboarding/server/routes/index.ts b/x-pack/plugins/observability_onboarding/server/routes/index.ts
index 6a1067465787c..e68bc3e075993 100644
--- a/x-pack/plugins/observability_onboarding/server/routes/index.ts
+++ b/x-pack/plugins/observability_onboarding/server/routes/index.ts
@@ -9,10 +9,12 @@ import type {
   ServerRouteRepository,
 } from '@kbn/server-route-repository';
 import { statusRouteRepository } from './status/route';
+import { customLogsRouteRepository } from './custom_logs/route';
 
 function getTypedObservabilityOnboardingServerRouteRepository() {
   const repository = {
     ...statusRouteRepository,
+    ...customLogsRouteRepository,
   };
 
   return repository;
diff --git a/x-pack/plugins/observability_onboarding/server/routes/register_routes.ts b/x-pack/plugins/observability_onboarding/server/routes/register_routes.ts
index 83000c1eaeec4..0220f64582396 100644
--- a/x-pack/plugins/observability_onboarding/server/routes/register_routes.ts
+++ b/x-pack/plugins/observability_onboarding/server/routes/register_routes.ts
@@ -66,6 +66,13 @@ export function registerRoutes({
             logger,
             params: decodedParams,
             plugins,
+            core: {
+              setup: core,
+              start: async () => {
+                const [coreStart] = await core.getStartServices();
+                return coreStart;
+              },
+            },
           })) as any;
 
           if (data === undefined) {
diff --git a/x-pack/plugins/observability_onboarding/server/routes/types.ts b/x-pack/plugins/observability_onboarding/server/routes/types.ts
index c8f1c0dc99560..6988561f84e44 100644
--- a/x-pack/plugins/observability_onboarding/server/routes/types.ts
+++ b/x-pack/plugins/observability_onboarding/server/routes/types.ts
@@ -4,7 +4,7 @@
  * 2.0; you may not use this file except in compliance with the Elastic License
  * 2.0.
  */
-import { KibanaRequest, Logger } from '@kbn/core/server';
+import { CoreSetup, CoreStart, KibanaRequest, Logger } from '@kbn/core/server';
 import { ObservabilityOnboardingServerRouteRepository } from '.';
 import {
   ObservabilityOnboardingPluginSetupDependencies,
@@ -26,6 +26,10 @@ export interface ObservabilityOnboardingRouteHandlerResources {
       >;
     };
   };
+  core: {
+    setup: CoreSetup;
+    start: () => Promise<CoreStart>;
+  };
 }
 
 export interface ObservabilityOnboardingRouteCreateOptions {
diff --git a/x-pack/plugins/observability_onboarding/server/types.ts b/x-pack/plugins/observability_onboarding/server/types.ts
index 99e7157178ff1..93113a5043904 100644
--- a/x-pack/plugins/observability_onboarding/server/types.ts
+++ b/x-pack/plugins/observability_onboarding/server/types.ts
@@ -5,21 +5,27 @@
  * 2.0.
  */
 
+import { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server';
 import { CustomRequestHandlerContext } from '@kbn/core/server';
 import {
   PluginSetup as DataPluginSetup,
   PluginStart as DataPluginStart,
 } from '@kbn/data-plugin/server';
 import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
+import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
 
 export interface ObservabilityOnboardingPluginSetupDependencies {
   data: DataPluginSetup;
   observability: ObservabilityPluginSetup;
+  cloud: CloudSetup;
+  usageCollection: UsageCollectionSetup;
 }
 
 export interface ObservabilityOnboardingPluginStartDependencies {
   data: DataPluginStart;
   observability: undefined;
+  cloud: CloudStart;
+  usageCollection: undefined;
 }
 
 // eslint-disable-next-line @typescript-eslint/no-empty-interface