---
title: "Gets traffic analytics"
method: GET
path: "/1.0/account/traffic-analytics"
tags: ["Traffic Analytics"]
---

# Gets traffic analytics

`GET /1.0/account/traffic-analytics`

## Request

- Base URL: `https://customer-api.datadome.co`
- URL: `https://customer-api.datadome.co/1.0/account/traffic-analytics`
- Auth: API key in header `x-api-key`

Returns the traffic metrics of your account over a time window: requests by DataDome status, by origin and by threat, the responses DataDome returned, slider and device check outcomes, and contact form submissions. Metrics can be bucketed by time and split by root domain, domain, endpoint or AI agent.

**Access.** The endpoint is available to accounts on an Enterprise Bot Protect plan that have the Trend Reports feature. Any other account gets `403` with the error `TREND_REPORTS_NOT_ENABLED`, whatever the API key. The API key identifies one account, and every metric returned belongs to that account.

**Authentication.** Send the API key in the `x-api-key` header.

**Rate limit.** 5 requests per minute per API key. Above it the endpoint returns `429` with a `Retry-After` header. A request spends the budget once access is granted and before its parameters are checked: a `400` uses one request of the budget, a `403` does not.

**Time window.** `from` is included and `to` is excluded. Both are optional: without `to` the window ends now, and without `from` it starts 24 hours before `to`. `from` must be within the last 24 months and not in the future. A `to` in the future is treated as now. Send dates as ISO 8601 with seconds and an offset or `Z`, for example `2026-09-08T15:00:00Z`. Fractional seconds are rejected. Every timestamp in the response has the same format, rendered in the requested `timezone`.

**Realtime horizon.** The horizon is the end of the latest hour covered by your trend reports, usually 48 to 72 hours before the request (now minus 48 hours, floored to the hour, when no recent report exists). Read it from `meta.realtimeHorizon`; do not compute it. Each window boundary is handled on its own. A boundary older than the horizon is snapped outward to the hour (`from` is floored, `to` is ceiled). A boundary at or after the horizon is kept to the second. The window actually served is returned in `meta.from` and `meta.to`. Label reports with those values, not with the requested ones.

**Data sources and stability.** Before the horizon, metrics come from hourly trend reports. From the horizon on, they come from raw traffic, to the second. Metrics after `meta.realtimeHorizon` are not final: slider and device check outcomes are added after the request is served, so the same query replayed later can return higher counts for the same bucket. Only data before the realtime horizon is stable. In the raw traffic part, requests absorbed by the Edge Circuit Breaker during a DDoS event are counted in `requestsCount`, `requestsByOrigin.threats`, `requestsByThreat.ddos`, `requestsByDataDomeStatus.protectionEnabled` and the `block` responses. They carry no domain, endpoint or AI agent, so they are left out of any query that filters or splits by root domain, domain or endpoint, and out of agentic scope.

**Vocabulary: slider and block.** `slider` is the CAPTCHA challenge DataDome serves (wire values `block` and `invalidate_captcha`). `block` is the hard block (wire value `hard_block`). `allow` covers `authorize` and `tagged_authorize`, and `deviceCheck` is the device check interstitial. `sliderOutcomes.count` comes from the slider outcome data, not from the responses, so it can differ from `responsesBreakdown.slider`.

**Buckets and pagination.** `interval` sets the time bucket (`hour`, `day` or `month`). Without it, the whole window is one bucket. `splitBy` adds one dimension per value, and each dimension multiplies the number of buckets. Day and month buckets follow the calendar of `timezone`. The first and last bucket are clamped to the window, so they can be shorter than `interval`. Buckets with no traffic are left out, so a window without traffic returns `data: []`. Buckets are ordered by time, then by the dimensions in the order given in `splitBy`. Pagination applies only with `interval` or `splitBy`. Otherwise the response holds at most one bucket and `meta.hasMore` is `false`. When `meta.hasMore` is `true`, send `meta.nextCursor` back as `cursor` with every other parameter unchanged (`limit` may change). A cursor expires after 1 hour. An expired cursor, or one sent with other parameters, is rejected with `400` `INVALID_CURSOR`. The last page has `hasMore: false` and no `nextCursor`.

**Agentic traffic.** Agentic scope is on when `agenticOnly=true`, when `aiAgents` is set, or when `splitBy` contains `aiAgent`. In agentic scope every metric counts AI agent traffic only, `meta.query.agenticScope` is `true`, and every bucket carries `requestsByIntent`. Its values never exceed `requestsCount` and can sum to less when a request's detected intent is not one of its keys. With `splitBy=aiAgent`, each bucket carries `aiAgentUuid`. A `null` value groups the traffic of agents that are not AI agents of your account.

**Warnings.** An `endpoints` or `aiAgents` value that is a valid UUID but matches nothing on your account does not fail the request. It is listed in `meta.warnings`, with the code `UNKNOWN_ENDPOINT_UUID` or `UNKNOWN_AI_AGENT_UUID`, and it matches no traffic. `meta.warnings` is absent when there is nothing to report. `rootDomains` and `domains` are not checked: a value that matches nothing returns no traffic and no warning.

## Query parameters

- `from` string, date-time
- `to` string, date-time
- `interval` 'hour' | 'day' | 'month'
- `timezone` string
- `splitBy` string[]
- `rootDomains` string[]
- `domains` string[]
- `endpoints` string[]
- `aiAgents` string[]
- `agenticOnly` boolean
- `limit` integer
- `cursor` string

## Response `200`

The metrics, one entry of `data` per bucket, and `meta`, which describes the window served, the query as understood and the pagination state.

- TrafficAnalytics: A page of traffic analytics: the buckets and the metadata that describes them.
  - `meta` TrafficAnalyticsMeta, required: The window actually served, the query as understood and the pagination state.
    - `from` string, date-time, required: Start of the served window, included, after snapping. Use this value, not the requested one, to label reports.
    - `to` string, date-time, required: End of the served window, excluded, after snapping. Use this value, not the requested one, to label reports.
    - `realtimeHorizon` string, date-time, required: End of the latest hour covered by the account's trend reports, usually 48 to 72 hours before the request (now minus 48 hours, floored to the hour, when no recent report exists). A window boundary older than it is snapped to the hour; a boundary at or after it is kept to the second. Read it here rather than computing it.
    - `timezone` string, required: Canonical IANA time zone name, for example `Europe/Paris`; aliases such as `US/Eastern` are rejected. Applied to bucket boundaries and to every timestamp of the response.
    - `query` TrafficAnalyticsQueryEcho, required: The query as the server understood it, after defaults were applied.
      - `interval` 'hour' | 'day' | 'month': Time bucket size in effect. Absent, not null, when the request had no `interval` and the window is one bucket.
      - `splitBy` string[], required: Dimensions the metrics are split by, in the requested order. Empty when there is no split.
      - `agenticScope` boolean, required: True when the metrics count agentic traffic only, which is the case when `agenticOnly=true`, `aiAgents` or `splitBy=aiAgent` was sent. While true, every bucket carries `requestsByIntent`.
    - `hasMore` boolean, required: Whether more buckets follow this page.
    - `nextCursor` string: Cursor of the next page, to send back as `cursor`. Present only when `hasMore` is `true`; absent, not null, on the last page. Expires after 1 hour.
    - `warnings` TrafficAnalyticsWarning[]: Filter values that match nothing on the account. Absent, not empty, when there is nothing to report. A warning never changes the HTTP status.
      - `code` 'UNKNOWN_ENDPOINT_UUID' | 'UNKNOWN_AI_AGENT_UUID', required: Machine-readable warning code.
      - `message` string, required: Human-readable explanation of the warning.
      - `values` string[], required: The values that match nothing.
  - `data` TrafficMetrics[], required: Buckets matching the query. Buckets with no traffic are left out, so it is empty when no traffic matches, which is a successful response.
    - `from` string, date-time, required: Start of the bucket, included.
    - `to` string, date-time, required: End of the bucket, excluded. The first and last bucket of a window can be shorter than `interval` when the window does not start or end on a bucket boundary.
    - `rootDomain` string: Present when `splitBy` contains `rootDomain`.
    - `domain` string: Present when `splitBy` contains `domain`.
    - `endpointUuid` string, uuid: Present when `splitBy` contains `endpoint`.
    - `aiAgentUuid` string, uuid, nullable: Present when `splitBy` contains `aiAgent`. `null` groups the traffic of agents that are not AI agents of the account.
    - `requestsCount` integer, required: Total requests in the bucket. In the raw traffic part of a window, this includes requests absorbed by the Edge Circuit Breaker, unless the query filters or splits by root domain, domain or endpoint, or is in agentic scope.
    - `requestsByDataDomeStatus` RequestsByDataDomeStatus, required: Requests by DataDome protection status.
      - `protectionEnabled` object, required: Requests received while protection was enabled.
        - `count` integer, required: Requests received while protection was enabled.
        - `threats` integer, required: Of those, the requests detected as threats.
      - `protectionDisabled` object, required: Requests received while protection was disabled.
        - `count` integer, required: Requests received while protection was disabled.
        - `threats` integer, required: Of those, the requests detected as threats and not acted upon.
    - `requestsByOrigin` RequestsByOrigin, required: Requests by origin. The origins are mutually exclusive, but their counts do not have to sum to `requestsCount`. Never derive one origin from `requestsCount` minus the others.
      - `humans` OriginTraffic, required: The requests of one origin and the responses DataDome returned to them.
        - `count` integer, required: Requests of this origin.
        - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
          - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
          - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
          - `block` integer: Request hard blocked. Wire value `hard_block`.
          - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
          - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
          - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
      - `threats` OriginTraffic, required: The requests of one origin and the responses DataDome returned to them.
        - `count` integer, required: Requests of this origin.
        - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
          - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
          - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
          - `block` integer: Request hard blocked. Wire value `hard_block`.
          - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
          - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
          - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
      - `verifiedBots` OriginTraffic, required: The requests of one origin and the responses DataDome returned to them.
        - `count` integer, required: Requests of this origin.
        - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
          - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
          - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
          - `block` integer: Request hard blocked. Wire value `hard_block`.
          - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
          - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
          - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
      - `aiAgents` OriginTraffic, required: The requests of one origin and the responses DataDome returned to them.
        - `count` integer, required: Requests of this origin.
        - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
          - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
          - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
          - `block` integer: Request hard blocked. Wire value `hard_block`.
          - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
          - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
          - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
      - `custom` OriginTraffic, required: The requests of one origin and the responses DataDome returned to them.
        - `count` integer, required: Requests of this origin.
        - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
          - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
          - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
          - `block` integer: Request hard blocked. Wire value `hard_block`.
          - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
          - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
          - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
    - `requestsByThreat` RequestsByThreat, required: Threat requests by threat type.
      - `scraping` integer, required: Scraping requests.
      - `scalping` integer, required: Scalping requests.
      - `spamming` integer, required: Spamming requests.
      - `credentialStuffing` integer, required: Credential stuffing requests.
      - `fakeAccountCreation` integer, required: Fake account creation requests.
      - `paymentFraud` integer, required: Payment fraud requests.
      - `apiAbuse` integer, required: API abuse requests.
      - `vulnerabilityScanning` integer, required: Vulnerability scanning requests.
      - `ddos` integer, required: DDoS requests, Edge Circuit Breaker requests included.
      - `agenticAbuse` integer, required: Agentic abuse requests.
    - `responsesBreakdown` ResponsesBreakdown, required: Requests by the response DataDome returned. `redirect` and `waitingRoom` are always present. They read 0 for periods whose trend reports do not carry them. Under `requestsByOrigin.humans`, `slider` and `block` are always absent.
      - `allow` integer, required: Request let through. Wire values `authorize` and `tagged_authorize`.
      - `slider` integer: Slider served. Wire values `block` and `invalidate_captcha`.
      - `block` integer: Request hard blocked. Wire value `hard_block`.
      - `deviceCheck` integer, required: Device check served. Wire value `interstitial`.
      - `redirect` integer, required: Request redirected. 0 when the data does not carry it.
      - `waitingRoom` integer, required: Request sent to the waiting room. 0 when the data does not carry it.
    - `sliderOutcomes` SliderOutcomes, required: What happened to the sliders served. Outcomes can be counted after the bucket was first served, so recent counts can still grow.
      - `count` integer, required: Sliders with an outcome.
      - `challengeNotLoaded` integer, required: Slider served but the page script never ran.
      - `failed` integer, required: Slider attempted and failed.
      - `ignored` integer, required: Slider displayed and never attempted.
      - `blocked` integer, required: Slider refused by a slider rule.
      - `passed` SliderPassedBreakdown, required: Sliders passed, by challenge type.
        - `count` integer, required: Sliders passed.
        - `visual` integer, required: Passed the visual challenge.
        - `audio` integer, required: Passed the audio challenge.
    - `deviceCheckOutcomes` DeviceCheckOutcomes, required: What happened to the device checks served.
      - `challengeNotLoaded` integer, required: Device check served but the page script never ran.
      - `allow` integer, required: Device check passed, request let through.
      - `block` integer, required: Device check failed, request blocked.
      - `slider` SliderOutcomes, required: What happened to the sliders served. Outcomes can be counted after the bucket was first served, so recent counts can still grow.
        - `count` integer, required: Sliders with an outcome.
        - `challengeNotLoaded` integer, required: Slider served but the page script never ran.
        - `failed` integer, required: Slider attempted and failed.
        - `ignored` integer, required: Slider displayed and never attempted.
        - `blocked` integer, required: Slider refused by a slider rule.
        - `passed` SliderPassedBreakdown, required: Sliders passed, by challenge type.
          - `count` integer, required: Sliders passed.
          - `visual` integer, required: Passed the visual challenge.
          - `audio` integer, required: Passed the audio challenge.
    - `contactFormSubmissionsCount` integer, required: Number of slider contact form submissions.
    - `requestsByIntent` AiAgentRequestsByIntent: Agentic requests by detected intent. `legitimate` covers well-behaved agentic activity; every other key is a detected abusive behaviour. The values never exceed `requestsCount` and can sum to less when a request's detected intent is not one of these keys.
      - `legitimate` integer, required: Legitimate agentic requests.
      - `scraping` integer, required: Scraping requests.
      - `scalping` integer, required: Scalping requests.
      - `spamming` integer, required: Spamming requests.
      - `credentialStuffing` integer, required: Credential stuffing requests.
      - `fakeAccountCreation` integer, required: Fake account creation requests.
      - `paymentFraud` integer, required: Payment fraud requests.
      - `apiAbuse` integer, required: API abuse requests.
      - `vulnerabilityScanning` integer, required: Vulnerability scanning requests.
      - `agenticAbuse` integer, required: Agentic abuse requests. 0 when the data does not carry it.

## Other responses

- `400`: One or more parameters are invalid. Every failing parameter is listed, each with its `field`. Codes: `INVALID_FROM`, `INVALID_FROM_FORMAT`, `INVALID_TO_FORMAT`, `INVALID_TIME_RANGE`, `INVALID_INTERVAL`, `INVALID_TIMEZONE`, `INVALID_TIMEZONE_OFFSET`, `INVALID_SPLIT_BY`, `INVALID_LIMIT`, `INVALID_CURSOR`, `INVALID_ENDPOINT_UUID`, `INVALID_AI_AGENT_UUID`. A `400` spends one request of the rate-limit budget.
- `401`: The API key is missing or not usable. `MISSING_API_KEY` when the `x-api-key` header is absent or empty. `INVALID_API_KEY` when the key is unknown, revoked or disabled.
- `403`: The account is not on an Enterprise Bot Protect plan or does not have the Trend Reports feature. A `403` does not spend the rate-limit budget.
- `429`: Too many requests. This endpoint accepts 5 requests per minute per API key. Wait for the number of seconds given in `Retry-After` before retrying.
- `500`: An unexpected error occurred. The request can be retried.

---

[API](https://skmtc.dev/datadome/apis/management-api.md) - [All operations](https://skmtc.dev/datadome/apis/management-api/llms.txt) - [OpenAPI document](https://skmtc.dev/datadome/apis/management-api/revisions/80062169b99e?raw)
