Cloudflare API — SKILL.md

Raw skill file that agents receive when using this skill

Download
---
name: "Cloudflare API"
description: "Skill for Cloudflare API — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "infrastructure"
agents: ["claude-code", "codex", "gemini"]
tags: ["cloudflare-api", "infrastructure", "auto-generated"]
---

# Cloudflare API

---
name: cloudflare-api
description: Use when managing Cloudflare resources via API - DNS records, zones, page rules, security settings, analytics, and Workers. Essential for infrastructure automation and bulk operations.
category: infrastructure
metadata:
  author: skynet
  version: 1.0.0
---

# Cloudflare API

## Authentication Setup

```bash
# Set environment variables
export CF_API_TOKEN="your_api_token_here"
export CF_API_EMAIL="your@email.com"
export CF_API_KEY="your_global_api_key"  # Legacy method

# Test authentication
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"
```

## Zone Management

### List and Find Zones
```bash
# List all zones
curl -X GET "https://api.cloudflare.com/client/v4/zones" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Get specific zone by name
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Store zone ID for reuse
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result[0].id')
```

### Zone Settings
```bash
# Get SSL settings
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ssl" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Enable Always Use HTTPS
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/always_use_https" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value":"on"}'

# Set security level
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/security_level" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value":"medium"}'
```

## DNS Record Management

### CRUD Operations
```bash
# List DNS records
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Create A record
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "A",
    "name": "subdomain",
    "content": "192.168.1.1",
    "ttl": 3600,
    "proxied": true
  }'

# Update DNS record
DNS_RECORD_ID="record_id_here"
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "192.168.1.2"}'

# Delete DNS record
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"
```

### Bulk DNS Operations
```bash
# Find and update multiple records
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" | \
  jq -r '.result[] | select(.name | contains("api")) | .id' | \
  while read record_id; do
    curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$record_id" \
      -H "Authorization: Bearer $CF_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"proxied": false}'
  done
```

## Page Rules and Workers

### Page Rules
```bash
# List page rules
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/pagerules" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Create cache everything rule
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/pagerules" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targets": [{"target": "url", "constraint": {"operator": "matches", "value": "*.example.com/api/*"}}],
    "actions": [{"id": "cache_level", "value": "cache_everything"}],
    "priority": 1,
    "status": "active"
  }'
```

### Workers
```bash
# List Workers scripts
curl -X GET "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Deploy Worker script
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts/my-worker" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/javascript" \
  --data-binary "@worker.js"
```

## Security and Firewall

### Firewall Rules
```bash
# List firewall rules
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/rules" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Block IP range
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/rules" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {"expression": "ip.src in {192.168.1.0/24}"},
    "action": "block",
    "description": "Block internal network"
  }'

# Rate limiting rule
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rate_limits" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "threshold": 10,
    "period": 60,
    "action": {"mode": "ban", "timeout": 86400},
    "match": {"request": {"url": "*.example.com/api/*"}}
  }'
```

## Analytics and Monitoring

```bash
# Get zone analytics
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/analytics/dashboard?since=-1440&until=now" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Security events
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/security/events" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"

# Cache statistics
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/analytics/colos" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json"
```

## Decision Tree: DNS Record Management

```
DNS Record Task?
├── Create new record
│   ├── A/AAAA → Use type: "A"/"AAAA", set proxied: true/false
│   ├── CNAME → Use type: "CNAME", target must be FQDN
│   └── MX → Use type: "MX", include priority field
├── Bulk operations
│   ├── Many similar records → Use loop with API calls
│   └── Import from file → Use Cloudflare CLI or script with JSON
├── Update existing
│   ├── Change IP → PATCH with new content
│   ├── Toggle proxy → PATCH with proxied: true/false
│   └── Change TTL → PATCH with ttl value
└── Troubleshoot
    ├── Record not resolving → Check proxied status and DNS propagation
    └── API errors → Verify zone ID and record ID exist
```

## Troubleshooting

### Common Errors and Solutions

**Error 10000: "Authentication error"**
```bash
# Check token validity
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer $CF_API_TOKEN"

# If invalid, regenerate token with proper permissions
```

**Error 81044: "DNS record already exists"**
```bash
# Find existing record first
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=subdomain.example.com" \
  -H "Authorization: Bearer $CF_API_TOKEN"

# Then update instead of create
```

**Error 1004: "DNS points to prohibited IP"**
```bash
# Check if IP is in prohibited range (private IPs when proxied)
# Solution: Set proxied to false for private IPs
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -d '{"proxied": false}'
```

**Rate Limiting (Error 1015)**
```bash
# Implement backoff strategy
sleep_time=1
for attempt in {1..3}; do
  response=$(curl -w "%{http_code}" -s -o response.json -X GET "..." \
    -H "Authorization: Bearer $CF_API_TOKEN")
  if [[ $response == "200" ]]; then
    break
  elif [[ $response == "429" ]]; then
    sleep $((sleep_time * 2))
    sleep_time=$((sleep_time * 2))
  fi
done
```

### Debugging Tips
```bash
# Enable verbose curl output
curl -v -X GET "https://api.cloudflare.com/client/v4/zones" \
  -H "Authorization: Bearer $CF_API_TOKEN"

# Parse JSON responses with jq
curl -s "..." | jq '.errors[] | {code, message}'

# Check API response success
curl -s "..." | jq -r '.success'
```

## Best Practices

- Use API tokens instead of Global API Key
- Implement proper error handling and retries
- Cache zone IDs to reduce API calls
- Use pagination for large datasets (`?page=1&per_page=50`)
- Monitor rate limits and implement exponential backoff
- Always verify changes with GET requests after POST/PATCH operations

curl -s https://skills.skynet.ceo/api/skills/cloudflare-api/skill.md