Skip to content
Cloudflare Docs

Run endpoint health checks (beta)

Magic Transit uses endpoint health checks to determine the overall health of your inter-network connections. Probes originate from Cloudflare infrastructure, outside customer network namespaces, and target IP addresses deep within your network, beyond the tunnel-terminating border router. These "long distance" probes are purely diagnostic.

When choosing which endpoint IP addresses to monitor with health checks, use these guidelines:

  • Provide one IP address for each of the prefixes Cloudflare advertises.
  • Redundant IPs routed through the same ISP (Internet Service Provider) and infrastructure are not necessary but are useful when troubleshooting.

Cloudflare pings health check IPs from within the published Cloudflare IP range, which is also available through the Cloudflare API.

When configuring an endpoint health check for an IP prefix, select an IP address within the range of that IP prefix. Refer to the table for an example of an endpoint health check configuration.

PrefixEndpoint IP address
103.21.244.0/24103.21.244.100
103.21.245.0/24103.21.245.100

Refer to Tunnel health checks for more information.

Configure endpoint health checks (beta)

You can only configure endpoint health checks through the Cloudflare API. They are not available in the dashboard. Currently, configuring health checks is a beta feature.

Refer to the API documentation to learn how to create, list, and delete endpoint health checks. The following example creates a new endpoint health check.

Terminal window
curl "https://api.cloudflare.com/client/v4/accounts/account_id/diagnostics/endpoint-healthcheck" \
--request POST \
--json '{
"check_type": "icmp",
"endpoint": "8.31.160.1",
"name": "Datacenter 1 - primary"
}'
{
"result": {
"id": "<HEALTH_CHECK_ID>",
"check_type": "icmp",
"endpoint": "8.31.160.1",
"name": "Datacenter 1 - primary"
},
"success": true,
"errors": [],
"messages": []
}

Query endpoint health checks with GraphQL

Use the GraphQL Analytics API to query endpoint health check results for your account. The magicEndpointHealthCheckAdaptiveGroups dataset returns probe results aggregated by the dimensions and time interval you specify.

Send all GraphQL queries as HTTP POST requests to https://api.cloudflare.com/client/v4/graphql.

Prerequisites

You need the following to query endpoint health check data:

Query parameters

The following parameters are some of the most common ones in the filter object:

ParameterDescription
date_geqStart date for the query in YYYY-MM-DD format (for example, 2026-01-01). When used with a date-based truncation dimension, returns results from this date onward. You can also use a full ISO 8601 timestamp (for example, 2026-01-01T00:00:00Z).
date_leq(Optional) End date for the query. Uses the same format as date_geq.
datetime_geq(Optional) Start timestamp in ISO 8601 format (for example, 2026-01-01T00:00:00Z). Use instead of date_geq for time-based truncation dimensions.
datetime_leq(Optional) End timestamp in ISO 8601 format.
limitMaximum number of result groups to return.

You can also filter on any dimension listed in the Available dimensions table. Append an operator suffix to the dimension name to create a filter — for example, endpoint_in to filter by a list of endpoints, or checkType_neq to exclude a specific check type. Using a dimension name without a suffix filters for equality. For the full list of supported operators, refer to Filtering.

Available dimensions

You can query the following dimensions in the dimensions field:

DimensionDescription
checkIdThe unique ID of the configured health check.
checkTypeThe type of health check (for example, icmp).
endpointThe IP address of the endpoint being checked.
nameThe name assigned to the health check when configured (may be empty if not set).
dateEvent timestamp truncated to the day.
datetimeFull event timestamp.
datetimeMinuteEvent timestamp truncated to the minute.
datetimeFiveMinutesEvent timestamp truncated to five-minute intervals.
datetimeFifteenMinutesEvent timestamp truncated to 15-minute intervals.
datetimeHalfOfHourEvent timestamp truncated to 30-minute intervals.
datetimeHourEvent timestamp truncated to the hour.

Available metrics

MetricDescription
countTotal number of health check events in the group.
sum.totalTotal number of health check probes sent.
sum.failuresNumber of failed health check probes.
avg.lossPercentageAverage calculated loss percentage (0-100).

API call

The following example queries endpoint health check results for a specific account, returning probe counts aggregated in five-minute intervals. Replace <ACCOUNT_ID> with your account ID and <API_TOKEN> with your API token.

Terminal window
echo '{ "query":
"query GetEndpointHealthCheckResults($accountTag: string, $datetimeStart: string) {
viewer {
accounts(filter: {accountTag: $accountTag}) {
magicEndpointHealthCheckAdaptiveGroups(
filter: {
datetime_geq: $datetimeStart
}
limit: 10
) {
count
dimensions {
checkId
checkType
endpoint
datetimeFiveMinutes
}
sum {
failures
total
}
}
}
}
}",
"variables": {
"accountTag": "<ACCOUNT_ID>",
"datetimeStart": "2026-01-21T00:00:00Z"
}
}' | tr -d '\n' | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @-

Pipe the output to jq to format the JSON response for easier reading:

Terminal window
... | curl --silent \
https://api.cloudflare.com/client/v4/graphql \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data @- | jq .

Example response

{
"data": {
"viewer": {
"accounts": [
{
"magicEndpointHealthCheckAdaptiveGroups": [
{
"count": 288,
"dimensions": {
"checkId": "90b478c7-bb51-4640-b94b-2c3050e9fa00",
"checkType": "icmp",
"datetimeFiveMinutes": "2026-01-21T12:00:00Z",
"endpoint": "103.21.244.100"
},
"sum": {
"failures": 0,
"total": 288
}
},
{
"count": 288,
"dimensions": {
"checkId": "90b478c7-bb51-4640-b94b-2c3050e9fa00",
"checkType": "icmp",
"datetimeFiveMinutes": "2026-01-21T12:05:00Z",
"endpoint": "103.21.244.100"
},
"sum": {
"failures": 2,
"total": 288
}
}
]
}
]
}
},
"errors": null
}

In this response, sum.total is the number of probes sent during the interval and sum.failures is the number that did not receive a reply. A failures value of 0 indicates the endpoint was fully reachable during that period.

Configure alerts for endpoint health checks

You can set up alerts to be notified when the state of your endpoint's health is below a threshold defined by you.

  1. Make a GET request to get a list of IDs for all of the endpoint health checks configured:
Terminal window
curl "https://api.cloudflare.com/client/v4/accounts/account_id/diagnostics/endpoint-healthcheck" \
--request GET
{
"result": [
{
"id": "<HEALTH_CHECK_ID>",
"check_type": "icmp",
"endpoint": "8.31.160.1",
"name": "Datacenter 1 - primary"
}
],
"success": true,
"errors": [],
"messages": []
}
  1. Take note of the id value for the endpoint you want to get alerts for.
  2. In the Cloudflare dashboard, go to the Notifications page.
Go to Notifications
  1. Select Add.
  2. From the drop-down menu, select Magic Transit.
  3. Select Magic Endpoint Health Check Alert.
  4. Provide a name for your new notification and optionally provide a description.
  5. In the Service Level Objective (SLO) drop-down menu, select the SLO threshold for your notification. The SLO defines the percentage of endpoint health checks that must pass. If the number of passing endpoint health checks falls below the SLO, Cloudflare generates an alert:
    • High - 99%
    • Medium - 98%
    • Low - 97%
  6. In the drop-down menu below SLOs, select the id value that matches the id you got through the API in step 1. This id should match the endpoint health check you want to get notifications for.
  7. Select your preferred notification method (such as email or webhooks).
  8. Select Save.

You will now receive notifications through your preferred method whenever the SLO for your endpoint health checks falls below your chosen threshold.