CDN Network - API Design
Content Delivery API
Standard Content Request
Copy GET /images/hero-banner.webp HTTP/2
Host : assets.example.com
Accept : image/webp,image/png,*/*
Accept-Encoding : gzip, br
If-None-Match : "abc123def456"
If-Modified-Since : Wed, 15 Jan 2025 10:00:00 GMT
--- Response (Cache Hit) - --
HTTP/2 200 OK
Content-Type: image/webp
Content-Length: 245760
Cache-Control: public, max-age= 86400 , stale-while-revalidate= 3600
ETag: "abc123def456"
Last-Modified: Wed, 15 Jan 2025 10 :00 :00 GMT
Age: 7200
X-Cache: HIT
X-Cache-Edge: us-east-1 - iad
X-Request-Id: req-7 f3a2b1c
Vary: Accept-Encoding
CF-Ray: 8 a1b2c3d4e5f
[binary content] Conditional Requests (304 Not Modified)
Copy GET /styles/main.css HTTP/2
Host : assets.example.com
If-None-Match : "v2.5.1-hash"
--- Response - --
HTTP/2 304 Not Modified
ETag: "v2.5.1-hash"
Cache-Control: public, max-age= 604800
Age: 43200
X-Cache: HIT Range Requests (Partial Content)
Copy GET /videos/episode-1.mp4 HTTP/2
Host : stream.example.com
Range : bytes=1048576-2097151
--- Response - --
HTTP/2 206 Partial Content
Content-Type: video/mp4
Content-Range: bytes 104857 6-2097151 /104857600
Content-Length: 1048576
Accept-Ranges: bytes
X-Cache: HIT Cache Header Semantics
Copy Cache -Control directives honored by CDN:
- public : Cache at edge (default for GET 200 )
- private : Do NOT cache at edge (pass through)
- no-cache : Cache but revalidate on every request
- no-store : Never cache , never store
- max -age =N: Cache for N seconds
- s-maxage =N: CDN-specific max -age (overrides max -age )
- stale-while -revalidate =N: Serve stale for N seconds while refreshing
- stale-if -error =N: Serve stale for N seconds if origin errors
- immutable: Never revalidate (versioned assets)
- no-transform : Do not modify content (no compression/optimization)
CDN-specific headers:
- CDN-Cache -Control : CDN-only directives (not forwarded to client)
- Surrogate-Control : Akamai-style CDN control header
- X-Cache -TTL : Override TTL for this response
Cache Management API
Purge by URL
Copy POST /api/v1/distributions/{dist_id}/purge
Authorization : Bearer <api_token>
Content-Type : application/json
{
"type": "url",
"items": [
"https://assets.example.com/images/hero-banner.webp",
"https://assets.example.com/styles/main.css"
],
"options": {
"include_variants": true,
"soft_purge": false
}
}
--- Response ---
HTTP/1.1 202 Accepted
{
"purge_id": "purge-a1b2c3d4",
"status": "in_progress",
"items_count": 2,
"estimated_completion_seconds": 5,
"edges_targeted": 247,
"created_at": "2025-01-15T10:30:00Z"
}Purge by Prefix/Wildcard
Copy POST /api/v1/distributions/{dist_id}/purge
Authorization : Bearer <api_token>
Content-Type : application/json
{
"type": "prefix",
"items": [
"https://assets.example.com/images/products/*",
"https://assets.example.com/api/v2/catalog/*"
]
}
--- Response ---
HTTP/1.1 202 Accepted
{
"purge_id": "purge-e5f6g7h8",
"status": "in_progress",
"estimated_objects_affected": 15000,
"estimated_completion_seconds": 30
}Purge All (Full Invalidation)
Copy POST /api/v1/distributions/{dist_id}/purge
Authorization : Bearer <api_token>
{
"type": "all",
"confirm": true
}
--- Response ---
HTTP/1.1 202 Accepted
{
"purge_id": "purge-full-i9j0k1",
"status": "in_progress",
"warning": "Full purge will temporarily increase origin load",
"estimated_completion_seconds": 60
}Cache Prefetch/Warm
Copy POST /api/v1/distributions/{dist_id}/prefetch
Authorization : Bearer <api_token>
Content-Type : application/json
{
"urls": [
"https://assets.example.com/videos/new-release.mp4",
"https://assets.example.com/images/campaign-2025.webp"
],
"regions": ["us-east", "eu-west", "ap-northeast"],
"priority": "high",
"headers": {
"Accept-Encoding": "br"
}
}
--- Response ---
HTTP/1.1 202 Accepted
{
"prefetch_id": "pf-m2n3o4p5",
"urls_count": 2,
"regions_targeted": 3,
"edges_targeted": 45,
"status": "in_progress"
}Get Purge Status
Copy GET /api/v1/distributions/{dist_id}/purge/purge-a1b2c3d4
Authorization : Bearer <api_token>
--- Response ---
HTTP/1.1 200 OK
{
"purge_id": "purge-a1b2c3d4",
"status": "completed",
"items_count": 2,
"edges_completed": 247,
"edges_total": 247,
"created_at": "2025-01-15T10:30:00Z",
"completed_at": "2025-01-15T10:30:04Z",
"duration_ms": 4200
}
Configuration API
Create Distribution
Copy POST /api/v1/distributions
Authorization : Bearer <api_token>
Content-Type : application/json
{
"name": "Production Assets",
"origins": [
{
"domain_name": "origin.example.com",
"protocol": "https",
"port": 443,
"path": "/assets",
"custom_headers": {
"X-Origin-Auth": "secret-token"
},
"connection_timeout_ms": 5000,
"read_timeout_ms": 30000
}
],
"default_cache_behavior": {
"viewer_protocol_policy": "redirect-to-https",
"allowed_methods": ["GET", "HEAD", "OPTIONS"],
"cache_policy": "optimized-static",
"compress": true,
"default_ttl": 86400,
"max_ttl": 31536000
},
"alternate_domain_names": ["assets.example.com", "cdn.example.com"],
"certificate_id": "cert-x1y2z3",
"price_class": "all_edges",
"http_version": "http2and3",
"ipv6_enabled": true,
"logging": {
"enabled": true,
"bucket": "s3://cdn-logs-bucket/production/",
"include_cookies": false
}
}
--- Response ---
HTTP/1.1 201 Created
{
"distribution_id": "dist-q5r6s7t8",
"domain_name": "d1234abcdef.cdn.example.net",
"status": "deploying",
"estimated_deploy_minutes": 5,
"created_at": "2025-01-15T10:00:00Z"
}Update Origin Configuration
Copy PUT /api/v1/distributions/{dist_id}/origins/{origin_id}
Authorization : Bearer <api_token>
Content-Type : application/json
{
"domain_name": "origin-v2.example.com",
"failover": {
"origin_id": "origin-backup-456",
"status_codes": [500, 502, 503, 504],
"timeout_ms": 10000
},
"health_check": {
"path": "/health",
"interval_seconds": 30,
"healthy_threshold": 3,
"unhealthy_threshold": 2
}
}
--- Response ---
HTTP/1.1 200 OK
{
"origin_id": "origin-123",
"status": "deploying",
"config_version": 5
}Set Cache Behaviors
Copy POST /api/v1/distributions/{dist_id}/cache-behaviors
Authorization : Bearer <api_token>
Content-Type : application/json
{
"path_pattern": "/api/v2/*",
"priority": 1,
"origin_id": "origin-api-789",
"cache_policy": {
"min_ttl": 0,
"max_ttl": 60,
"default_ttl": 10,
"query_string": {
"behavior": "whitelist",
"keys": ["page", "limit", "sort"]
},
"headers": {
"behavior": "whitelist",
"keys": ["Authorization", "Accept-Language"]
},
"cookies": {
"behavior": "none"
}
},
"viewer_protocol_policy": "https-only",
"allowed_methods": ["GET", "HEAD", "OPTIONS", "POST"],
"compress": true
}
--- Response ---
HTTP/1.1 201 Created
{
"behavior_id": "cb-u8v9w0x1",
"path_pattern": "/api/v2/*",
"priority": 1,
"status": "deploying"
}
Analytics API
Get Bandwidth Statistics
Copy GET /api/v1/distributions/{dist_id}/analytics/bandwidth
?start=2025-01-14T00:00:00Z
&end=2025-01-15T00:00:00Z
&granularity=1hour
®ions=us-east,eu-west
Authorization : Bearer <api_token>
--- Response ---
HTTP/1.1 200 OK
{
"distribution_id": "dist-q5r6s7t8",
"period": {
"start": "2025-01-14T00:00:00Z",
"end": "2025-01-15T00:00:00Z"
},
"granularity": "1hour",
"totals": {
"bytes_sent": 8547321856000,
"bytes_received": 125478963200,
"requests": 1247856321
},
"time_series": [
{
"timestamp": "2025-01-14T00:00:00Z",
"bytes_sent": 312456789000,
"bytes_received": 4567890000,
"requests": 45678901
}
]
}Get Cache Hit Ratio
Copy GET /api/v1/distributions/{dist_id}/analytics/cache
?start=2025-01-14T00:00:00Z
&end=2025-01-15T00:00:00Z
&granularity=5min
Authorization : Bearer <api_token>
--- Response ---
HTTP/1.1 200 OK
{
"totals": {
"hit_ratio": 0.934,
"hits": 1165456789,
"misses": 82399532,
"expired": 12456789,
"bypass": 5678901
},
"time_series": [
{
"timestamp": "2025-01-14T00:00:00Z",
"hit_ratio": 0.941,
"hits": 4056789,
"misses": 253211
}
],
"by_content_type": {
"image/*": {"hit_ratio": 0.97, "requests": 500000000},
"text/css": {"hit_ratio": 0.95, "requests": 200000000},
"application/javascript": {"hit_ratio": 0.93, "requests": 300000000},
"text/html": {"hit_ratio": 0.72, "requests": 150000000},
"application/json": {"hit_ratio": 0.55, "requests": 97856321}
}
}Get Latency Percentiles
Copy GET /api/v1/distributions/{dist_id}/analytics/latency
?start=2025-01-14T00:00:00Z
&end=2025-01-15T00:00:00Z
&granularity=1hour
&percentiles=p50,p90,p95,p99
Authorization : Bearer <api_token>
--- Response ---
HTTP/1.1 200 OK
{
"totals": {
"p50_ms": 12.4,
"p90_ms": 45.2,
"p95_ms": 78.6,
"p99_ms": 156.3,
"avg_ms": 23.7
},
"by_cache_status": {
"hit": {"p50_ms": 8.2, "p95_ms": 32.1, "p99_ms": 65.4},
"miss": {"p50_ms": 145.6, "p95_ms": 320.8, "p99_ms": 890.2}
},
"by_region": {
"us-east": {"p50_ms": 8.1, "p95_ms": 28.4},
"eu-west": {"p50_ms": 11.3, "p95_ms": 42.7},
"ap-northeast": {"p50_ms": 15.8, "p95_ms": 55.2}
},
"time_series": [
{
"timestamp": "2025-01-14T00:00:00Z",
"p50_ms": 11.8,
"p95_ms": 72.3,
"p99_ms": 148.9
}
]
}Get Error Rate Analytics
Copy GET /api/v1/distributions/{dist_id}/analytics/errors
?start=2025-01-14T00:00:00Z
&end=2025-01-15T00:00:00Z
Authorization : Bearer <api_token>
--- Response ---
HTTP/1.1 200 OK
{
"error_rate": 0.0023,
"total_errors": 2867543,
"by_status_code": {
"400": 456789,
"403": 234567,
"404": 1567890,
"500": 123456,
"502": 234567,
"503": 178901,
"504": 71373
},
"by_type": {
"origin_error": 608297,
"client_error": 2259246,
"edge_error": 0
},
"top_error_urls": [
{"url": "/api/v2/users/profile", "count": 45678, "status": 500},
{"url": "/images/deleted-asset.png", "count": 34567, "status": 404}
]
}
SSL/TLS Certificate API
Upload Custom Certificate
Copy POST /api/v1/certificates
Authorization : Bearer <api_token>
Content-Type : application/json
{
"certificate": "-----BEGIN CERTIFICATE-----\nMIIF...\n-----END CERTIFICATE-----",
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----",
"certificate_chain": "-----BEGIN CERTIFICATE-----\nMIIG...\n-----END CERTIFICATE-----",
"domain_names": ["assets.example.com", "*.example.com"]
}
--- Response ---
HTTP/1.1 201 Created
{
"certificate_id": "cert-a1b2c3d4",
"domain_names": ["assets.example.com", "*.example.com"],
"issuer": "DigiCert Inc",
"not_before": "2025-01-01T00:00:00Z",
"not_after": "2026-01-01T00:00:00Z",
"key_algorithm": "RSA-2048",
"status": "pending_deployment",
"fingerprint_sha256": "AB:CD:EF:12:34..."
}Request Managed Certificate (Auto-Provisioned)
Copy POST /api/v1/certificates/managed
Authorization : Bearer <api_token>
Content-Type : application/json
{
"domain_names": ["new-site.example.com"],
"validation_method": "dns",
"key_algorithm": "ecdsa-p256",
"auto_renew": true
}
--- Response ---
HTTP/1.1 201 Created
{
"certificate_id": "cert-managed-e5f6",
"status": "pending_validation",
"validation_records": [
{
"domain": "new-site.example.com",
"type": "CNAME",
"name": "_acme-challenge.new-site.example.com",
"value": "validation-token.cdn.example.net"
}
]
}Deploy Certificate to Distribution
Copy PUT /api/v1/distributions/{dist_id}/certificate
Authorization : Bearer <api_token>
Content-Type : application/json
{
"certificate_id": "cert-a1b2c3d4",
"minimum_protocol_version": "TLSv1.2",
"ssl_support_method": "sni-only"
}
--- Response ---
HTTP/1.1 200 OK
{
"status": "deploying",
"edges_deployed": 0,
"edges_total": 247,
"estimated_completion_minutes": 10
}
Edge Function/Worker API
Deploy Edge Function
Copy POST /api/v1/distributions/{dist_id}/edge-functions
Authorization : Bearer <api_token>
Content-Type : application/json
{
"name": "image-optimizer",
"runtime": "javascript",
"code": "export default { async fetch(request, env) { const url = new URL(request.url); if (url.pathname.startsWith('/images/')) { const width = url.searchParams.get('w') || 800; return fetch(request, { cf: { image: { width: parseInt(width), quality: 80, format: 'webp' } } }); } return fetch(request); } }",
"event_type": "viewer-request",
"memory_limit_mb": 128,
"timeout_ms": 5000,
"environment_variables": {
"OPTIMIZATION_QUALITY": "80",
"MAX_WIDTH": "2048"
}
}
--- Response ---
HTTP/1.1 201 Created
{
"function_id": "fn-g7h8i9j0",
"name": "image-optimizer",
"version": 1,
"status": "deploying",
"code_size_bytes": 456,
"deployed_edges": 0,
"created_at": "2025-01-15T10:00:00Z"
}Associate Function with Cache Behavior
Copy PUT /api/v1/distributions/{dist_id}/cache-behaviors/{behavior_id}/functions
Authorization : Bearer <api_token>
Content-Type : application/json
{
"associations": [
{
"event_type": "viewer-request",
"function_id": "fn-g7h8i9j0"
},
{
"event_type": "origin-response",
"function_id": "fn-k1l2m3n4"
}
]
}
--- Response ---
HTTP/1.1 200 OK
{
"behavior_id": "cb-u8v9w0x1",
"function_associations": [
{"event_type": "viewer-request", "function_id": "fn-g7h8i9j0"},
{"event_type": "origin-response", "function_id": "fn-k1l2m3n4"}
],
"status": "deploying"
}Edge Function Event Types
Copy viewer-request: Runs before cache lookup
viewer-response: Runs after cache/origin response
origin-request: Runs before origin fetch (only on cache miss)
origin-response: Runs after origin response
Real-Time Log Streaming API
Create Log Subscription
Copy POST /api/v1/distributions/{dist_id}/log-subscriptions
Authorization : Bearer <api_token>
Content-Type : application/json
{
"name": "production-logs",
"destination": {
"type": "kinesis",
"stream_arn": "arn:aws:kinesis:us-east-1:123456789:stream/cdn-logs",
"role_arn": "arn:aws:iam::123456789:role/cdn-log-writer"
},
"fields": [
"timestamp", "client_ip", "method", "host", "path",
"status_code", "response_bytes", "cache_status",
"time_to_first_byte", "total_time_ms", "user_agent",
"tls_version", "country"
],
"sampling_rate": 100,
"filter": {
"status_codes": [500, 502, 503, 504],
"cache_status": ["MISS", "ERROR"]
}
}
--- Response ---
HTTP/1.1 201 Created
{
"subscription_id": "logs-o4p5q6r7",
"status": "active",
"fields_count": 13,
"estimated_volume_gb_per_day": 45.2
}Supported Destinations
Copy - Amazon Kinesis Data Streams
- Amazon S3 (batched, 5-minute intervals)
- Google Cloud Pub/Sub
- Azure Event Hubs
- Datadog
- Splunk HEC
- Custom HTTPS endpoint (webhook)
- Apache Kafka (self-hosted)
Rate Limiting and Quotas
API Rate Limits
Endpoint Category
Rate Limit
Burst
Configuration (CRUD)
100 req/min
20
Purge requests
1000 req/min
100
Prefetch requests
500 req/min
50
Analytics queries
300 req/min
30
Certificate operations
50 req/min
10
Edge function deploys
100 req/min
20
Log subscription mgmt
50 req/min
10
Rate Limit Response
Copy HTTP/1.1 429 Too Many Requests
Retry-After : 12
X-RateLimit-Limit : 100
X-RateLimit-Remaining : 0
X-RateLimit-Reset : 1705312812
{
: ,
: ,
: 100 ,
: ,
: 12
}
API Authentication
Authentication Methods
Copy 1. API Token (Bearer) :
Authorization : Bearer cdn_live_a1b2c3d4e5f6...
- Long-lived tokens for server-to-server
- Scoped permissions (read-only, purge-only, full-access)
2. Signed Requests (HMAC) :
X-CDN-Timestamp : 1705312800
X-CDN-Signature : sha256=abc123...
- Time-limited, replay-protected
- Used for high-security operations
3. OAuth 2.0 :
Authorization : Bearer eyJhbGciOiJSUzI1NiI...
- For user-facing dashboards
- Short-lived access tokens + refresh tokens
4. IAM Role (AWS-style) :
- Cross-account access via assumed roles
- Temporary credentials with STS Error Response Format
Copy {
"error" : {
"code" : "InvalidParameter" ,
"message" : "The path_pattern '/api/*' conflicts with existing behavior" ,
"details" : {
"field" : "path_pattern" ,
"conflicting_behavior_id" : "cb-existing-123"
} ,
"request_id" : "req-7f3a2b1c" ,
"documentation_url" : "https://docs.cdn.example.com/errors/InvalidParameter"
}
}