11 KiB
Cloudflare API Overview
Authentication
Global API Key (used in examples)
curl -X GET "https://api.cloudflare.com/client/v4/..." \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: abc123..."
API Token (recommended for production)
curl -X GET "https://api.cloudflare.com/client/v4/..." \
-H "Authorization: Bearer <token>"
Response Format
All API responses follow this structure:
{
"success": true/false,
"errors": [],
"messages": [],
"result": { ... },
"result_info": { ... }
}
Always check success field before processing result.
Core Endpoints by Category
Zone Management
List zones:
GET /zones?name=<domain>
Returns zone information including id, name, status, name_servers
Get zone details:
GET /zones/{zone_id}
Get all zone settings:
GET /zones/{zone_id}/settings
Returns all configurable settings for the zone
SSL/TLS
Get SSL mode:
GET /zones/{zone_id}/settings/ssl
Result: {"value": "flexible"|"full"|"strict"|"off"}
Update SSL mode:
PATCH /zones/{zone_id}/settings/ssl
Content-Type: application/json
{"value": "full"}
Get Always Use HTTPS:
GET /zones/{zone_id}/settings/always_use_https
Update Always Use HTTPS:
PATCH /zones/{zone_id}/settings/always_use_https
{"value": "on"|"off"}
List SSL certificates:
GET /zones/{zone_id}/ssl/certificate_packs
Get SSL verification details:
GET /zones/{zone_id}/ssl/verification
Get SSL settings (universal, dedicated, etc):
GET /zones/{zone_id}/ssl/analyze
TLS 1.3 setting:
GET /zones/{zone_id}/settings/tls_1_3
PATCH /zones/{zone_id}/settings/tls_1_3
{"value": "on"|"off"|"zrt"}
Minimum TLS version:
GET /zones/{zone_id}/settings/min_tls_version
PATCH /zones/{zone_id}/settings/min_tls_version
{"value": "1.0"|"1.1"|"1.2"|"1.3"}
DNS Records
List DNS records:
GET /zones/{zone_id}/dns_records
Returns array of DNS records with type, name, content, proxied status, TTL
Filter by type:
GET /zones/{zone_id}/dns_records?type=A
GET /zones/{zone_id}/dns_records?type=CNAME
Get specific record:
GET /zones/{zone_id}/dns_records/{record_id}
Create DNS record:
POST /zones/{zone_id}/dns_records
{
"type": "A",
"name": "example.com",
"content": "192.0.2.1",
"ttl": 3600,
"proxied": true
}
Update DNS record:
PATCH /zones/{zone_id}/dns_records/{record_id}
{"proxied": true}
Delete DNS record:
DELETE /zones/{zone_id}/dns_records/{record_id}
DNSSEC status:
GET /zones/{zone_id}/dnssec
Page Rules
List page rules:
GET /zones/{zone_id}/pagerules
Get specific page rule:
GET /zones/{zone_id}/pagerules/{rule_id}
Create page rule:
POST /zones/{zone_id}/pagerules
{
"targets": [{"target": "url", "constraint": {"operator": "matches", "value": "*example.com/*"}}],
"actions": [{"id": "always_use_https"}],
"priority": 1,
"status": "active"
}
Update page rule:
PATCH /zones/{zone_id}/pagerules/{rule_id}
Delete page rule:
DELETE /zones/{zone_id}/pagerules/{rule_id}
Cache
Purge everything:
POST /zones/{zone_id}/purge_cache
{"purge_everything": true}
Purge by URL:
POST /zones/{zone_id}/purge_cache
{"files": ["https://example.com/style.css", "https://example.com/script.js"]}
Purge by tag:
POST /zones/{zone_id}/purge_cache
{"tags": ["tag1", "tag2"]}
Purge by host:
POST /zones/{zone_id}/purge_cache
{"hosts": ["example.com", "www.example.com"]}
Cache settings:
GET /zones/{zone_id}/settings/cache_level
GET /zones/{zone_id}/settings/browser_cache_ttl
GET /zones/{zone_id}/settings/development_mode
Firewall
List firewall rules:
GET /zones/{zone_id}/firewall/rules
List WAF rules:
GET /zones/{zone_id}/firewall/waf/packages
GET /zones/{zone_id}/firewall/waf/packages/{package_id}/rules
IP Access Rules:
GET /zones/{zone_id}/firewall/access_rules/rules
POST /zones/{zone_id}/firewall/access_rules/rules
{
"mode": "block"|"challenge"|"whitelist",
"configuration": {"target": "ip", "value": "192.0.2.1"},
"notes": "Blocked malicious IP"
}
Rate limiting:
GET /zones/{zone_id}/rate_limits
POST /zones/{zone_id}/rate_limits
Analytics
Get analytics:
GET /zones/{zone_id}/analytics/dashboard
Traffic analytics:
GET /zones/{zone_id}/analytics/colos
DNS analytics:
GET /zones/{zone_id}/dns_analytics/report
Load Balancers
List load balancers:
GET /zones/{zone_id}/load_balancers
Get load balancer details:
GET /zones/{zone_id}/load_balancers/{lb_id}
List pools:
GET /accounts/{account_id}/load_balancers/pools
List monitors:
GET /accounts/{account_id}/load_balancers/monitors
Workers & Routes
List worker routes:
GET /zones/{zone_id}/workers/routes
List worker scripts:
GET /accounts/{account_id}/workers/scripts
Settings (Other Common)
Development mode:
GET /zones/{zone_id}/settings/development_mode
PATCH /zones/{zone_id}/settings/development_mode
{"value": "on"|"off"}
Security level:
GET /zones/{zone_id}/settings/security_level
PATCH /zones/{zone_id}/settings/security_level
{"value": "off"|"essentially_off"|"low"|"medium"|"high"|"under_attack"}
Rocket Loader:
GET /zones/{zone_id}/settings/rocket_loader
PATCH /zones/{zone_id}/settings/rocket_loader
{"value": "on"|"off"}
Auto minify:
GET /zones/{zone_id}/settings/minify
PATCH /zones/{zone_id}/settings/minify
{"value": {"css": "on", "html": "on", "js": "on"}}
Brotli compression:
GET /zones/{zone_id}/settings/brotli
HTTP/2:
GET /zones/{zone_id}/settings/http2
HTTP/3 (QUIC):
GET /zones/{zone_id}/settings/http3
IPv6:
GET /zones/{zone_id}/settings/ipv6
Opportunistic Encryption:
GET /zones/{zone_id}/settings/opportunistic_encryption
Automatic HTTPS Rewrites:
GET /zones/{zone_id}/settings/automatic_https_rewrites
PATCH /zones/{zone_id}/settings/automatic_https_rewrites
{"value": "on"|"off"}
Learning New Endpoints
Method 1: List All Settings
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/settings" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key" | jq '.result[] | {id, value}'
This returns all available settings with current values. Use setting id to construct endpoint:
/zones/{zone_id}/settings/{id}
Method 2: Cloudflare API Docs
Browse official API reference: https://developers.cloudflare.com/api/
Structure:
- Operations organized by product/feature
- Each operation shows:
- HTTP method and endpoint
- Required/optional parameters
- Request body schema
- Response schema
- Example requests
Search strategy:
- Identify feature/product (SSL, DNS, Cache, etc.)
- Find relevant operations (List, Get, Create, Update, Delete)
- Check request schema for required fields
- Test with GET before making changes
Method 3: Explore API Interactively
Pattern:
- Start with zone info to understand structure
- List resources:
GET /zones/{zone_id}/{resource_type} - Get specific item:
GET /zones/{zone_id}/{resource_type}/{id} - Check available operations in docs
- Make changes:
PATCH/POST/DELETE
Example exploration for unknown feature:
# 1. Check if endpoint exists
curl -I "https://api.cloudflare.com/client/v4/zones/{zone_id}/feature_name"
# 2. Try listing (if collection)
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/feature_name" \
-H "X-Auth-Email: email" \
-H "X-Auth-Key: key"
# 3. Examine response structure
# 4. Consult docs for modification operations
Error Handling
Common error codes:
- 400: Bad request (check request format)
- 401: Unauthorized (check API credentials)
- 403: Forbidden (insufficient permissions)
- 404: Not found (check zone_id or resource_id)
- 429: Rate limit exceeded (wait before retrying)
- 500: Server error (Cloudflare issue, retry later)
Error response structure:
{
"success": false,
"errors": [
{
"code": 1234,
"message": "Error description"
}
],
"messages": [],
"result": null
}
Rate Limits
- Free tier: ~1200 requests per 5 minutes
- Paid tiers: Higher limits based on plan
- If rate limited (429), back off exponentially
Best Practices
-
Use jq for readability:
curl ... | jq '.result' -
Extract specific fields:
curl ... | jq '.result.value' curl ... | jq '.result[] | {id, name, value}' -
Check success before processing:
response=$(curl ...) success=$(echo "$response" | jq -r '.success') if [ "$success" = "true" ]; then echo "$response" | jq '.result' else echo "$response" | jq '.errors' fi -
Store zone_id for reuse:
zone_id=$(curl ... | jq -r '.result[0].id') -
Test with GET first: Before modifying configuration, always GET to see current state
Common Investigation Patterns
Pattern 1: Settings Investigation
# Get all settings
curl -X GET "/zones/{zone_id}/settings" | jq '.result[]'
# Filter specific settings
curl -X GET "/zones/{zone_id}/settings" | jq '.result[] | select(.id | contains("ssl"))'
Pattern 2: Resource Listing + Details
# List resources
curl -X GET "/zones/{zone_id}/dns_records" | jq '.result[] | {id, name, type}'
# Get specific resource
record_id="..."
curl -X GET "/zones/{zone_id}/dns_records/$record_id" | jq '.'
Pattern 3: Multi-Setting Check
# Check related settings in parallel
curl ... /settings/ssl &
curl ... /settings/always_use_https &
curl ... /pagerules &
wait
Pattern 4: Change + Verify
# Make change
curl -X PATCH "/zones/{zone_id}/settings/ssl" -d '{"value":"full"}'
# Verify change applied
curl -X GET "/zones/{zone_id}/settings/ssl" | jq '.result.value'
Account-Level vs Zone-Level
Some resources are account-level, not zone-level:
Account-level:
- Load balancer pools/monitors:
/accounts/{account_id}/load_balancers/... - Workers scripts:
/accounts/{account_id}/workers/... - Access policies:
/accounts/{account_id}/access/...
Zone-level:
- DNS records:
/zones/{zone_id}/dns_records - SSL settings:
/zones/{zone_id}/settings/ssl - Page rules:
/zones/{zone_id}/pagerules
Get account_id from zone info:
curl -X GET "/zones?name=example.com" | jq '.result[0].account.id'