HELIOS DOCS

Cloudflare

Connect Cloudflare with an API token or OAuth app to call REST endpoints and receive supported alerts.

What your agents can do

Helios uses a pinned version of Cloudflare's OpenAPI spec to look up REST endpoints. It attaches your token or OAuth credentials to API calls. Access depends on the token's permissions or the OAuth scopes you approve.

  • Create, update, and delete DNS records, and change zone settings such as the security level
  • Purge cached files after a deploy
  • Inspect Workers, their versions and deployments, and set secrets
  • Read and write Workers KV, manage R2 buckets, and query D1 databases
  • Manage Access applications, WAF rules, and Cloudflare Tunnels

Agents can also produce and consume K2 stream records on each stream's own host, <STREAM_ID>.k2.cloudflarestorage.com. These calls need the full stream URL and an API token with the K2 Produce or K2 Consume permission. The GraphQL Analytics API is not included in endpoint lookup.

Authentication

MethodTypeDescription
Helios Cloudflare AppOAuth 2.0Helios's Cloudflare app, plus your account ID. You don't need to create an app
Cloudflare API TokenAPI KeyA Cloudflare account or user API token, plus your account ID
Your own Cloudflare OAuth appOAuth 2.0An OAuth client you create in your Cloudflare account, plus your account ID

See Integration authentication for how credentials are stored and injected.

Every method needs your account ID. In the Cloudflare dashboard, open Workers & Pages and copy Account ID from Account Details.

Helios Cloudflare App

Connect through Helios's Cloudflare app. You don't need to create an app in Cloudflare.

  1. In Helios, choose Helios Cloudflare App.
  2. Enter Account ID. Turn on Admin access to also ask for the admin scopes.
  3. Save, then approve access in Cloudflare. On the consent screen, choose the account whose ID you entered. If you leave it out, Helios doesn't save the connection and asks you to check the account ID.

Helios asks for every scope listed under Scopes Helios asks for below, and for the admin scopes when Admin access is on. Helios refreshes the access token when it expires. To change Admin access, edit it through Manage and connect again.

If Cloudflare refuses the authorization, an admin of your Cloudflare account may have turned off third-party apps. A Super Administrator can turn them on under Manage Account → Members → Settings → Public OAuth App access.

Cloudflare API Token

To create an account API token, you need the Super Administrator role or the API Token Provisioning capability. Any member can create a user token, which acts as that member. A token can only have permissions that its creator has.

  1. In the Cloudflare dashboard, go to Manage account → Account API tokens and select Create Token. A user token from My Profile → API Tokens also works.
  2. Select Create Custom Token and add permissions:
    • For full access, add every permission group under Account and Zone, each at its highest level, such as Edit. For a user token, also add the User permissions. Cloudflare lists them all in API token permissions.
    • Triggers need Notifications Edit. Alerts that Cloudflare limits to chosen zones also need Zone Read, and Pages alerts need Cloudflare Pages Read.
  3. Under Zone Resources, include all zones from the account.
  4. Select Continue to summary, then Create Token, and copy the token.
  5. In Helios, choose Cloudflare API Token. Enter Account ID, paste the token into API Token, and save.

A token with fewer permissions still works for the endpoints those permissions cover. For user tokens, the connection test verifies token validity. Account access is checked when you call account endpoints or set up triggers. If the token expires or you roll it, enter the new one through Manage. If you add permissions for more alerts, save the connection again so Helios creates them.

Cloudflare suggests account API tokens for integrations like this one. They keep working after the person who created them leaves your Cloudflare account.

Your own Cloudflare OAuth app

To create an OAuth client, you need the Super Administrator, Administrator, or OAuth Client Write role.

  1. In the Cloudflare dashboard, go to Manage Account → OAuth clients and select Create client.

  2. Enter a client name. Set the response type to code, the grant types to authorization_code and refresh_token, and the token authentication method to client_secret_basic. With the refresh_token grant, Cloudflare adds the offline_access scope that Helios needs for a refresh token.

  3. Add this redirect URL:

    https://api.heliosapp.com/integrations/cloudflare/oauth_callback
  4. Select Continue and add every scope in the table below. Helios asks for all of them, so the client needs every one. To let people decline some scopes on the consent screen, turn off Required for those scopes under Choose optional scopes.

  5. If you'll turn on Admin access, also add account-api-tokens.write, account-settings.write, and scim-provisioning.write.

  6. Select Create client and copy the Client ID and Client Secret. Cloudflare shows the secret only once.

  7. In Helios, choose Your own Cloudflare OAuth app. Enter Account ID, Client ID, and Client Secret. Turn on Admin access to also ask for the admin scopes.

  8. Save, then approve access in Cloudflare. Select the same account on the consent screen.

Admin access adds the scopes that manage the account itself: account-api-tokens.write creates and edits account API tokens, account-settings.write changes account settings and members, and scim-provisioning.write provisions members through SCIM. Cloudflare lets only a Super Administrator manage members and create account API tokens.

Cloudflare's list of OAuth scopes has no billing scopes, so OAuth connections can't read or change billing. Use an API token with the billing permissions for that.

A new client is private, so only members of your Cloudflare account can approve it. Helios refreshes the access token when it expires. If you rotate the client secret, enter the new one through Manage and connect again. To change Admin access, edit it through Manage and connect again.

Triggers

Cloudflare can start a Workflow when it sends an alert. Webhooks are available on all Cloudflare plans. When you save the connection, Helios adds a webhook destination named Helios to your account. It attempts to create an alert named Helios: ... for each supported alert type your account offers. Deleting the connection removes the alerts and the destination.

This needs the Notifications Edit permission on the token, or the notifications.write scope for an OAuth app. Without it, agents still work, but no events reach Helios.

Each supported alert type has its own event:

EventDescriptionFilters
abuse_report_alert.sentSomeone filed an abuse report against a website in the accountnone
access_custom_certificate_expiration_type.sentAn Access mTLS certificate expires in 30 or 14 dayszone
advanced_ddos_attack_l4_alert.sentCloudflare mitigated a Layer 3/4 DDoS attack above the configured packet ratenone
advanced_ddos_attack_l7_alert.sentCloudflare mitigated an HTTP DDoS attack above the configured request ratezone
advanced_http_alert_error.sentCloudflare detected a rise in edge or origin errorszone
bgp_hijack_notification.sentYour IP prefixes were advertised where they should not benone
billing_budget_alert.sentUsage charges reached a budget threshold you setnone
billing_usage_alert.sentA product's usage went above a threshold you setnone
block_notification_block_removed.sentCloudflare Trust & Safety removed a block from a websitenone
block_notification_new_block.sentCloudflare Trust & Safety placed a block on a websitenone
block_notification_review_rejected.sentCloudflare Trust & Safety rejected a request to remove a blocknone
bot_traffic_basic_alert.sentCloudflare detected a spike in bot traffic on a zonezone
brand_protection_alert.sentA saved Brand Protection query matched a new domainnone
brand_protection_digest.sentA digest of the domains that match saved Brand Protection queriesnone
casb_weekly_digest.sentA weekly digest of CASB findingsnone
clickhouse_alert_fw_anomaly.sentSecurity events spiked on a zonezone
clickhouse_alert_fw_ent_anomaly.sentSecurity events from the chosen services spiked on a zonezone
closed_port_scan_alert.sentCloudflare detected newly closed portsnone
cloudforce_one_request_notification.sentCloudflare sent a Cloudforce One request notificationnone
cni_maintenance_notification.sentMaintenance is planned that might affect a Classic CNI connectionnone
containers_security_alert.sentCloudforce One found a potential threat in Containersnone
custom_analytics.sentA Custom Alert's SQL query met its detection criterianone
custom_bot_detection_alert.sentCloudflare detected a spike in bot traffic on a zonezone
custom_ssl_certificate_event_type.sentA custom hostname certificate was validated, issued or renewed, or is expiringzone
dedicated_ssl_certificate_event_type.sentAn advanced certificate was validated, issued or renewed, or is expiringzone
device_connectivity_anomaly_alert.sentThe number of devices connected to the WARP client spiked or droppednone
dos_attack_l4.sentCloudflare mitigated a Layer 3/4 DDoS attacknone
dos_attack_l7.sentCloudflare mitigated an HTTP DDoS attack on a zonezone
expiring_service_token_alert.sentAn Access service token expires soonnone
failing_logpush_job_disabled_alert.sentCloudflare disabled a Logpush job that kept failingnone
fbm_auto_advertisement.sentMagic Transit started advertising prefixes after an attacknone
fbm_dosd_attack.sentNetwork flow data shows a DDoS attacknone
fbm_volumetric_attack.sentNetwork flow data shows a volumetric attacknone
health_check_status_notification.sentA health check's origin became healthy or unhealthyzone
hostname_aop_custom_certificate_expiration_type.sentA hostname-level Authenticated Origin Pulls certificate expires in 30 or 14 dayszone
http_alert_edge_error.sentCloudflare sent an edge error rate alertzone
http_alert_origin_error.sentCloudflare could not reach the origin for more requests than usualzone
image_notification.sentCloudflare Images sent a notification about a direct creator uploadnone
image_resizing_notification.sentThe account used up its free image transformationsnone
incident_alert.sentA Cloudflare incident was created, updated or resolvednone
leaked_service_token_alert.sentAn Access service token was detected as leakednone
load_balancing_health_alert.sentA load balancer pool or origin became healthy or unhealthynone
load_balancing_pool_enablement_alert.sentA load balancer pool was enabled or disablednone
log_explorer_scheduled_query_results_alert.sentA scheduled Log Explorer query returned resultsnone
logo_match_alert.sentSecurity Center found a new domain that uses an uploaded logonone
magic_tunnel_health_check_event.sentA Magic Tunnel's health check success rate dropped below its SLOnone
magic_wan_tunnel_health.sentAn IPsec or GRE tunnel's health check success rate dropped below its SLOnone
maintenance_event_notification.sentMaintenance at a Cloudflare data center was scheduled, changed or cancelednone
mtls_certificate_store_certificate_expiration_type.sentA certificate uploaded for mTLS expires in 30 or 14 daysnone
open_port_scan_alert.sentCloudflare detected newly open portsnone
pages_event_alert.sentA Pages deployment started, failed or succeedednone
radar_notification.sentRadar found a traffic anomaly, outage, route hijack or route leak for a location or networknone
real_origin_monitoring.sentCloudflare cannot reach an originzone
scriptmonitor_alert_new_code_change_detections.sentThe code of a monitored script changedzone
scriptmonitor_alert_new_hosts.sentA page loaded a resource from a domain not seen beforezone
scriptmonitor_alert_new_malicious_hosts.sentA page loaded a resource from a domain reported as maliciouszone
scriptmonitor_alert_new_malicious_scripts.sentCloudflare classified a script on a page as maliciouszone
scriptmonitor_alert_new_malicious_url.sentA page loaded a resource from a URL reported as maliciouszone
scriptmonitor_alert_new_max_length_resource_url.sentA page loaded a resource whose URL is longer than the maximumzone
scriptmonitor_alert_new_resources.sentA page loaded a resource not seen beforezone
secondary_dns_all_primaries_failing.sentEvery primary nameserver of a secondary zone is failingzone
secondary_dns_primaries_failing.sentA primary nameserver of a secondary zone is failingzone
secondary_dns_warning.sentA transferred zone issued a warningzone
secondary_dns_zone_successfully_updated.sentA zone transfer to a secondary zone succeededzone
secondary_dns_zone_validation_warning.sentCloudflare sent a secondary DNS zone validation warningzone
security_insights_alert.sentSecurity Center found a new security insightnone
sentinel_alert.sentCloudflare sent a Sentinel alertnone
stakeout_credential_leak_alert.sentCloudforce One found leaked credentials that match your domainnone
stakeout_saved_query_daily_digest_alert.sentA daily digest of new threat events for a saved querynone
stakeout_saved_query_immediate_alert.sentCloudforce One found new threat events for a saved querynone
stream_live_notifications.sentA Stream live input changed statenone
synthetic_test_latency_alert.sentA DEX test's latency spiked or droppednone
synthetic_test_low_availability_alert.sentA DEX test's success rate dropped below its SLOnone
traffic_anomalies_alert.sentA zone's traffic spiked or dropped unexpectedlyzone
tunnel_health_event.sentA Cloudflare Tunnel's health status changednone
tunnel_update_event.sentA Cloudflare Tunnel was created or deletednone
universal_ssl_event_type.sentA Universal SSL certificate was validated, issued or renewed, or is expiringzone
web_analytics_metrics_update.sentCloudflare sent the weekly Web Analytics summary of a sitenone
workers_observability_alert.sentA Workers Observability alert started firing or returned to normalnone
workers_observability_real_time_issue.sentWorkers Observability detected an issue on a Workernone
zone_aop_custom_certificate_expiration_type.sentA zone-level Authenticated Origin Pulls certificate expires in 30 or 14 dayszone
  • Zone matches the zone that the alert is about, chosen from your zones. It's optional. Alerts that aren't about a zone never match a zone filter.

Cloudflare offers each alert type only on some plans or with some products. The trigger picker marks the events your account doesn't offer as unavailable, with the reason.

Some alert types need filters. Helios uses the values listed by Cloudflare, known status values, or resources it can list in your account:

  • Health check status alerts cover healthy and unhealthy changes.
  • Pool enablement alerts cover pools being enabled and disabled.
  • Pages alerts cover the projects Helios lists, both environments, and deployments that start, fail, or succeed.
  • Alerts that require chosen zones cover the zones Helios lists in the account.

Helios reads up to 1,000 zones and 200 Pages projects when you save the connection. Save the connection again after you add a zone or a Pages project.

Some alert types need a value that only you can choose, such as a usage threshold, a budget, a service-level objective, a saved query, or a custom alert's SQL query. Helios can't create those alerts, so the trigger picker shows them as unavailable.

Some alerts send one notification when they start and another when they end. The payload's alert_event field is ALERT_STATE_EVENT_START or ALERT_STATE_EVENT_END, so say in the prompt which one the agent should act on.

Helios manages the alerts that send to the Helios destination. It updates them each time the connection is saved, so edits you make to them in Cloudflare don't last. If Helios can't update an alert it created before, it keeps the old alert, and the event stays available.

An agent's fix can lead to another alert. For example, an origin that the agent brings back can send a health check alert when it turns healthy, which starts another run. A Pages deployment that the agent starts sends its own deployment alerts. Say in the prompt which alerts to ignore, such as ALERT_STATE_EVENT_END events or origins that are healthy. See Guarding against events you don't want.

Cloudflare doesn't sign notifications. It sends the destination's secret in the cf-webhook-auth header, and Helios compares it with the secret it generated for the connection. Notifications whose ts is more than an hour old are rejected.

Check that it works

  • The connection: after you save, the connection's status shows Connected. Error means Cloudflare rejected the token, or the token can't reach the account ID.
  • The destination: in the Cloudflare dashboard, go to Alerts → Destinations. The Webhooks card should list Helios. Under Alerts → Overview, the Helios: ... alerts should be listed.
  • A trigger:
    1. Add universal_ssl_event_type.sent to a workflow with no filters. Any event works if your account offers it.
    2. In Alerts → Overview, open the menu of the matching Helios: ... alert and choose Test. Cloudflare sends a test alert with sample data.
    3. Check that a run starts. Then open the connection in Helios and click Webhook events to see the event.

Common errors

What you seeCauseFix
The Cloudflare API token is …The token is disabled or expiredCreate a new token and enter it through Manage
Cloudflare did not allow access to account … Check the account ID.Account ID is wrong, or the token or OAuth approval doesn't cover that accountCopy the account ID from Workers & Pages, and select the same account on the consent screen
Cloudflare access token not found. Finish connecting the OAuth app first.The OAuth approval wasn't finishedOpen the connection and connect again
Cloudflare refuses the sign-inThe OAuth client doesn't have every scope that Helios asks forAdd every scope from the table to the client, then connect again
No Helios destination under Alerts → Destinations, and no runs startThe token lacks Notifications Edit, or the OAuth app lacks notifications.write. Helios reports this as Cloudflare did not save the webhook destinationAdd the permission, then save the connection again
An event is unavailable in the trigger pickerThe account doesn't offer the alert, the alert needs a value you choose, or Cloudflare rejected it. The picker shows whichGet the plan or product that offers it, or add the missing permission and save the connection again
An agent gets 403 from an endpointThe token or OAuth app lacks the permission for itAdd the permission to the token, or the scope to the OAuth client and connect again
No run starts, and the alert looks fineThe zone filter doesn't match, or the alert is about a zone or Pages project added after you saved the connectionTry the trigger with no filters, and save the connection again

Limits

Cloudflare allows 1,200 API requests per five minutes for each user or account token, across the dashboard and the API. Accounts without a paid zone can have up to 100 webhook destinations. See Cloudflare's API rate limits and webhook setup.

Last updated on