Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to Datadog

Scalekit connector
Open markdown

The Datadog connector lets your AI agent act in each user's Datadog account. Each user connects their own Datadog API key once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 105 tools.

Tools
105
What they doRead · write · destructive
54 · 38 · 1354 read38 write13 destructive
Users sign in with

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Datadog connection

    In AgentKit > Connections, create a Datadog connection. The name you give it is the connection_name your code passes. See Configure connections.

    Console steps with screenshots

    Register your Datadog API credentials with Scalekit so Scalekit can proxy API requests and inject your keys automatically. Datadog uses API key authentication.

    1. Find your Datadog site

      Datadog hosts accounts on regional sites. You must provide your site when creating a connected account — Scalekit uses it to route API calls to the correct endpoint.

      Site identifierRegion
      datadoghq.comUS1 (default)
      us3.datadoghq.comUS3
      us5.datadoghq.comUS5
      datadoghq.euEU1
      ap1.datadoghq.comAP1
      ddog-gov.comUS1-FED (GovCloud)

      If you are unsure which site your account uses, check the URL when you sign in to Datadog — for example, app.datadoghq.eu means your site is datadoghq.eu. See the Datadog site documentation for details.

    2. Get your Datadog API key and Application key

      • Sign in to Datadog and go to Organization Settings → API Keys.
      • Copy an existing API key or click + New Key to create one dedicated to this integration.

      Datadog Organization Settings API Keys page showing existing keys and a New Key button

      • Go to Organization Settings → Application Keys.
      • Copy an existing Application key or click + New Key to create a dedicated one. Copy the key value immediately — Datadog will not show it again.

      Datadog New Application Key creation modal showing key name, key value to copy, and Actions API Access enabled

    3. Create a connection in Scalekit

      • In Scalekit dashboard, go to AgentKit → Connections → Create Connection. Find Datadog and click Create.

      Datadog connector shown in Scalekit's Create Connection search

      • Note the Connection name — you will use this as connection_name in your code (e.g., datadog).
      • Click Save.

      Scalekit connection configuration for Datadog showing connection name and API Key authentication type

    4. Add a connected account

      Connected accounts link a specific user identifier in your system to a set of Datadog credentials. Add one in the dashboard to test. In production, each user adds their own through the authorization link: they enter their credentials on the page it opens.

      In the dashboard, to test

      • Open the connection you created and click the Connected Accounts tab → Add account.
      • Fill in:
        • Your User’s ID — a unique identifier for this user in your system (e.g., user_123)
        • API Key — the Datadog API key from step 2
        • Application Key — the Datadog Application key from step 2
        • Datadog Site — your site identifier from step 1 (e.g., datadoghq.com)
      • Click Create Account.

      Add connected account form for Datadog in Scalekit showing User ID, API Key, Application Key, and Datadog Site fields

      From your backend, if your app already has the credentials

      For example, when users enter them on a settings page in your app:

      import { Scalekit, ConnectorStatus } from '@scalekit-sdk/node';
      const scalekit = new Scalekit(
      process.env.SCALEKIT_ENVIRONMENT_URL,
      process.env.SCALEKIT_CLIENT_ID,
      process.env.SCALEKIT_CLIENT_SECRET,
      );
      // Never hard-code credentials — read from secure storage or user input
      const datadogApiKey = getUserDatadogApiKey(); // retrieve from your secure store
      const datadogAppKey = getUserDatadogAppKey();
      const datadogSite = getUserDatadogSite(); // e.g. 'datadoghq.com'
      const authorizationDetails = {
      details: {
      case: 'staticAuth',
      value: {
      details: {
      api_key: datadogApiKey,
      app_key: datadogAppKey,
      dd_site: datadogSite,
      },
      },
      },
      };
      let { connectedAccount } = await scalekit.actions.upsertConnectedAccount({
      connectionName: 'datadog',
      identifier: 'user_123',
      authorizationDetails,
      });
      // Make sure the account is ACTIVE before the first tool call.
      if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
      ({ connectedAccount } = await scalekit.actions.upsertConnectedAccount({
      connectionName: 'datadog',
      identifier: 'user_123',
      authorizationDetails,
      }));
      }
  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'datadog'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Datadog:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'datadog_current_user_get',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user opens the link once and enters their Datadog credentials there. If your app already has a user's credentials, add the account from your backend instead, as the console steps above show. See Authorize a user for the full flow and statuses.

Most tools require IDs that must be fetched from the API — never guess or hard-code them.

ResourceTool to get IDField in response
Monitor IDdatadog_monitors_listarray[].id
Dashboard IDdatadog_dashboards_listdashboards[].id
Downtime IDdatadog_downtime_create responsedata.id (UUID — not included[].id)
Notebook IDdatadog_notebooks_listdata[].id
Incident IDdatadog_incidents_listdata[].id
SLO IDdatadog_slos_listdata[].id
Role IDdatadog_roles_listdata[].id
User IDdatadog_users_listdata[].id
RUM App IDdatadog_rum_applications_listdata[].id
Event IDdatadog_event_create responseevent.id_str (use id_str, not id — see note below)
Metric namedatadog_metrics_listmetrics[] (requires from Unix timestamp)
Log pipeline IDdatadog_log_pipelines_listarray[].id
Why event IDs must come from id_str

Datadog event IDs are 64-bit integers (e.g. 8610103547030771722) that exceed the float64 precision limit (~9 × 10¹⁵). When the numeric id field is parsed as a JSON number, it loses precision and the path resolves to a wrong ID, causing a 400 “No event matches” error. Always read event.id_str from the response and pass it as a string to datadog_event_get.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • datadog_api_key_validateValidate the current Datadog API key.Read-only

    Validate API Key

    Validate the current Datadog API key.

    Inputs

    This tool takes no inputs.

  • datadog_containers_listList all containers running on your infrastructure.Read-only

    List Containers

    List all containers running on your infrastructure.

    Inputs

    filter_tagsstring
    Filter containers by tag.
    page_cursorstring
    Cursor for pagination to get the next page of results.
    page_sizeinteger
    Maximum number of containers to return per page.
  • datadog_current_user_getGet the current authenticated Datadog user.Read-only

    Get Current User

    Get the current authenticated Datadog user.

    Inputs

    This tool takes no inputs.

  • datadog_dashboard_getGet a specific Datadog dashboard by ID.Read-only

    Get Dashboard

    Get a specific Datadog dashboard by ID.

    Inputs

    dashboard_idstringrequired
    ID of the dashboard to retrieve.
  • datadog_dashboards_listList all Datadog dashboards.Read-only

    List Dashboards

    List all Datadog dashboards.

    Inputs

    countinteger
    Maximum number of dashboards to return.
    filter_deletedstring
    Filter deleted dashboards (true/false).
    filter_sharedstring
    Filter shared dashboards (true/false).
    startinteger
    Start index for pagination.
  • datadog_downtime_getGet a specific Datadog downtime by ID.Read-only

    Get Downtime

    Get a specific Datadog downtime by ID.

    Inputs

    downtime_idstringrequired
    ID of the downtime to retrieve.
  • datadog_downtimes_listList all Datadog downtimes.Read-only

    List Downtimes

    List all Datadog downtimes.

    Inputs

    filter_monitor_idinteger
    Filter downtimes by monitor ID.
    page_limitinteger
    Number of items to return per page.
    page_offsetinteger
    Offset for pagination.
  • datadog_event_getGet a specific Datadog event by ID.Read-only

    Get Event

    Get a specific Datadog event by ID.

    Inputs

    event_idstringrequired
    ID of the event to retrieve. Use the id_str value from event_create or events_list_v2 to avoid float precision loss.

Workflows

Proxy API call
const result = await actions.request({
connectionName: 'datadog',
identifier: 'user_123',
path: '/api/v1/monitor',
method: 'GET',
});
console.log(result);
Create a monitor
const monitor = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_monitor_create',
toolInput: {
name: 'High CPU Usage',
type: 'metric alert',
query: 'avg(last_5m):avg:system.cpu.user{*} > 90',
message: 'CPU usage is high on {{host.name}}. @slack-alerts',
},
});
console.log('Monitor created:', monitor.id);
Search logs
const logs = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_logs_search',
toolInput: {
query: 'service:web status:error',
from: '2024-01-01T00:00:00Z',
to: '2024-01-02T00:00:00Z',
limit: 50,
},
});
console.log('Log count:', logs.data?.length);
Query metrics
const metrics = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_metrics_query',
toolInput: {
query: 'avg:system.cpu.user{*}',
from: 1704067200, // Unix timestamp
to: 1704153600,
},
});
console.log('Series:', metrics.series);
Create an incident
const incident = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_incident_create',
toolInput: {
title: 'Database connection failures',
customer_impacted: true,
severity: 'SEV-2',
},
});
console.log('Incident ID:', incident.data?.id);
Create a scheduled downtime

The start and end fields use ISO 8601 format, not Unix timestamps.

const downtime = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_downtime_create',
toolInput: {
scope: 'env:production',
start: '2026-06-01T02:00:00Z',
end: '2026-06-01T04:00:00Z',
message: 'Scheduled maintenance window',
},
});
// Use data.id (UUID), not included[].id (user UUID)
const downtimeId = downtime.data?.id;
console.log('Downtime ID:', downtimeId);
Create a metric SLO

The query field must be a JSON string containing numerator and denominator metric queries. Pass thresholds as a JSON string too.

const slo = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_slo_create',
toolInput: {
name: 'API Success Rate',
type: 'metric',
query: JSON.stringify({
numerator: 'sum:requests.success{*}.as_count()',
denominator: 'sum:requests.total{*}.as_count()',
}),
thresholds: JSON.stringify([{ target: 99.5, timeframe: '30d' }]),
},
});
const sloId = slo.data?.[0]?.id;
Retrieve an event

Datadog event IDs are 64-bit integers that exceed the float64 precision limit. Always use the id_str field from event_create or events_list_v2 — not the numeric id field — to avoid silent precision loss.

// Create an event and capture its string ID
const created = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_event_create',
toolInput: {
title: 'Deployment completed',
text: 'v2.3.1 deployed to production',
date_happened: Math.floor(Date.now() / 1000),
},
});
const eventId = created.event?.id_str; // use id_str, not id
// Retrieve it
const event = await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_event_get',
toolInput: { event_id: eventId },
});
console.log(event.event?.title);
Submit custom metrics

datadog_metrics_submit takes separate array parameters for timestamps and values — not a serialized series object.

await actions.executeTool({
connector: 'datadog',
identifier: 'user_123',
toolName: 'datadog_metrics_submit',
toolInput: {
metric_name: 'app.request.duration',
metric_type: 3, // 3 = gauge
points_timestamps: JSON.stringify([Math.floor(Date.now() / 1000)]),
points_values: JSON.stringify([142.5]),
tags: JSON.stringify(['env:production', 'service:api']),
},
});