跳转到主要内容

GraphQL Analytics API

import { Details, MetaInfo } from "~/components";

Privacy Proxy exposes metrics through Cloudflare's GraphQL Analytics API. All metrics are queryable through a single endpoint:

POST https://api.cloudflare.com/client/v4/graphql

Before you begin, you will need:

  • API token — Create a token with Account Analytics read permissions. For more information, refer to our Analytics API token documentation: Configure an Analytics API token.
  • Account ID — Your Cloudflare account ID, passed as accountTag in queries. For more information, refer to Find account and zone IDs.

Making a request

The following example shows how to query your Privacy Proxy metrics daily request volume using curl. Replace the placeholder values with your own.

curl https://api.cloudflare.com/client/v4/graphql \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "query": "query DailyRequestVolume($accountTag: String!, $startDate: Date!, $endDate: Date!) { viewer { accounts(filter: { accountTag: $accountTag }) { privacyProxyRequestMetricsAdaptiveGroups(filter: { date_geq: $startDate, date_leq: $endDate }, limit: 10000, orderBy: [date_ASC]) { count dimensions { date } } } } }",
    "variables": {
      "accountTag": "<YOUR_ACCOUNT_TAG>",
      "startDate": "2026-04-04",
      "endDate": "2026-04-06"
    }
  }'

Available nodes

Four GraphQL nodes are available. All four return aggregate data only — no raw per-connection records are exposed.

  1. privacyProxyRequestMetricsAdaptiveGroups — Query aggregate request volume and error rates, filterable by time, location, endpoint, status code, and proxy status dimensions.
  2. privacyProxyIngressConnMetricsAdaptiveGroups — Query client-to-proxy connection counts, bytes transferred, and latency percentiles, filterable by time, location, endpoint, and transport dimensions.
  3. privacyProxyEgressConnMetricsAdaptiveGroups — Query proxy-to-origin connection counts, bytes transferred, and latency percentiles, filterable by time, location, endpoint, and transport dimensions.
  4. privacyProxyAuthMetricsAdaptiveGroups — Query authentication attempt counts, filterable by time, location, endpoint, auth method, and auth result dimensions.

:::note[Adaptive sampling] Requests are sampled. :::


Schema

Field Type Description Node
bytesSentToClient uint64 Total bytes sent from the proxy back to the client. Ingress connection
bytesRecvdFromClient uint64 Total bytes received by the proxy from the client. Ingress connection
bytesSentToOrigin uint64 Total bytes sent from the proxy to the upstream origin. Egress connection
bytesRecvdFromOrigin uint64 Total bytes received by the proxy from the upstream origin. Egress connection
packetsSentToClient uint64 Total packets sent from the proxy back to the client. Ingress connection
packetsRecvdFromClient uint64 Total packets received by the proxy from the client. Ingress connection
packetsSentToOrigin uint64 Total packets sent from the proxy to the upstream origin. Egress connection
packetsRecvdFromOrigin uint64 Total packets received by the proxy from the upstream origin. Egress connection

All four nodes expose a count field that returns the total number of sampled events (requests, connections, or auth attempts) matching the query filter.

Field Type Description Node
durationMsP50 float64 Median lifetime of a connection, in milliseconds. Ingress and egress connection
durationMsP95 float64 95th percentile connection lifetime, in milliseconds. Ingress and egress connection
durationMsP99 float64 99th percentile connection lifetime, in milliseconds. Ingress and egress connection
handshakeDurationUsP50 float64 Median TCP+TLS/QUIC handshake time, in microseconds. Ingress and egress connection
handshakeDurationUsP95 float64 95th percentile handshake time, in microseconds. Ingress and egress connection
handshakeDurationUsP99 float64 99th percentile handshake time, in microseconds. Ingress and egress connection
connectRequestHandlingDurationUsP50 float64 Median time to handle a CONNECT request, in microseconds. Not yet available. Request
connectRequestHandlingDurationUsP95 float64 95th percentile time to handle a CONNECT request, in microseconds. Not yet available. Request
connectRequestHandlingDurationUsP99 float64 99th percentile time to handle a CONNECT request, in microseconds. Not yet available. Request
connectTunnelSetupDurationUsP50 float64 Median time to establish a tunnel after receiving a CONNECT request, in microseconds. Not yet available. Request
connectTunnelSetupDurationUsP95 float64 95th percentile tunnel setup time, in microseconds. Not yet available. Request
connectTunnelSetupDurationUsP99 float64 99th percentile tunnel setup time, in microseconds. Not yet available. Request
Field Type Description
date Date Calendar date (day granularity).
datetimeMinute Time Timestamp truncated to the minute.
datetimeFiveMinutes Time Timestamp truncated to five-minute intervals.
datetimeFifteenMinutes Time Timestamp truncated to fifteen-minute intervals.
datetimeHour Time Timestamp truncated to the hour.
coloCode string Cloudflare data center that handled the request.
endpoint string The appId that generated traffic.

All timestamp dimensions refer to the end of each connection or request, not the start.

Field Type Description
statusCode uint16 HTTP status code returned by the proxy to the client.
proxyStatus string Proxy-level error classification. null when no proxy-level error occurred. Refer to proxy status reference for possible values.
tunnelType string Tunnel protocol used (connect-tcp, connect-udp, connect-ip). Not yet available.
Field Type Description
transport string Transport protocol on the client-to-proxy connection (tcp, quic).
tlsVersion string TLS version negotiated on the client-to-proxy connection. Not yet available.
Field Type Description
transport string Transport protocol on the proxy-to-origin connection (tcp, quic).
Field Type Description
authMethod string Authentication method used (for example, Token, Psk).
authResult string Authentication outcome (success, failure).

All four nodes share the same argument signature.

  • filter — Filters your data. accountTag is always required inside the filter.
  • limit — Maximum number of records to return.
  • orderBy — Sort order for results.

Sample queries

Get a high-level view of daily request volume over a date range.

query DailyRequestVolume(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyRequestMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [date_ASC]
      ) {
        count
        dimensions {
          date
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Identify which HTTP status codes and proxy-level errors are occurring to pinpoint the source of failures.

query ErrorBreakdown(
  $accountTag: String!
  $start: Time!
  $end: Time!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyRequestMetricsAdaptiveGroups(
        filter: {
          datetimeFifteenMinutes_geq: $start
          datetimeFifteenMinutes_leq: $end
          statusCode_geq: 400
        }
        limit: 10000
        orderBy: [datetimeFifteenMinutes_ASC]
      ) {
        count
        dimensions {
          datetimeFifteenMinutes
          statusCode
          proxyStatus
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04T00:00:00Z",
  "end": "2026-04-06T23:59:59Z"
}

Rank the most frequent proxy error types to prioritize investigation.

query TopProxyErrors(
  $accountTag: String!
  $start: Date!
  $end: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyRequestMetricsAdaptiveGroups(
        filter: {
          date_geq: $start
          date_leq: $end
          proxyStatus_neq: ""
        }
        limit: 10000
        orderBy: [count_DESC]
      ) {
        count
        dimensions {
          proxyStatus
          statusCode
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04",
  "end": "2026-04-06"
}

Monitor the mix of connect-tcp, connect-udp, and connect-ip over time to understand how clients are connecting.

query TunnelTypeDistribution(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyRequestMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [date_ASC]
      ) {
        count
        dimensions {
          date
          tunnelType
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Get a high-level view of daily ingress connection count and bytes transferred.

query IngressTrafficOverview(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyIngressConnMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [date_ASC]
      ) {
        count
        sum {
          bytesSentToClient
          bytesRecvdFromClient
        }
        dimensions {
          date
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Compare client-to-proxy connection duration across data centers to identify regions with long-lived or stalled connections.

query IngressDurationByColo(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyIngressConnMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [quantiles_durationMsP50_DESC]
      ) {
        quantiles {
          durationMsP50
          durationMsP95
          durationMsP99
        }
        dimensions {
          coloCode
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Understanding which transport protocols (QUIC versus TCP) and TLS versions your clients use helps you plan deprecations, detect misconfigured clients, and verify that traffic meets your security requirements.

query IngressProtocolDistribution(
  $accountTag: String!
  $start: Time!
  $end: Time!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyIngressConnMetricsAdaptiveGroups(
        filter: {
          datetimeFifteenMinutes_geq: $start
          datetimeFifteenMinutes_leq: $end
        }
        limit: 10000
        orderBy: [datetimeFifteenMinutes_ASC]
      ) {
        count
        dimensions {
          datetimeFifteenMinutes
          transport
          tlsVersion
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04T00:00:00Z",
  "end": "2026-04-06T23:59:59Z"
}

Get a high-level view of daily bytes flowing between the proxy and the upstream origin.

query EgressBytesOverview(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyEgressConnMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [date_ASC]
      ) {
        count
        sum {
          bytesSentToOrigin
          bytesRecvdFromOrigin
        }
        dimensions {
          date
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Compare proxy-to-origin handshake times across data centers to identify regions with degraded origin reachability.

query EgressLatencyByColo(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyEgressConnMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [quantiles_handshakeDurationUsP50_DESC]
      ) {
        quantiles {
          handshakeDurationUsP50
          handshakeDurationUsP95
          handshakeDurationUsP99
        }
        dimensions {
          coloCode
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Track proxy-to-origin handshake latency at fine granularity over a specific time window.

query EgressPerformanceTrend(
  $accountTag: String!
  $start: Time!
  $end: Time!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyEgressConnMetricsAdaptiveGroups(
        filter: {
          datetimeFiveMinutes_geq: $start
          datetimeFiveMinutes_leq: $end
        }
        limit: 10000
        orderBy: [datetimeFiveMinutes_ASC]
      ) {
        quantiles {
          handshakeDurationUsP50
          handshakeDurationUsP95
          handshakeDurationUsP99
        }
        count
        dimensions {
          datetimeFiveMinutes
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04T08:00:00Z",
  "end": "2026-04-06T14:00:00Z"
}

Track daily authentication volume per method to understand adoption and spot anomalies.

query AuthVolumeByMethod(
  $accountTag: String!
  $startDate: Date!
  $endDate: Date!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyAuthMetricsAdaptiveGroups(
        filter: {
          date_geq: $startDate
          date_leq: $endDate
        }
        limit: 10000
        orderBy: [date_ASC]
      ) {
        count
        dimensions {
          date
          authMethod
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "startDate": "2026-04-04",
  "endDate": "2026-04-06"
}

Detect surges in authentication failures and identify which auth method is failing.

query AuthFailureSpike(
  $accountTag: String!
  $start: Time!
  $end: Time!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyAuthMetricsAdaptiveGroups(
        filter: {
          datetimeMinute_geq: $start
          datetimeMinute_leq: $end
          authResult: "failure"
        }
        limit: 10000
        orderBy: [datetimeFiveMinutes_ASC]
      ) {
        count
        dimensions {
          datetimeFiveMinutes
          authMethod
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04T10:00:00Z",
  "end": "2026-04-06T14:00:00Z"
}

Compare hourly success versus failure counts to compute auth success rate and spot degradation trends.

query AuthSuccessRate(
  $accountTag: String!
  $start: Time!
  $end: Time!
) {
  viewer {
    accounts(filter: { accountTag: $accountTag }) {
      privacyProxyAuthMetricsAdaptiveGroups(
        filter: {
          datetimeHour_geq: $start
          datetimeHour_leq: $end
        }
        limit: 10000
        orderBy: [datetimeHour_ASC]
      ) {
        count
        dimensions {
          datetimeHour
          authResult
        }
      }
    }
  }
}
{
  "accountTag": "<YOUR_ACCOUNT_TAG>",
  "start": "2026-04-04T00:00:00Z",
  "end": "2026-04-06T23:59:59Z"
}