Deploy a custom ruleset
To deploy a custom ruleset, add a rule with execute action to the list of rules of a phase entry point ruleset at the account or zone level. The expression of the new rule will define when the custom ruleset will run.
You can only deploy custom rulesets in an entry point ruleset with the same scope. For example, a custom ruleset defined at the account level can only be deployed at the account level.
If you are using Terraform, refer to WAF custom rules configuration using Terraform for examples of creating and deploying custom rulesets.
If you are using the Cloudflare dashboard, refer to Work with custom rulesets in the dashboard.
- Obtain the name of the phase where you want to deploy the custom ruleset.
- Create a custom ruleset and keep the ID of the new custom ruleset.
- Fetch the rules already present in the phase entry point ruleset. You must include in the
PUTrequest all existing rules you want to keep.
The following PUT request adds a rule that executes a custom ruleset when the zone name matches example.com.
In the PUT request, you must include the IDs of all existing rules you want to keep. The response will include all the rules in the phase entry point ruleset after the update.
Required API token permissions
At least one of the following token permissions
is required:
Mass URL Redirects WriteMagic Firewall WriteL4 DDoS Managed Ruleset WriteTransform Rules WriteSelect Configuration WriteAccount WAF WriteAccount Rulesets WriteLogs Write
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rulesets/phases/http_request_firewall_custom/entrypoint" \ --request PUT \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --json '{ "rules": [ { "action": "execute", "description": "Execute custom ruleset", "expression": "(cf.zone.name == \"example.com\") and cf.zone.plan eq \"ENT\"", "action_parameters": { "id": "<CUSTOM_RULESET_ID>" } }, { "id": "<EXISTING_PHASE_RULE_ID_1>" }, { "id": "<EXISTING_PHASE_RULE_ID_2>" } ] }'{ "result": { "id": "<ACCOUNT_PHASE_RULESET_ID>", "name": "http_request_firewall_custom phase entry point ruleset for my account", "description": "Execute several rulesets", "kind": "root", "version": "3", "rules": [ { "id": "<PHASE_RULE_ID>", "version": "1", "action": "execute", "description": "Execute custom ruleset", "action_parameters": { "id": "<CUSTOM_RULESET_ID>", "version": "latest" }, "expression": "(cf.zone.name == \"example.com\") and cf.zone.plan eq \"ENT\"", "last_updated": "2021-03-18T18:35:14.135697Z", "ref": "<PHASE_RULE_REF>", "enabled": true }, { "id": "<EXISTING_PHASE_RULE_ID_1>", "version": "1", "action": "execute", "action_parameters": { "id": "<EXECUTED_RULESET_ID_1>", "version": "latest" }, "expression": "(cf.zone.name eq \"example.com\") and cf.zone.plan eq \"ENT\"", "last_updated": "2021-03-16T15:51:49.180378Z", "ref": "<EXISTING_PHASE_RULE_REF_1>", "enabled": true }, { "id": "<EXISTING_PHASE_RULE_ID_2>", "version": "1", "action": "execute", "action_parameters": { "id": "<EXECUTED_RULESET_ID_2>", "version": "latest" }, "expression": "(cf.zone.name eq \"example.com\") and cf.zone.plan eq \"ENT\"", "last_updated": "2021-03-16T15:50:29.861157Z", "ref": "<EXISTING_PHASE_RULE_REF_2>", "enabled": true } ], "last_updated": "2021-03-18T18:35:14.135697Z", "phase": "http_request_firewall_custom" }, "success": true, "errors": [], "messages": []}The following PUT request adds a rule to a zone-level entry point ruleset that executes a custom ruleset with ID "<CUSTOM_RULESET_ID>" for requests targeting the /login URI path.
You must include in the PUT request the IDs of all existing rules you want to keep. The response will include all the rules in the phase entry point ruleset after the update.
Required API token permissions
At least one of the following token permissions
is required:
Response Compression WriteConfig Settings WriteDynamic URL Redirects WriteCache Settings WriteCustom Errors WriteOrigin WriteManaged headers WriteZone Transform Rules WriteMass URL Redirects WriteMagic Firewall WriteL4 DDoS Managed Ruleset WriteHTTP DDoS Managed Ruleset WriteSanitize WriteTransform Rules WriteSelect Configuration WriteBot Management WriteZone WAF WriteAccount WAF WriteAccount Rulesets WriteLogs WriteLogs Write
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_request_firewall_custom/entrypoint" \ --request PUT \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --json '{ "rules": [ { "action": "execute", "description": "Execute custom ruleset (zone)", "expression": "(http.request.uri.path eq \"/login\")", "action_parameters": { "id": "<CUSTOM_RULESET_ID>" } }, { "id": "<EXISTING_PHASE_RULE_ID_1>" } ] }'{ "result": { "id": "<ZONE_PHASE_RULESET_ID>", "name": "http_request_firewall_custom phase entry point ruleset for my zone", "description": "", "kind": "zone", "version": "3", "rules": [ { "id": "<PHASE_RULE_ID>", "version": "1", "action": "execute", "description": "Execute custom ruleset (zone)", "action_parameters": { "id": "<CUSTOM_RULESET_ID>", "version": "latest" }, "expression": "(http.request.uri.path eq \"/login\")", "last_updated": "2025-08-18T18:35:14.135697Z", "ref": "<PHASE_RULE_REF>", "enabled": true }, { "id": "<EXISTING_PHASE_RULE_ID_1>", "version": "1", "action": "managed_challenge", "expression": "(cf.waf.score lt 20 and http.request.uri.path wildcard \"/admin/*\")", "last_updated": "2025-08-16T15:51:49.180378Z", "ref": "<EXISTING_PHASE_RULE_REF_1>", "enabled": true } ], "last_updated": "2025-08-18T18:35:14.135697Z", "phase": "http_request_firewall_custom" }, "success": true, "errors": [], "messages": []}Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark
-