mrkeyoor.com_
Sat 08 Aug 21:00 UTC
PyPIUtilsupdated 08 Aug 2026

datadog-api-client

datadog-api-client is Datadog's generated Python SDK for its public v1 and v2 HTTP APIs. It supplies a Configuration object, synchronous, threaded, and optional asyncio transports, per-resource API classes, and hundreds of typed request and response models for monitors, dashboards, logs, metrics, incidents, users, integrations, and newer products. It manages Datadog resources and submits data through public endpoints; it is not the Datadog Agent, ddtrace, or an application instrumentation library.

Verdict

The right default for broad imperative Datadog automation in Python, especially when generated request models prevent payload mistakes. For one endpoint or declarative infrastructure, raw HTTP or an IaC provider can be much easier to maintain.

API stability3/5Configuration, ApiClient context managers, versioned API namespaces, generated model constructors, and endpoint methods follow a consistent pattern. The actual surface is regenerated from Datadog's evolving v1 and v2 schemas, and unstable operations require explicit opt-in because they may break. Version pinning and generated-example review matter more here than with a small hand-designed client.
Docs4/5The README documents authentication, sites, compression, debugging, rate-limit retry, custom urllib3 policies, proxies, threaded calls, the async extra, and pagination. The hosted reference exposes every API class and model, and the source distribution contains endpoint-specific examples. Finding the right example among a huge generated surface is the remaining friction, and model names can overwhelm first-time users.
Maintenance5/5Datadog publishes and supports the package, PyPI released 2.58.0 in August 2026, and the repository was pushed the same day. Continuous regeneration keeps it close to current public APIs and products. That high activity is valuable for coverage, though it also means frequent versions and generated diffs that consumers should test before automated dependency updates.
Ecosystem4/5The client spans a very large portion of Datadog's public control plane and intake APIs, offers synchronous, threaded, and asyncio transports, and ships thousands of generated examples. It works well alongside the Agent, ddtrace, Terraform, Pulumi, and CI systems, but it is one piece of a provider-specific ecosystem and does not replace instrumentation or declarative resource ownership.

Use it if

  • You automate Datadog monitors, dashboards, incidents, users, integrations, or other public API resources from Python
  • You want generated models and method signatures instead of hand-building Datadog JSON and authentication headers
  • You need paging helpers, configurable retry, proxies, regional Datadog sites, or an optional asyncio transport
  • You want examples generated against the same OpenAPI description as the client
Skip it if

Setup reality

pip install datadog-api-client supports the synchronous urllib3 transport on Python 3.8 or newer. By default Configuration reads DD_API_KEY and DD_APP_KEY; these are different credentials, and management calls commonly need both. Use restricted application-key scopes where Datadog supports them and keep both values in a secret manager. The Agent's local configuration does not automatically make these environment variables available to your script. Site selection is mandatory outside the default datadoghq.com organization: set configuration.server_variables['site'] to the exact Datadog site, such as datadoghq.eu, before constructing the client. The package mirrors two API generations, so imports include datadog_api_client.v1 or .v2 and model names can be long. Use the generated example for the exact endpoint version rather than guessing. The normal ApiClient is a context manager and should be closed; create it once for a batch instead of for every item. Retry is off by default. Setting enable_retry handles rate-limit responses with a documented default retry count, while a custom urllib3 Retry can include server errors and takes precedence over enable_retry, retry_backoff_factor, and max_retries. Retrying create or update calls needs an idempotency decision, not just a transport toggle. Debug mode logs requests and can expose headers or payloads, so do not enable it casually in production. Proxy configuration is a URL string on Configuration. Gzip responses are enabled unless compress is false. Async support is not in the base install: use pip install 'datadog-api-client[async]', which adds aiosonic, then AsyncApiClient in an async with block. ThreadedApiClient is a separate synchronous option whose API methods return AsyncResult and require .get(). Endpoint list methods do not all paginate identically, but generated *_with_pagination methods return iterables that make additional requests as consumed. Unstable operations refuse to run until configuration.unstable_operations[method_name] is true, which is a useful warning that the contract can break. Models validate fields locally, but API errors still raise ApiException with status, parsed body, and headers. Treat those bodies as potentially sensitive, especially when logging failed monitor queries or user-management calls.

Patterns

Validate configured credentialsvalidate-api-key

from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v1.api.authentication_api import AuthenticationApi

configuration = Configuration()
with ApiClient(configuration) as client:
    result = AuthenticationApi(client).validate()
    print(result.valid)

Configuration reads DD_API_KEY and DD_APP_KEY by default; endpoint authorization still depends on key scopes.

Target a regional Datadog siteselect-datadog-site

from datadog_api_client import ApiClient, Configuration

configuration = Configuration()
configuration.server_variables['site'] = 'datadoghq.eu'

with ApiClient(configuration) as client:
    call_api(client)

Use the site assigned to your organization; valid credentials sent to the default US host will not access an EU organization.

Iterate through monitors with paginationlist-monitors

from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v1.api.monitors_api import MonitorsApi

with ApiClient(Configuration()) as client:
    monitors = MonitorsApi(client).list_monitors_with_pagination(
        monitor_tags='service:checkout',
        page_size=100,
    )
    for monitor in monitors:
        print(monitor.id, monitor.name)

The returned iterable fetches more pages as you consume it, so stopping early can avoid unnecessary requests.

Create a log alert monitorcreate-monitor

from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v1.api.monitors_api import MonitorsApi
from datadog_api_client.v1.model.monitor import Monitor
from datadog_api_client.v1.model.monitor_type import MonitorType

body = Monitor(
    name='Checkout errors',
    type=MonitorType.LOG_ALERT,
    query='logs("service:checkout status:error").index("main").rollup("count").last("5m") > 10',
    message='Checkout errors are elevated',
    tags=['service:checkout', 'managed-by:python'],
)
with ApiClient(Configuration()) as client:
    created = MonitorsApi(client).create_monitor(body=body)

Generated models validate structure, but Datadog still validates the monitor query and account permissions server-side.

Retry rate-limited requestsenable-rate-limit-retry

from datadog_api_client import ApiClient, Configuration

configuration = Configuration()
configuration.enable_retry = True
configuration.max_retries = 5

with ApiClient(configuration) as client:
    call_api(client)

The built-in switch is documented for 429 responses; decide separately whether mutating operations are safe to retry.

Provide an explicit urllib3 retry policyset-custom-retry

import urllib3
from datadog_api_client import ApiClient, Configuration

retry = urllib3.util.Retry(
    total=5,
    backoff_factor=2,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=['GET'],
)
configuration = Configuration(retry_policy=retry)
with ApiClient(configuration) as client:
    call_read_only_api(client)

A custom retry policy overrides enable_retry, retry_backoff_factor, and max_retries; limiting methods avoids repeating writes blindly.

Call an API with asynciouse-async-client

import asyncio
from datadog_api_client import AsyncApiClient, Configuration
from datadog_api_client.v1.api.dashboards_api import DashboardsApi

async def main():
    async with AsyncApiClient(Configuration()) as client:
        dashboards = await DashboardsApi(client).list_dashboards()
        print(dashboards)

asyncio.run(main())

Install datadog-api-client[async] first; the base package does not include the aiosonic transport extra.

Run calls through the threaded clientuse-threaded-client

from datadog_api_client import Configuration, ThreadedApiClient
from datadog_api_client.v1.api.dashboards_api import DashboardsApi

with ThreadedApiClient(Configuration()) as client:
    pending = DashboardsApi(client).list_dashboards()
    dashboards = pending.get()

Methods return AsyncResult under ThreadedApiClient; forgetting .get() leaves you with the handle rather than the response.

Explicitly enable an unstable operationcall-unstable-endpoint

from datadog_api_client import ApiClient, Configuration
from datadog_api_client.v2.api.incidents_api import IncidentsApi

configuration = Configuration()
configuration.unstable_operations['list_incidents'] = True
with ApiClient(configuration) as client:
    for incident in IncidentsApi(client).list_incidents_with_pagination():
        print(incident.id)

The operation name, not the API class name, is the opt-in key; unstable contracts can change between releases.

Inspect structured API failureshandle-api-errors

from datadog_api_client.exceptions import ApiException

try:
    call_api(client)
except ApiException as error:
    logger.error('Datadog request failed', extra={
        'status': error.status,
        'body': error.body,
    })
    raise

ApiException can contain response headers and a parsed body; redact credentials and sensitive query data before logging.

Alternatives

PackageRegistryPick it when
datadogPyPIYou maintain code on Datadog's older, smaller datadogpy client and do not need the generated modern surface
requestsPyPIYou call only one or two stable endpoints and prefer explicit HTTP over hundreds of generated models
pulumi-datadogPyPIYou want declarative Datadog infrastructure under Pulumi state instead of imperative API scripts